The problem
modifications.json states the gap in its own description:
The provenance of values introduced by 'parameter_overrides' is not defined in v0.1.
So this is not a defect report. It is a request to close a deferral, and an argument for why it should close in v0.2 rather than drift.
parameter_overrides replaces tool call arguments. A replaced argument is a value the Guardian introduced into an execution path. Nothing on the wire records where that value came from.
The obvious answer, that metadata.evaluator already says which layer decided, does not hold. evaluator is an enum of deterministic, agent, composite, and it sits on the decision rather than on the modification. Two things follow. A decision carries one evaluator value and may carry many overrides, so the attribution is one-to-many at best. And composite exists precisely for the case where both layers contributed, which makes decision-level attribution insufficient by construction rather than by omission. When evaluator is composite, the schema is saying that some of this decision came from the model and some did not, and offering no way to tell which part is which.
Why the wire has to carry it
The two-layer Guardian architecture depends on the deterministic layer being authoritative and the agent layer being constrained. That constraint is enforceable only if a consumer can tell the two apart.
A rewritten tool argument that originated in the agent layer is a model-authored value entering an execution path. That is the same trust-boundary crossing the specification takes seriously everywhere else. post-compact.json requires derived_from on a summary and states that "No amount of LLM processing launders untrusted-classified data into trusted-classified data." skill-load.json carries a digest rather than a digest_verified boolean so the Guardian can verify the binding itself instead of trusting the framework. The reasoning in both transfers to an overridden argument without modification.
It cannot be reconstructed downstream. The runtime receives {"path": "value"} and applies it. The layer that authored it is knowable only at the moment of authorship, inside the Guardian, and is gone by the time anything else sees the decision. That is the condition for putting something on the wire.
Shape, attached to the override rather than the decision: each entry in parameter_overrides carries the authoring layer, drawn from the same deterministic / agent / composite vocabulary metadata.evaluator already uses, so the enum is reused rather than invented. Optional in the base schema, consistent with how provenance is handled, and a candidate for the acs-provenance strict variants where it would become required.
Which constituencies this affects
Alternatives considered
Leave it deployment-defined, which is the v0.1 position. Defensible for v0.1 and getting harder to hold. The reference Guardian is being built now, adapters are landing in PR #22, and each implementation that ships without this makes one up. The HKDF situation in #118 is the same shape one step further along: an underspecified detail becomes a de facto profile set by whoever implements first.
Ride metadata.evaluator. Covered above. One value per decision, and composite defeats it outright.
Ride cited_provenance_ids. That field answers which provenance objects drove the verdict. It does not answer who authored a value the verdict introduced, which is the opposite direction of travel.
Commit the full decision record to the chain, per Discussion #115. This is complementary and possibly the better home. If the chain commits the disposition, the rules that fired, and the inputs relied on, then layer attribution is a field in that record rather than a field in modifications. Worth deciding which of the two carries it before either is built.
Discussion link
#150
Discussion #115 is the adjacent thread on committing the full decision record to the chain, and #150 names it as the question to settle first.
Current Priority Scope
Feeds the runnable Guardian reference implementation
The problem
modifications.jsonstates the gap in its own description:So this is not a defect report. It is a request to close a deferral, and an argument for why it should close in v0.2 rather than drift.
parameter_overridesreplaces tool call arguments. A replaced argument is a value the Guardian introduced into an execution path. Nothing on the wire records where that value came from.The obvious answer, that
metadata.evaluatoralready says which layer decided, does not hold.evaluatoris an enum ofdeterministic,agent,composite, and it sits on the decision rather than on the modification. Two things follow. A decision carries oneevaluatorvalue and may carry many overrides, so the attribution is one-to-many at best. Andcompositeexists precisely for the case where both layers contributed, which makes decision-level attribution insufficient by construction rather than by omission. Whenevaluatoriscomposite, the schema is saying that some of this decision came from the model and some did not, and offering no way to tell which part is which.Why the wire has to carry it
The two-layer Guardian architecture depends on the deterministic layer being authoritative and the agent layer being constrained. That constraint is enforceable only if a consumer can tell the two apart.
A rewritten tool argument that originated in the agent layer is a model-authored value entering an execution path. That is the same trust-boundary crossing the specification takes seriously everywhere else.
post-compact.jsonrequiresderived_fromon a summary and states that "No amount of LLM processing launders untrusted-classified data into trusted-classified data."skill-load.jsoncarries a digest rather than adigest_verifiedboolean so the Guardian can verify the binding itself instead of trusting the framework. The reasoning in both transfers to an overridden argument without modification.It cannot be reconstructed downstream. The runtime receives
{"path": "value"}and applies it. The layer that authored it is knowable only at the moment of authorship, inside the Guardian, and is gone by the time anything else sees the decision. That is the condition for putting something on the wire.Shape, attached to the override rather than the decision: each entry in
parameter_overridescarries the authoring layer, drawn from the samedeterministic/agent/compositevocabularymetadata.evaluatoralready uses, so the enum is reused rather than invented. Optional in the base schema, consistent with howprovenanceis handled, and a candidate for theacs-provenancestrict variants where it would become required.Which constituencies this affects
Alternatives considered
Leave it deployment-defined, which is the v0.1 position. Defensible for v0.1 and getting harder to hold. The reference Guardian is being built now, adapters are landing in PR #22, and each implementation that ships without this makes one up. The HKDF situation in #118 is the same shape one step further along: an underspecified detail becomes a de facto profile set by whoever implements first.
Ride
metadata.evaluator. Covered above. One value per decision, andcompositedefeats it outright.Ride
cited_provenance_ids. That field answers which provenance objects drove the verdict. It does not answer who authored a value the verdict introduced, which is the opposite direction of travel.Commit the full decision record to the chain, per Discussion #115. This is complementary and possibly the better home. If the chain commits the disposition, the rules that fired, and the inputs relied on, then layer attribution is a field in that record rather than a field in
modifications. Worth deciding which of the two carries it before either is built.Discussion link
#150
Discussion #115 is the adjacent thread on committing the full decision record to the chain, and #150 names it as the question to settle first.
Current Priority Scope
Feeds the runnable Guardian reference implementation