Skip to content

adk: stamp observation_mode on every capsule (in_path / event_stream) — #33 reference use - #46

Merged
StevenMih merged 1 commit into
mainfrom
rehome/observation-mode
Aug 6, 2026
Merged

adk: stamp observation_mode on every capsule (in_path / event_stream) — #33 reference use#46
StevenMih merged 1 commit into
mainfrom
rehome/observation-mode

Conversation

@StevenMih

Copy link
Copy Markdown
Contributor

Same-repo rebase of #27 (thisjody), which fails neutrality solely because fork PRs don't receive the NEUTRALITY_TERMS secret by design. Author credit preserved — content and design are Jody's own; two review fixes below are new in this rebase.

The implementation half of #33, paired with the spec text in action-state-group/agent-action-capsule#35 (merged as #41), which defines the field and the compute_attestation container it rides in.

Every ADK capsule now states how its producer observed the action it sealed:

  • Callback path + manual seals (guard/emit_blocked/emit_denied/emit_errored) stamp in_path.
  • Event-stream tap stamps event_stream.

Two review fixes carried over, both mutant-verified

  1. Stamp last, not first. The four in_path call sites built extra_compute as {"observation_mode": "in_path", **_compute_from_context(ctx)} — literal-then-spread, so a context key literally named observation_mode would silently overwrite the stamp. Flipped to spread-then-literal so the stamp always wins. Confirmed via a constructed collision: old order → silently corrupted; new order → correctly wins.
  2. Tests assert on parsed structure, not a json.dumps substring. The old test had a dead or clause that would pass even with a wrong stamp value, so long as "in_path" appeared anywhere else in the capsule (e.g. an action_id). Confirmed via a constructed capsule with a wrong observation_mode but a substring-colliding action_id: old check passed, new check correctly failed.

Deliberately small: five emit sites, one stamp each, plus a docstring section. 28/28 (test_adk.py), 319/319 full suite (excluding the optional agentgateway extra — pre-existing/unrelated grpc dependency gap, confirmed present on unmodified main too), ruff clean.

🤖 Generated with Claude Code

#33 reference use

Every ADK capsule now states how its producer observed the action it
sealed:

- Callback path + manual seals (guard/emit_blocked/emit_denied/
  emit_errored) stamp in_path — the emitter executes in the action's own
  call path and binds input/output from its own position.
- Event-stream tap stamps event_stream — the emitter observes the runner's
  narration after the fact, where id-less pairing is best-effort.

This adapter is why the field earns its keep: the same emitter genuinely
observes from two different proximities depending on integration shape,
and before this stamp the two capsules were indistinguishable. Provenance,
not a quality score — the capsule states its vantage, the consumer decides
the weight.

Two review fixes carried over from PR #27 (thisjody), both mutant-verified:

- Stamp last, not first: the four in_path call sites built extra_compute
  as {"observation_mode": "in_path", **_compute_from_context(ctx)} —
  literal-then-spread, so a context key literally named observation_mode
  would silently overwrite the stamp. Vanishingly unlikely given the
  allow-list _SAFE_CONTEXT_ATTRS enforces, but it's precisely the fail-open
  pattern #26 (context-hygiene) argues against right next to this PR.
  Flipped to spread-then-literal so the stamp always wins.
- Tests now assert on the parsed capsule structure
  (model_attestation.compute_attestation.observation_mode) instead of a
  json.dumps(capsule) substring check. The old check had a dead
  clause ("in_path" in json.dumps(...)) that would pass even if the field
  were wrong, so long as the substring appeared anywhere else in the
  capsule (e.g. an action_id). Confirmed via a constructed capsule with a
  wrong observation_mode but a substring-colliding action_id: old check
  passed, new check correctly failed.

Original PR #27 (thisjody, fork feat/observation-mode branch) failed the
neutrality gate solely because fork PRs don't receive the NEUTRALITY_TERMS
secret by design. Rebased as this same-repo branch so the gate can run.
Author credit preserved — content and design are Jody's own; only the two
review fixes above are new in this rebase.

Deliberately small: five emit sites, one stamp each, plus a docstring
section. Tests: 28/28 (test_adk.py), 319/319 full suite (excluding the
optional agentgateway extra, pre-existing/unrelated grpc dependency gap),
ruff clean.

Signed-off-by: stevenmih <stevenmih88-3@gmail.com>
@StevenMih
StevenMih merged commit 89c5188 into main Aug 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant