VerifierOracle.read and JsonDocumentOracle.read in
openadapt_flow/reward/oracles.py take an identity argument, stamp it onto
the observation, and then read the whole collection. VerifierOracle calls
capture_post_state(None) with no selector at all. So current inside
judge_episode holds every record the store will return, including rows
belonging to other subjects.
The subject enters the judgement in one place only: the required effect's own
match selector, resolved against the identity by worker._bind. A load-time
guard in RewardBundle.load now refuses a bundle whose required effects select
no record by a declared oracle.identity_keys entry, so the gap can no longer
be authored by accident.
That guard checks the contract. It does not scope the read, and two costs
remain:
- Evidence. The observation goes into the receipt's evidence digest, so a
receipt naming one patient is computed over a snapshot holding many.
- Volume. On a substrate with a large collection the worker pulls far more of
the store than the episode needs.
The fix is to pass identity down to the verifier and let each substrate
scope its own read: a path template or query parameter for REST, a WHERE
clause for SQL, a search parameter for FHIR, a path prefix for the file and
document verifiers. That means an identity argument on
EffectVerifier.capture_post_state and, per adapter, a declared mapping from
an identity key to that substrate's query language. An identity key an adapter
cannot map should refuse rather than fall back to the unscoped read.
One question to settle in the same change: whether an oracle read that returns
a record outside the declared identity is itself grounds for refusal, or only
for a narrower observation.
Opened by an agent session, not the founder.
VerifierOracle.readandJsonDocumentOracle.readinopenadapt_flow/reward/oracles.pytake anidentityargument, stamp it ontothe observation, and then read the whole collection.
VerifierOraclecallscapture_post_state(None)with no selector at all. Socurrentinsidejudge_episodeholds every record the store will return, including rowsbelonging to other subjects.
The subject enters the judgement in one place only: the required effect's own
matchselector, resolved against the identity byworker._bind. A load-timeguard in
RewardBundle.loadnow refuses a bundle whose required effects selectno record by a declared
oracle.identity_keysentry, so the gap can no longerbe authored by accident.
That guard checks the contract. It does not scope the read, and two costs
remain:
receipt naming one patient is computed over a snapshot holding many.
the store than the episode needs.
The fix is to pass
identitydown to the verifier and let each substratescope its own read: a path template or query parameter for REST, a
WHEREclause for SQL, a search parameter for FHIR, a path prefix for the file and
document verifiers. That means an identity argument on
EffectVerifier.capture_post_stateand, per adapter, a declared mapping froman identity key to that substrate's query language. An identity key an adapter
cannot map should refuse rather than fall back to the unscoped read.
One question to settle in the same change: whether an oracle read that returns
a record outside the declared identity is itself grounds for refusal, or only
for a narrower observation.
Opened by an agent session, not the founder.