Skip to content

feat(intent-bridge): bind successor observations for #338 - #340

Open
altrudev wants to merge 19 commits into
agentrust-io:mainfrom
altrudev:prototype/successor-observation-v0
Open

feat(intent-bridge): bind successor observations for #338#340
altrudev wants to merge 19 commits into
agentrust-io:mainfrom
altrudev:prototype/successor-observation-v0

Conversation

@altrudev

@altrudev altrudev commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Implements #338 as the narrow successor-observation extension accepted in the issue review.

Governing rule

The bridge must not treat a bound transcript.after object as proof that a requested real-world transition occurred.

This PR keeps successor integrity separate from successor sufficiency:

  • the exact successor envelope is bound with the bridge's RFC 8785 / SHA-256 identity relation;
  • the binding covers observation content, observer identity, and observation timestamp;
  • trust, freshness, observer-independence policy, and the transition predicate are evaluated separately;
  • outcomes stay surface-local: established, contradicted, or not-established;
  • malformed artifacts and digest mismatches are refusals, not evidence outcomes;
  • absent successor evidence is not-established, never a positive result;
  • executor/observer separation is required only when verifier policy requires it.

Integration

The exact-envelope binding now lives in agentrust_trace.intent_bridge, alongside the existing canonical-byte binding for transcript.before.tool_call.

The tri-state successor evaluator remains separate so a successful integrity check cannot silently become transition closure.

The informative PIC/TRACE bridge profile now states the assurance boundary for requirements 2, 4, and 5, including the treatment of absent after.

No TRACE Trust Record schema change. No replay semantics. No universal transition-predicate language. No application-state store.

Adversarial coverage

The existing #340 matrix covers:

  • valid bound trusted successor -> established;
  • trusted contradictory successor -> contradicted;
  • absent successor -> not-established;
  • observation substitution -> refusal;
  • observer relabelling -> refusal;
  • timestamp retiming -> refusal;
  • stale/untrusted successor -> not-established;
  • executor self-observation with independence required -> not-established;
  • executor self-observation when independence is not required -> established;
  • undecidable predicate -> not-established.

AI-assistance disclosure: ChatGPT assisted with DDC radial analysis, implementation drafting, and adversarial review. altrudev remains responsible for the contribution.

Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
@github-actions

github-actions Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

🔴 Contributor Check: HIGH

Check Result
Profile HIGH
Credential LOW
Overall HIGH

Automated check by AgenTrust Contributor Check.

@github-actions github-actions Bot added the needs-review:HIGH Contributor check flagged HIGH risk label Sep 12, 2026
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
Signed-off-by: altrudev <266135212+altrudev@users.noreply.github.com>
@altrudev altrudev changed the title prototype: evaluate bound successor observations for #338 feat(intent-bridge): bind successor observations for #338 Sep 13, 2026

@rajnisht7 rajnisht7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integrity vs sufficiency split is in looks in the right direction, but there are a few gaps:

  • verify_bridge() still does not bind the successor When transcript_required is true, the path still ends roughly as:
if not isinstance(transcript.get("after"), dict):
    raise AuthorizationMismatch(...)

and there is no call to _bind_successor_observation(), and no check against a successor digest.

  • expected_successor_digest is not authenticated by the bridge evaluate_successor_observation(..., expected_successor_digest=...) only checks:
    digest(after) == expected_successor_digest
    That expected value is caller-supplied and it is not a field of the signed authorization, and schema/pic-trace-bridge-v1.json has no successor digest either. The module docstring even says the prototype does not decide whether that digest lives in the signed authorization, the transcript, or a detached artifact.

  • #338 says that when a profile makes a successor-state claim, the verifier must establish the exact observation for this evaluation, so substituted/replayed after objects can be detected.
    If the caller can also choose expected_successor_digest, a substituted observation can still be made to “match” by passing expected = digest(forged_after). Until the expected digest is tied to something authenticated (signed authorization, committed transcript field, or a detached artifact that is itself verified), requirement 1 is only partly met.

  • Two meanings of after:
    In verify_bridge: after = any execution-result object (dict).
    In _bind_successor_observation: after = exactly {observation, observer, observed_at}.

  • Docstrings still say “prototype” while the PR title is feat(...).

  • Optional tests: future observed_at, max_age_seconds == 0, empty trusted_observers (logic looks fine when tried manually).

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

Labels

needs-review:HIGH Contributor check flagged HIGH risk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants