Summary
Formalize ir_09 §5 pointer-passing into a documented, injectable resource-store contract on disclose/discover, and guarantee leaf outputs survive a serialization/subagent boundary. ir already implements lazy store[pointer] (Disclosure.pointer + POINTER_KEYS + _default_body_loader, select.py:493+) — but the dereference is hard-wired to local disk paths, and SearchHit lacks a public to_dict() (its score may be a numpy float from dense ranking).
Why (rationale)
- ir_09 §5: retrievers/subagents return ranked pointers + snippets, never full payloads; the full payload is dereferenced on demand via
store[pointer] — a MutableMapping resource store. ir's _default_body_loader IS that, but only over disk.
- Making the store injectable (
Mapping[pointer, payload]) lets ir's lazy disclosure work over dol stores / URLs / blob storage — the exact substrate the agent layer (and app_ef) needs, and a clean DI win for ir's own non-agent callers.
- ir_09's MultiAgentAgent (§7) runs subagents in isolated contexts that return distilled pointer-sets across a process/serialization boundary. ir must guarantee its leaf outputs are lossless + numpy-free + carry the pointer so a lead can
ir.disclose them later.
Scope
- Promote
BodyLoader (select.py:67, already Callable[[Mapping], str | None]) to a documented Protocol.
- Add an optional
store: Mapping[str, Any] | None = None param to disclose (and pass-through on discover): when given, a pointer is dereferenced as store[pointer]; when absent, fall back to today's disk _default_body_loader.
- Preserve purity + stale-tolerance: a missing key / unreadable target ->
body=None and metadata['disclosure']='pointer_unreadable' (today's behavior).
- Add
SearchHit.to_dict() casting score to float; audit that no numpy scalar leaks into any *.to_dict() (Selection, Disclosure, DiscoveryResult already have to_dict).
- The eager-vs-lazy question (ir_09 §9) stays the caller's: ir hands back additive
Disclosure objects either way.
API sketch (proposed — store= param, ResourceStore, SearchHit.to_dict do not exist yet)
# ir/select.py
from collections.abc import Mapping
ResourceStore = Mapping[str, Any] # PROPOSED: pointer -> payload (dol store / URL map / blob)
def disclose(selection, *, level='body',
loader: 'BodyLoader | None' = None,
store: 'ResourceStore | None' = None) -> list[Disclosure]: # PROPOSED store=
# if store is not None: body = store.get(pointer) (stale-tolerant)
# else: today's _default_body_loader (disk)
...
# ir/base.py
@dataclass(frozen=True)
class SearchHit:
artifact_id: str
surface_kind: str
score: float
text: str
metadata: dict
def to_dict(self) -> dict: # PROPOSED
return {'artifact_id': self.artifact_id, 'surface_kind': self.surface_kind,
'score': float(self.score), 'text': self.text, 'metadata': dict(self.metadata)}
Design notes
- No new hard dependency;
store is any Mapping (a dol store satisfies it).
- Keeps stale-tolerance: disclosure never raises; missing pointer ->
body=None.
- The numpy-free guarantee is what makes the substrate edge safe for cross-process subagent returns (§7) and for the qh/HTTP facade.
Acceptance criteria
Refs ir_09 §5 (pointer-passing context engineering), §7 (multi-agent subagent boundary), §9 (eager vs lazy dereference — caller's choice).
Summary
Formalize ir_09 §5 pointer-passing into a documented, injectable resource-store contract on
disclose/discover, and guarantee leaf outputs survive a serialization/subagent boundary. ir already implements lazystore[pointer](Disclosure.pointer + POINTER_KEYS +_default_body_loader, select.py:493+) — but the dereference is hard-wired to local disk paths, andSearchHitlacks a publicto_dict()(itsscoremay be a numpy float from dense ranking).Why (rationale)
store[pointer]— aMutableMappingresource store. ir's_default_body_loaderIS that, but only over disk.Mapping[pointer, payload]) lets ir's lazy disclosure work overdolstores / URLs / blob storage — the exact substrate the agent layer (andapp_ef) needs, and a clean DI win for ir's own non-agent callers.ir.disclosethem later.Scope
BodyLoader(select.py:67, alreadyCallable[[Mapping], str | None]) to a documented Protocol.store: Mapping[str, Any] | None = Noneparam todisclose(and pass-through ondiscover): when given, a pointer is dereferenced asstore[pointer]; when absent, fall back to today's disk_default_body_loader.body=Noneandmetadata['disclosure']='pointer_unreadable'(today's behavior).SearchHit.to_dict()castingscoretofloat; audit that no numpy scalar leaks into any*.to_dict()(Selection,Disclosure,DiscoveryResultalready haveto_dict).Disclosureobjects either way.API sketch (proposed —
store=param,ResourceStore,SearchHit.to_dictdo not exist yet)Design notes
storeis anyMapping(adolstore satisfies it).body=None.Acceptance criteria
disclose(sel)with nostore=behaves exactly as today (disk loader).disclose(sel, store={pointer: 'body text'})dereferences via the mapping; a missing key ->body=None+disclosure='pointer_unreadable'.SearchHit.to_dict()exists and castsscoreto a Pythonfloat.*.to_dict()isjson.dumps-able (no numpy scalars) for dense-ranked hits.BodyLoader/ResourceStoreare documented as the §5 resource-store contract.Refs ir_09 §5 (pointer-passing context engineering), §7 (multi-agent subagent boundary), §9 (eager vs lazy dereference — caller's choice).