Skip to content

docs(security): operator-identity binding + cross-principal coherence guard spec (Caroline incident)#897

Open
JKHeadley wants to merge 1 commit into
mainfrom
echo/operator-identity-binding-spec
Open

docs(security): operator-identity binding + cross-principal coherence guard spec (Caroline incident)#897
JKHeadley wants to merge 1 commit into
mainfrom
echo/operator-identity-binding-spec

Conversation

@JKHeadley

Copy link
Copy Markdown
Owner

What

Design spec for the coherency-layer fixes behind the "Caroline" identity-bleed incident (topic 19437, 2026-06-05).

  • docs/specs/OPERATOR-IDENTITY-BINDING-SPEC.md
  • docs/eli16/operator-identity-binding-spec.eli16.md

The incident

On a shared machine (Mac Mini) running multiple agents — Echo plus an agent managing a real person "Caroline"'s accounts — Echo's overnight session silently adopted Caroline as its operator, crediting Justin's own decisions to her across three planning docs ("Locked with Caroline", "Mandate (Caroline)", "have Caroline drop a token"). Forensics: no git action was ever taken as Caroline (exposure unexercised), but the identity/attribution contamination ran deep. Double red flag — security (credential-isolation failure) + coherency (acting on a misidentified operator, undetected).

The fix (two reuse-existing-rails features)

  1. Hard topic-operator binding — each topic's operator is a verified fact taken from the authenticated inbound sender uid (never a name read from content), injected at session start in a <topic-operator> block, immutable for the session. Removes the cause (no hard operator fact → ambient fill).
  2. Cross-principal coherence guard — flags/blocks when an outbound message or freshly-authored doc attributes an operator-role decision (locked-with / approved / mandate / credential-drop) to a principal who isn't the bound operator. Catches the symptom. Warn for prose, block for authority/credential misattributions.

Includes the incident-replay regression test (feed the three real Caroline doc lines through the guard with topic 19437 bound to Justin → all must be caught). Per-agent credential isolation (the security half) is noted as a separate Phase-3 fix.

Scope

Docs-only (spec + eli16). No runtime changes. Phase-1 implementation follows. Tracked: CMT-1125.

ELI16

On a shared machine my overnight session quietly decided a different real person was its boss and credited my actual operator's decisions to her, for hours, unnoticed. This spec makes every agent know — as a hard, verified fact injected at startup — exactly which human is its operator for a conversation (taken from the platform's authenticated sender, never a name in a document), and adds an automatic check that flags it when an agent credits someone else with that operator's decisions. A replay test using the actual incident's text proves it would have caught it.

🤖 Generated with Claude Code

… guard spec (Caroline incident)

Design for the coherency-layer fixes behind the Caroline identity-bleed
(topic 19437, 2026-06-05): a shared-machine agent silently adopted a real
other principal (Caroline) as its operator and credited Justin's own
decisions to her across 3 docs. Two reuse-existing-rails fixes:
(1) hard topic-operator binding established from the AUTHENTICATED inbound
sender (never a content name) + injected at session start, immutable for the
session; (2) cross-principal coherence guard that flags/blocks attributing an
operator-role decision (locked-with/approved/mandate/credential-drop) to a
non-bound principal. Includes the incident-replay regression test. Per-agent
credential isolation (the security half) noted as a separate Phase-3 fix.
Tracked: CMT-1125.
@vercel

vercel Bot commented Jun 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
instar Ready Ready Preview, Comment Jun 6, 2026 5:48am

Request Review

JKHeadley added a commit that referenced this pull request Jun 6, 2026
… Is a Guess' standard (Caroline incident) (#898)

Earned from the Caroline identity-bleed (topic 19437, 2026-06-05): an
autonomous session adopted a real other principal as its operator and never
questioned who she was. The mechanical fix (#897 binding+guard) closes the
gap; this standard installs the missing EPISTEMIC layer — an unrecognized
party in a user/operator/decision role is a QUESTION to resolve against the
user registry, never a fact to accept, and this binds the agent's OWN
reasoning/output, not just inbound messages (the surface no gate watched).
Substrate section. Awaiting Justin's ratification before merge.

Co-authored-by: Instar Agent (echo) <echo@instar.local>
JKHeadley added a commit that referenced this pull request Jun 6, 2026
… (Know Your Principal #898, Phase 1) (#902)

* feat(security): PrincipalGuard — cross-principal attribution detector (Know Your Principal #898, Phase 1 brain)

Pure-logic detector half of the ratified Know Your Principal standard: establish
a topic operator ONLY from the authenticated sender (a content name can never
become the operator — by type), detect operator-role-decision attributions in
agent-authored text, and flag any credited to a non-bound/non-known principal
(block for mandate/credential, warn for prose). 13 unit tests incl. the
incident-replay regression (the real Caroline doc lines all caught; the same
lines crediting the bound operator all pass). No runtime consumers yet — wiring
into the topic-operator binding + session-start injection + review path are
later increments. Spec: docs/specs/OPERATOR-IDENTITY-BINDING-SPEC.md (#897);
incident CMT-1125.

* docs: Know Your Principal site doc + PrincipalGuard module ref (restore docs-coverage class floor)

The new PrincipalGuard core module tipped the docs-coverage class floor (54% <
55%). Fix = document the capability properly: a public 'Know Your Principal'
concept doc on the docs site (the standard is ratified in the constitution) +
an internal module reference. Both mention PrincipalGuard; coverage back to 55%.

---------

Co-authored-by: Instar Agent (echo) <echo@instar.local>
JKHeadley added a commit that referenced this pull request Jun 6, 2026
…tor (Know Your Principal #898, increment 2) (#904)

Decoupled store (state/topic-operators.json) for a topic's verified operator,
established ONLY from the authenticated sender (delegates to
PrincipalGuard.establishOperator — a content name can never become the operator).
Deliberately separate from the ScopeVerifier topic→project binding. Exposes
asVerifiedOperator (feeds the guard) + sessionContextBlock (the <topic-operator>
session-start injection). 10 unit tests (both sides of every boundary +
persistence + content-name-can't-become-operator). No runtime consumers yet.
Spec #897, standard #898, incident CMT-1125.

Co-authored-by: Instar Agent (echo) <echo@instar.local>
JKHeadley pushed a commit that referenced this pull request Jun 6, 2026
…rator routes (Know Your Principal #898, increment 2b)

Composes the merged TopicOperatorStore (#904) into the live AgentServer and
exposes it over HTTP — the runtime arm of the operator-binding spec (#897) and
the ratified "Know Your Principal" standard (#898).

- AgentServer: construct topicOperatorStore under the stateDir guard (own
  try/catch, fail-safe null), pass into routeCtx.
- routes: RouteContext.topicOperatorStore + four Bearer-gated routes —
  GET /topic-operator, GET /topic-operator/:topicId,
  GET /topic-operator/session-context?topicId=N, POST /topic-operator.
- CapabilityIndex: topicOperator entry (prefix /topic-operator) for discovery.

The load-bearing security property is preserved over the wire: the operator is
established ONLY from the authenticated sender uid; a blank uid is refused 400
(a content name can never become the operator — the "Caroline" identity-bleed
mode is impossible by construction). When the store is unwired every route
degrades to 503, never a crash.

Tests: Tier-2 integration (10) over the full HTTP pipeline + Tier-3 E2E (6)
feature-alive on the real AgentServer boot path, durable-write proof, and the
over-the-wire blank-uid refusal. Tier-1 unit shipped in #904.

The session-start HOOK wiring (auto-injecting the <topic-operator> block at boot)
is deliberately deferred to increment 2c (a hook-template + migrateHooks change),
keeping this PR a focused composition+routes change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
JKHeadley added a commit that referenced this pull request Jun 6, 2026
…rator routes (Know Your Principal #898, increment 2b) (#906)

Composes the merged TopicOperatorStore (#904) into the live AgentServer and
exposes it over HTTP — the runtime arm of the operator-binding spec (#897) and
the ratified "Know Your Principal" standard (#898).

- AgentServer: construct topicOperatorStore under the stateDir guard (own
  try/catch, fail-safe null), pass into routeCtx.
- routes: RouteContext.topicOperatorStore + four Bearer-gated routes —
  GET /topic-operator, GET /topic-operator/:topicId,
  GET /topic-operator/session-context?topicId=N, POST /topic-operator.
- CapabilityIndex: topicOperator entry (prefix /topic-operator) for discovery.

The load-bearing security property is preserved over the wire: the operator is
established ONLY from the authenticated sender uid; a blank uid is refused 400
(a content name can never become the operator — the "Caroline" identity-bleed
mode is impossible by construction). When the store is unwired every route
degrades to 503, never a crash.

Tests: Tier-2 integration (10) over the full HTTP pipeline + Tier-3 E2E (6)
feature-alive on the real AgentServer boot path, durable-write proof, and the
over-the-wire blank-uid refusal. Tier-1 unit shipped in #904.

The session-start HOOK wiring (auto-injecting the <topic-operator> block at boot)
is deliberately deferred to increment 2c (a hook-template + migrateHooks change),
keeping this PR a focused composition+routes change.

Co-authored-by: Instar Agent (echo) <echo@instar.local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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