Skip to content

spec: binding attributable human-approval outcomes to step_up and defer execution evidence #191

Open

Description

@Thru-Echoes

Spec section affected
§3.1 (Trust Record claims and evidence composition), §3.3 (verification), and the conformance suite (agentrust-io/trace-tests).

Problem
#114 closed with the decision recorded: 1.0 stays unchanged, and any widened step_up and defer verb set lands under a future profile version, with the version boundary being settled in #116. The closing note names the operator-reported STEP_UP and DEFER semantics the substance of that future version. This issue proposes requirements and a design direction for that substance, so the discussion has a concrete starting point when the version boundary lands.

What the enum alone loses is documented in the #114 thread: who satisfied an escalation, and what its terminal outcome was. Approver identity has to be frozen at emission or the receipt's answer decays by audit time, and a defer without a required terminal state becomes a laundering verb, both per the production report there.

The record currently has no place for either fact. delegation joins machine-delegated authority into the Trust Record (parent_record_hash, credential_id). Human-granted authority has no equivalent join. agent-manifest ADR-0006 defines an attributable approval record (approver-signed, action-bound via evidence_hash, time-bounded, with #40 requiring a human-attributable approver_id), but nothing connects that approval to the run and call that consumed it. The PIC/TRACE authorization bridge binds a pre-execution authorized decision to execution evidence and deliberately keeps authorization and runtime attestation separate; it is allow-only, records no escalation outcomes, and requires no human authorizer, so the escalation lifecycle remains uncovered.

Proposed change
Requirements first, then a candidate direction. Requirements a solution should meet:

  1. A verifier can determine, offline, from an evidence bundle: whether an escalated call's authorization was approved, denied, expired, cancelled, or explicitly closed unresolved, and whether approval evidence was consumed by the recorded run.
  2. Authorization outcomes and execution evidence stay separate lifecycles, joined by identifiers, preserving the boundary the PIC/TRACE bridge establishes.
  3. Approval evidence is attributable to a human principal per ADR-0006 and docs: full doc site upgrade — Getting Started, Integration, Platforms, Schema #40, and is signed by a key the record's subject does not control.
  4. Unresolved outcomes are representable and never silently coerced into approval, denial, or expiry.
  5. Unknown or unsupported profile versions are refused or reported per the obligations proposed in verification.md: format-versioning and verifier-compatibility obligations (evidence outlives verifiers) #116, which controls version and fallback behavior; this issue does not prejudge verification.md: format-versioning and verifier-compatibility obligations (evidence outlives verifiers) #116's resolution.

Candidate direction, offered for discussion rather than as settled design:

Authorization outcome
requested -> approved | denied | expired | cancelled
requested -> closed_unresolved, only through explicit closure evidence

Execution linkage (approved requests only)
approved -> consumed (enforcement allow) | rejected_by_policy
consumed -> executed | fault
  • Each escalation carries a stable decision_id and a canonical action digest, not a transcript index; indexes shift under retries, concurrency, and redaction.
  • The approval evidence is an ADR-0006-form artifact signed by the approver's own key over the decision_id, action digest, audience, run, and validity window. Reuse against another decision or run can leave the signature cryptographically valid, but verification fails on the mismatched bindings.
  • Separation of duties, machine-checkable: the approval key must not be the record's cnf confirmation key, and the approver principal must not resolve to the record's subject under the verifier's identity policy. A platform-asserted approver_id with no approver-verifiable signature fails; it is otherwise the operator-forgery class LIMITATIONS.md names for software-only records.
  • step_up opens an authorization request; defer holds one pending across a policy boundary. Neither authorizes execution by itself. These semantics are proposed here, not current ecosystem behavior.
  • closed_unresolved requires explicit closure evidence; the shape and signer of that evidence is a design question for this thread. In deployment data from a decision-provenance protocol I maintain (github.com/Thru-Echoes/TRACE, a different layer from runtime attestation), 117 of 461 recorded decisions were never resolved, so a schema that forces every escalation into expired misdescribes real workflows.
  • Privacy: portable records carry a scoped pseudonymous approver identifier; identity resolution stays in restricted evidence. This also addresses the identity-decay problem reported in Widen the per-call decision enum under a new profile version, not in 1.0 #114 without freezing personal identifiers into portable, possibly anchored records.

Container: a detached, separately versioned artifact in the bridge's pattern, or an oversight claim in the Trust Record under the new profile version. The bridge precedent suggests the detached artifact; maintainers are better placed to make that call, and this proposal works in either container.

Conformance fixtures I can draft for trace-tests, mirroring the action-receipts set: step_up approved and consumed; step_up denied; approval expired; action digest mismatch; same-party approval (with the verifier identity mapping needed to make the check deterministic); approval reused across decisions; step_up or defer with no oversight binding; defer closed unresolved; missing closure evidence; unsupported profile version.

Backward compatibility

  • Non-breaking

Depends on the container, stated plainly: a detached, separately versioned artifact leaves the Trust Record schema untouched and is non-breaking; an in-record oversight claim is breaking for closed-world v0.2 validators, because additionalProperties: false rejects unknown properties, and so belongs to the next profile version (the vehicle #114 chose), with unknown-version behavior governed by the direction #116 settles. Absence of oversight evidence means no oversight assertion, never that no approval occurred.

Motivation
Auditors ask who approved an escalated call before they ask anything else, per the production report in the #114 thread. Within any profile that records step_up or defer, a decision without an oversight binding should fail verification of a purportedly complete bundle; otherwise an implementation can emit step_up, omit the evidence, and still conform. On the regulatory side, EU AI Act Article 12(3)(d) requires logs for Annex III point 1(a) systems to include the identification of the natural persons involved in verification of results; with the Digital Omnibus in force, those Annex III obligations apply from 2 December 2027. Where an escalated-call approval is part of result verification, attributable oversight outcomes are evidence deployers will need; this proposal supports that evidence without asserting compliance by itself.

Related issues or PRs
#114 (decision recorded; the production report), #116 (format-versioning and verifier obligations; controls version and fallback behavior), the PIC/TRACE authorization bridge (composition precedent; boundary preserved), #66 (two-axis verification; oversight receipts are the human end of the intra-run axis), #117 (GapDisclosure coherence for undisclosed outcomes), agent-manifest ADR-0006 and #40 (attributable approval artifact and approver identity rule).

Activity

  1. imran-siddique commented on Aug 21, 2026

    @imran-siddique
    Member

    Holding this, and saying so rather than leaving it quiet, because it is a serious proposal and the wait is structural rather than a judgement on it.

    The gap you name is the right one. delegation joins machine-delegated authority into the Trust Record through parent_record_hash and credential_id, and human-granted authority has no equivalent join. agent-manifest ADR-0006 defines an attributable approval record, approver-signed, action-bound via evidence_hash, time-bounded, and #40 requires a human-attributable approver_id, but nothing connects that approval to the run and the call that consumed it. Your reading of the PIC/TRACE bridge is also correct: it binds a pre-execution authorized decision to execution evidence and is deliberately allow-only, records no escalation outcomes and requires no human authorizer, so the escalation lifecycle is genuinely uncovered rather than covered elsewhere.

    Both failure modes from the #114 thread are worth keeping in the eventual text in the form you put them: approver identity has to be frozen at emission or the receipt's answer decays by audit time, and a defer with no required terminal state is a laundering verb.

    Two things gate it.

    It is normative, so under CONTRIBUTING it goes through the spec change process with a sponsoring organization rather than being accepted or declined on this thread. I am routing it internally on that basis.

    Independently of that, the substance sits behind #116. #114 closed with the widened verb set landing under a future profile version, and #116, which settles the version boundary and the verifier-compatibility obligations that go with it, is still open. There is no version for this to land in until that is decided, and settling the join before the boundary would mean specifying a field without knowing which format version declares it or what a verifier that does not understand it must do.

    So this stays open as the record of the requirements. Nothing here needs restating when the boundary lands.

  2. Thru-Echoes commented on Aug 21, 2026

    @Thru-Echoes
    ContributorAuthor

    @imran-siddique Thanks for the detailed read. Understood on the internal routing and on #116 settling the version and verifier-compatibility boundary first.

  3. altrudev commented on Aug 23, 2026

    @altrudev
    Contributor

    I think the authorization/execution separation here is the right boundary.

    One additional question from work I have been doing on transition governance: does the future oversight binding also need to commit to the authorization context / predecessor state, rather than only the decision_id and canonical action digest?

    A valid approval plus a matching action receipt can still leave an ambiguity if the action executes against a materially different predecessor than the one the approver evaluated.

    For example:

    S0 -> approval(A, Δ, scope R)

    then before consumption:

    S0 -> S0'

    and the same nominal action A executes against S0'.

    The approval signature, action digest, run binding and execution receipt may all remain individually valid, while the resulting transition is no longer the transition that was actually reviewed.

    That suggests a distinction between:

    • approval validity;
    • approval consumption;
    • execution validity; and
    • transition validity — whether the observed successor remained within the predecessor, mutation, authority/resource scope and invariants on which approval depended.

    I would not necessarily put full application state into TRACE. A predecessor commitment could instead be a canonical digest or reference to the evidence snapshot used for the authorization decision, with successor verification remaining a separate lifecycle.

    Conceptually:

    decision_id + action_digest + authorization_context_digest

    then:

    consumed -> executed -> successor_evidence

    with verification able to detect a stale-predecessor or out-of-envelope transition rather than treating execution of the same nominal action as sufficient closure.

    This seems compatible with the separation already established here: authorization evidence says what was permitted; runtime evidence says what executed; transition evidence answers whether the resulting change remained inside the authority that was actually granted.

    Curious whether this is already intended to fall under the action digest / PIC bridge semantics, or whether predecessor/context binding is still an uncovered layer.

  4. altrudev commented on Aug 23, 2026

    @altrudev
    Contributor

    I turned the predecessor/context question from my earlier comment into a small working prototype so the boundary is easier to inspect concretely.

    Prototype PR: altrudev/Calibration-Studio#7

    It uses the newly merged references mechanism rather than proposing another TRACE field. An external AuthorizationContext/0.1 binds the decision_id, action digest, predecessor digest, policy basis, resource/effect envelope, and validity window; TRACE carries an assurance-neutral authorized-intent reference with its digest. A separate verifier then reports authorization-to-transition closure as VERIFIED, FAILED, or INDETERMINATE, independently of TRACE attestation validity.

    The current test set covers exact-context success, stale predecessor, resource/effect expansion, expiry, context tampering under the same decision ID, missing digest, unresolved reference, missing authorization reference, and exact-successor mismatch (10/10 passing locally).

    The important boundary is preserved: an unresolved external reference does not invalidate the TRACE Trust Record, and resolving it does not turn the referenced object into TRACE-attested evidence.

    This is intentionally informative research tooling rather than a normative wire-format proposal. If this composition is directionally useful for #191 after #116 settles, I can adapt the fixtures/semantics to whatever container the maintainers choose.

  5. altrudev commented on Aug 24, 2026

    @altrudev
    Contributor

    Follow-up: I ran the prototype through a full post-build DDC audit and updated the public implementation to v0.2.

    The audit found a real flaw in my first pass: field/digest agreement alone could over-promote external authorization and observation objects to VERIFIED, even though TRACE references are pointers rather than attested truth. v0.2 now requires independent verification of both external evidence classes before closure can become VERIFIED.

    The hardened version also adds:

    • exact predecessor binding;
    • TRACE.policy.bundle_hash ↔ authorization policy_digest binding;
    • ambiguity rejection for multiple authorized-intent references;
    • strict context/observation validation;
    • constrained canonicalization without claiming RFC 8785 equivalence;
    • optional approval-outcome presence/ambiguity checking;
    • preservation of TRACE attestation as an independent result.

    So a valid TRACE record can coexist with closure FAILED or INDETERMINATE; this layer never upgrades or downgrades TRACE itself.

    The expanded adversarial gate is 20/20 passing.

    Updated prototype: altrudev/Calibration-Studio#7

    I’m stopping here rather than proposing a normative TRACE change; the intent is to make the composition question executable and falsifiable against the current references model.

  6. lywinged commented on Aug 24, 2026

    @lywinged
    Collaborator

    Follow-up: I ran the prototype through a full post-build DDC audit and updated the public implementation to v0.2.

    The audit found a real flaw in my first pass: field/digest agreement alone could over-promote external authorization and observation objects to VERIFIED, even though TRACE references are pointers rather than attested truth. v0.2 now requires independent verification of both external evidence classes before closure can become VERIFIED.

    The hardened version also adds:

    • exact predecessor binding;
    • TRACE.policy.bundle_hash ↔ authorization policy_digest binding;
    • ambiguity rejection for multiple authorized-intent references;
    • strict context/observation validation;
    • constrained canonicalization without claiming RFC 8785 equivalence;
    • optional approval-outcome presence/ambiguity checking;
    • preservation of TRACE attestation as an independent result.

    So a valid TRACE record can coexist with closure FAILED or INDETERMINATE; this layer never upgrades or downgrades TRACE itself.

    The expanded adversarial gate is 20/20 passing.

    Updated prototype: altrudev/Calibration-Studio#7

    I’m stopping here rather than proposing a normative TRACE change; the intent is to make the composition question executable and falsifiable against the current references model.

    Ran it rather than read it — clean clone, refs/pull/7/head at a4fad71, Python 3.11. What reproduces, first: the gate is 20/20 as stated, and the commit history corroborates the audit account (harden after audit, then expand to 20). Your references entry validates against schema/trace-claim.json and the Reference model as merged; the fixture's digest recomputes byte-for-byte under your canonicalization; and the two rel values you chose are the registered ones in spec §3.1.2, used for exactly their registered semantics — approval-outcome is registered as "an attributable human approval attached to a step-up or defer decision", so this composition is per-spec, not off-label. Your boundary reading is also the text: rule 3 is "a verifier MUST NOT reject a record because an entry in references cannot be resolved, and MUST NOT treat a resolved reference as attested evidence", and the flaw your audit caught in v0.1 was a violation of its second clause, which v0.2 now honors.

    Your open question, answered by running it: verify_bridge takes bridge, trusted_authorizer_jwk, declaration, pic_intent_digest, pic_args_digest, tool_call, transcript, now — no input carries state. One signed bridge verified unchanged against two contradictory world-states in the same probe. Predecessor/context binding is an uncovered layer, not implicit in the action digest.

    Now the part I would want someone to tell me. I put the verifier under the same instrument that found the test gaps behind trace-spec #203/#204: neutralize each decision site, one at a time, and re-run your suite. I could neutralize twenty-six of them as units. Fifteen turn the suite red. Eleven leave all 20 tests green, and they include the joins the proposal is about:

    neutralized suite
    DECISION_ID_MISMATCH (observation ↔ context) 20 passed
    ACTION_DIGEST_MISMATCH (observation ↔ context) 20 passed
    REFERENCE_DECISION_ID_MISMATCH (ref.id ↔ context) 20 passed
    EXECUTED_BEFORE_AUTHORIZATION_VALID 20 passed
    the whole _validate_observation block 20 passed
    the AuthorizationContext/0.2 type check 20 passed
    the ObservedTransition/0.2 type check 20 passed
    AMBIGUOUS_APPROVAL_OUTCOME_REFERENCES 20 passed
    the canonicalization except (re-raise instead) 20 passed
    the observed_transition is None branch — no test reaches it 20 passed
    the unresolved-context return — its test asserts status only, so the named reason can be replaced 20 passed

    Of decision_id + action_digest + authorization_context_digest, the context digest is guarded and the other two joins are not. Branch coverage corroborates the sweep independently: the file sits at 81% branch-inclusive under your suite, and ten of the eleven sites are among the missing lines — the eleventh, the unresolved-context return, is covered, which is exactly the difference between an unreached guard and a weakly asserted one. The remainder of the gap is the field branches inside both validators, the non-list references return, and to_dict. The audit's own additions — both evidence-authenticity gates — are guarded, which is the pattern worth naming: a self-audit catches the class it is looking for.

    Six smaller ones, all run against unmodified code:

    • Boolean timestamps verify. not_before=False, expires_at=True, executed_at=True reaches VERIFIED — isinstance(True, int) is true and nothing excludes bool. The PIC bridge explicitly does (or isinstance(..., bool)).
    • A proven mismatch can be demoted. A tampered context (AUTHORIZATION_CONTEXT_DIGEST_MISMATCH already appended) plus a record with no policy.bundle_hash returns INDETERMINATE, because the policy-unavailable return fires while reasons is non-empty. Deleting one's own policy field converts contradiction evidence into "insufficient evidence"; returning FAILED with TRACE_POLICY_BINDING_UNAVAILABLE appended preserves both facts.
    • The digest charset runs opposite to the schema, in both directions. DIGEST_RE accepts uppercase hex, which the schema's ^sha(256:[0-9a-f]{64}|384:[0-9a-f]{96})$ forbids — so the tool accepts a digest no conforming record can carry. And it rejects sha384:, which the schema allows — a conforming record using sha384 returns INDETERMINATE with AUTHORIZED_INTENT_REFERENCE_HAS_NO_VALID_DIGEST, a reason string that is false as stated: the digest is valid TRACE, just unsupported here. If sha256-only is a deliberate v0.2 constraint, SPEC.md should say so and the reason should say "unsupported"; otherwise widening the regex to the schema's pattern closes both ends.
    • Malformed is reported as absent. references as an object rather than an array — a schema-invalid record — returns MISSING_AUTHORIZED_INTENT_REFERENCE. Harmless verdict, wrong diagnosis.
    • The integer half of the number problem is open. A context carrying 2**53 digests fine here, while rfc8785.dumps raises IntegerDomainError on the same object — so an artifact can exist whose digest a JCS-side implementation cannot recompute, which is the cross-language drift the constrained encoding exists to prevent. Floats are closed; large ints are not.
    • Expiry boundary is the opposite of the bridge's. executed_at == expires_at is valid here (>), expired under the bridge (>=); a zero-width window is valid here and rejected there ("expires_at must be after authorized_at"). Worth pinning in SPEC.md whichever way you decide.

    One boundary observation rather than a finding, because SPEC.md already discloses it plainly: no signature is created or checked anywhere in this layer, and trace_attestation is a caller-supplied string. That is the right layering — but it makes spec rule 2, "the record signature MUST cover references", the load-bearing wall of the whole composition. Concretely: a context widened to cover extra resources, with the record's reference digest rewritten to match, reaches closure VERIFIED — only the TRACE signature over references can catch that rewrite, so a consumer has to AND both verdicts, never read closure alone. Your README's composition diagram already draws runtime attestation as an independent arrow off the Trust Record; I am confirming that independence holds under attack, and that the one probe which defeats closure is exactly the one TRACE attestation exists to stop.

    I also wrote the twelve tests the sweep says are missing and re-ran the whole neutralization against the enlarged suite: 32 passed intact, and every one of the eleven silent sites now turns red when neutralized. Happy to send the test file and the mutation script — everything above reproduces from git fetch origin refs/pull/7/head && git checkout FETCH_HEAD && python -m pytest research/trace-transition-closure/tests/.

    None of this moves the architecture. The layering is right, the failure directions are right, and once the missing tests exist this is the strongest external exercise the references block has had.

  7. altrudev commented on Aug 24, 2026

    @altrudev
    Contributor
  8. lywinged commented on Aug 24, 2026

    @lywinged
    Collaborator

    @altrudev both files are on Calibration-Studio#7 rather than here, so the code sits where it runs and this issue stays about the proposal.

    The twelve tests are the file from my comment, unchanged. The mutation script is a rebuild: the original ran in a container that has since been reclaimed and only the tests were saved, so treat the tests as the artifact and the script as the method made executable. Two defects I found while rebuilding are written up there, and the first one matters if you keep a sweep as a gate: stale bytecode made two runs of the identical sweep over the identical tree return different counts.

  9. Thru-Echoes commented on Aug 24, 2026

    @Thru-Echoes
    ContributorAuthor

    The discussion above surfaces two distinct scope questions for the requirements record:

    1. Predecessor binding: whether the evidence must let a verifier determine that a consumed approval was evaluated against the predecessor context represented by the execution evidence. So a stale predecessor is detectable rather than passing silently.
    2. Transition conformance: whether the evidence must also let a verifier determine that the observed successor stayed. within the approved resource and effect envelope.

    @altrudev raised both. And their distinction between approval validity, consumption, execution validity, and transition validity is the useful frame.

    @lywinged reported that verify_bridge takes no state input and concluded that predecessor / context binding is an uncovered layer rather than something implicit in the action digest.

    Candidate fixtures from the thread, alongside the 10 in the issue body: stale predecessor, authorization context digest mismatch valid context with an out-of-envelope successor.

    Recording these here as open questions, not settled scope.

    Thanks!

  10. altrudev commented on Aug 24, 2026

    @altrudev
    Contributor
  11. imran-siddique commented on Aug 26, 2026

    @imran-siddique
    Member

    Lifting the hold. I said on 08-21 that this was waiting on #116 settling the version and verifier-compatibility boundary, and I have just split #116 in a way that removes the dependency.

    The short version: #116 carried four obligations, and only two of them are testable at all today. @lywinged measured their own vector set against a deliberately non-implementing verifier and it separated on 3 of 8. The structural cause, which I verified, is that schema/trace-claim.json pins eat_profile with a const and verify_record validates against that schema, so a non-v0.2 record is refused before any profile rule runs. No verdict-based vector can isolate the two from each other.

    The half this issue depended on is the observable half. What #191 needs from #116 is the obligation that a verification statement names the version it ran under, because an attributable approval outcome consumed years later is meaningless if the statement does not say what semantics it was evaluated against. That obligation is non-normative verifier behaviour plus vectors, needs no sponsor, and is moving. The two obligations still parked behind sponsorship are the emitter-side version carriage and the downgrade-disclosure rule, and neither is what this proposal rests on.

    So the wait here was real but I scoped it too broadly.

    On the scope split

    @Thru-Echoes, your separation into predecessor binding and transition conformance is the right cut and I am adopting it. They answer different questions, they can be evidenced independently, and collapsing them would produce a requirement that is hard to satisfy and harder to test. @altrudev agreeing to keep them apart rather than defending the combined framing is what made that clean.

    Predecessor binding is the one closer to landable: whether the evidence lets a verifier determine that a consumed approval was evaluated against the predecessor context the execution actually represents. Transition conformance is a larger question and should not gate it.

    On the prototype work

    @altrudev, running your own post-build audit and finding that field and digest agreement alone could over-promote external authorization objects, then shipping v0.2 rather than leaving v0.1 standing, is the reason this thread produced something. Self-audit that changes your own answer is rarer than review that changes someone else's.

    @lywinged, the mutation sweep showing 20/20 reproducible was not the same as 20/20 meaningful is the same finding you brought to #116 from a different direction, on someone else's code this time. Reproducibility measures the harness; separation measures the claim. Worth noting you have now demonstrated that twice in a week on two independent artifacts.

    Keeping the code on Calibration-Studio#7 so it sits where it runs, while this issue stays about the proposal, was the right call for both of you.

    This stays policy: take-internal, because the normative text still needs a sponsor and a maintainer carries any resulting spec change. That has not altered. What has altered is that it is no longer waiting on #116.

  12. imran-siddique commented on Aug 26, 2026

    @imran-siddique
    Member

    Tracking issue opened: #226, holding the rel registry as one question across #191, #209, #220 and the transition-closure thread.

  13. Thru-Echoes commented on Aug 27, 2026

    @Thru-Echoes
    ContributorAuthor

    Thanks for lifting the hold!

    Update to this issue:
    Recording the split here as you adopted it: predecessor binding is the nearer half and stays with this record. Transition conformance is an open question here and odes not gate it.

    Requirement 5 (unknown / unsupported versions refused or reported per #116) rests on the 2 obligations now moving there - the declared supported set with refusal outside it and the statement that names the version it ran under - so nothing in this record waits on the parked half.

    The body's container question predates section 3.1.2. Your #197 closing note lists this record among the bindings that consume that block --> that is the join. i.e. an approval-outcome entry in references, with digest committing to the approval artifact, keeps requirement 2 and touches nothing in the Trust Record beyond references.

    What belongs in #226 is which values this needs (beyond approval-outcome) and what a verifier may conclude from each.

  14. altrudev commented on Aug 27, 2026

    @altrudev
    Contributor
  15. imran-siddique commented on Sep 3, 2026

    @imran-siddique
    Member

    Two things, and neither reopens anything settled here.

    The split is holding and the thread has self-organised well. @Thru-Echoes recorded the split as adopted, @altrudev confirmed it, and §3.1.2 resolved the old container question: an approval-outcome entry in references with a digest committing to the approval artifact gives the join without a new Trust Record field. That is the right answer and nothing here needs me.

    The indeterminate case is not local to this issue. An attributable human-approval outcome that cannot be established is the same primitive as an unresolvable citation (#190), a re-run that could not be attempted (#249), a missing GPU half (#192), and an undecidable corpus case (#206). Filed #279 as the tracker, with the rule taken from #260: absence gets a name and a reason per surface, never a shared null, and never a value that can be reached by falling through.

    @altrudev, on Calibration-Studio#7 waiting for #226 to settle the normative-versus-informative boundary: that is the right place to hold it and the boundary you are preserving, reference integrity being distinct from authorization validity, approval consumption, execution validity and external-outcome identity, is exactly what #279 exists to keep from being flattened. Worth cross-linking the artifact from #279 when #226 settles.

    #279

  16. removed
    policy: take-internalIndividual-authored normative spec change; handled internally per policy
    on Sep 3, 2026
  17. imran-siddique commented on Sep 7, 2026

    @imran-siddique
    Member

    Keep predecessor binding in this issue and transition conformance separate. The existing approval-outcome reference plus digest resolves the container question. Additional relation vocabulary remains coordinated in #226, with absence outcomes tracked in #279.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions