ir.policy¶
Per-corpus policy — how a corpus is segmented/stored and what background work it gets.
This is the declarative half of ir’s maintenance story (issue #58): a corpus’s
policy lives as data in its registry entry, and ir resolves an effective
policy by layering entry over per-kind defaults over a global default.
An idempotent ir.maintenance.maintain() reads the policy and does the due
work; scheduling that work (cron / launchd, or an orchestration layer’s budget
governor) stays external — ir never imports an orchestration layer, and there
is no global Settings singleton (policy is per-corpus data, injected, not a
process-wide mutable). The light path stays a one-liner: every field has a smart
default, so ir build skills needs no policy at all.
The three policy axes:
reindex — when to rebuild:
"source-change"(default; rebuild is a near-no-op when nothing changed, so it is always safe to run),"interval"(only when older thanevery_hours), or"manual"(never automatic).synopsis — whether/when to attach LLM synopses (the expensive, off-by-default work): only the
recentslice, only duringdowntime_hours. Synopsis is realized as a strategy wrapper (ir.with_synopsis()), so it is incremental — only new/changed artifacts are synthesized.storage — the persistence backend. Today only
"local"(the file store); avd.Collectionbackend is the documented future seam (issue #28).
Module Attributes
Accepted |
|
Storage backends ir can resolve today. |
|
The global fallback policy (any kind without a specific default). |
|
Per-kind maintenance defaults. |
Functions
|
The smart-default |
|
Whether |
|
Whether a reindex is due under |
|
The effective policy for a registry |
|
The effective storage spec for an |
Classes
|
The background-work policy for one corpus (reindex + synopsis). |
|
When to (incrementally) rebuild a corpus. |
|
Whether/when to attach (expensive, LLM-generated) synopses. |
- ir.policy.DEFAULTS_BY_KIND: dict[str, dict] = {'files': {'reindex': {'on': 'source-change'}}, 'packages': {'reindex': {'on': 'source-change'}}, 'records': {'reindex': {'every_hours': 24, 'on': 'interval'}}, 'reports': {'reindex': {'on': 'source-change'}}, 'sessions': {'reindex': {'every_hours': 24, 'on': 'interval'}, 'synopsis': {'downtime_hours': [2, 6], 'enabled': False, 'scope': 'recent', 'window_days': 30}}, 'skills': {'reindex': {'on': 'source-change'}}}¶
Per-kind maintenance defaults. The rule of thumb encoded here: small, fully-enumerable corpora (skills/packages/reports/files) rebuild on source change (cheap, exact); large, append-mostly, time-stamped corpora (sessions) rebuild on an interval and keep synopsis off by default, with a downtime window ready for when it is turned on. New kinds register here.
- ir.policy.GLOBAL_DEFAULT = MaintenancePolicy(reindex=ReindexPolicy(on='source-change', every_hours=None), synopsis=SynopsisPolicy(enabled=False, scope='recent', window_days=30, downtime_hours=None))¶
The global fallback policy (any kind without a specific default).
- class ir.policy.MaintenancePolicy(reindex=<factory>, synopsis=<factory>)[source]¶
Bases:
objectThe background-work policy for one corpus (reindex + synopsis).
- ir.policy.REINDEX_TRIGGERS = ('source-change', 'interval', 'manual')¶
Accepted
reindex.ontriggers.
- class ir.policy.ReindexPolicy(on='source-change', every_hours=None)[source]¶
Bases:
objectWhen to (incrementally) rebuild a corpus.
- ir.policy.STORAGE_BACKENDS = ('local',)¶
Storage backends ir can resolve today.
"vd"(vd.Collection) is the documented future backend, gated on issue #28.
- class ir.policy.SynopsisPolicy(enabled=False, scope='recent', window_days=30, downtime_hours=None)[source]¶
Bases:
objectWhether/when to attach (expensive, LLM-generated) synopses.
downtime_hoursis a[start, end)pair of local-clock hours (wrapping past midnight is allowed, e.g.(22, 6));Nonemeans “any time”.scope="recent"limits synthesis to artifacts whose timestamp is withinwindow_days(corpora that expose a time signal);scope="all"synthesizes every artifact (bounded by incrementality).
- ir.policy.default_policy_for_kind(kind)[source]¶
The smart-default
MaintenancePolicyfor a corpuskind.- Return type:
- ir.policy.in_downtime(policy, now)[source]¶
Whether
nowfalls inside the synopsisdowntime_hourswindow.Nonewindow means “any time”. A window whose start hour is greater than its end hour wraps past midnight (e.g.(22, 6)is 22:00–06:00).- Return type:
- ir.policy.is_reindex_due(policy, last_maintained, now)[source]¶
Whether a reindex is due under
policygiven the last-maintained time.source-changeis always due (the build is incremental and a no-op when nothing changed, so running it cannot do harm).intervalis due when never maintained or older thanevery_hours.manualis never automatically due.
- Return type: