Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions .agents/pm/decisions/pm-qwuber.toon
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
id: pm-qwuber
title: "ADR: agent identity model — stable author namespace plus structured harness, model, and session provenance"
description: "pm already resolves an acting identity without PM_AUTHOR (pm-z9x1r2, closed 2026-07-25) and already writes an author_source discriminator. The recorded identity is still a single opaque string in the harness:<name> namespace: src/core/shared/author.ts returns { author, source, harness? } and nothing anywhere records WHICH MODEL performed the mutation. In a fleet where a claude-opus-5 session, a claude-haiku-4-5 session, and a GLM-5.2 session all run under harness:claude-code or harness:pi, every downstream question that matters — which model produced the rework, which model's context packing needs a different profile, which model may hold a claim — is unanswerable from history. This ADR decides the identity data model before any implementation lands, because identity is written into immutable history and is therefore effectively unchangeable after the fact. Options considered: (a) widen the author string to harness:<harness>/<model> — cheap, greppable, but explodes author cardinality, breaks every existing equality filter, and conflates a stable principal with a volatile runtime attribute; (b) keep author as the stable principal namespace and add structured provenance fields (agent_harness, agent_model, agent_model_source, agent_session) to the history entry and to the resolved identity — preserves existing filters, keeps cardinality bounded, and lets model be absent without making the author unknown; (c) full principal identity with signatures — deferred to pm-u14c. Recommended: (b), with (a) available as a rendering concern only."
description: Decide the stable author and structured harness/model provenance contract while keeping invocation session identifiers transient and non-durable.
type: Decision
status: open
status: closed
priority: 1
tags[7]: adr,agent-ux,"area:sdk",author,governance,identity,provenance
created_at: "2026-07-25T12:24:02.830Z"
updated_at: "2026-07-25T12:34:57.630Z"
updated_at: "2026-07-25T20:06:40.746Z"
closed_at: "2026-07-25T20:06:39.645Z"
author: "harness:claude-code"
estimated_minutes: 180
acceptance_criteria: "The decision states whether model belongs in the author string or in structured provenance fields, with the rejected options and their reasons recorded; The decision names every provenance field, its type, its cardinality expectations, and its absence semantics (a missing model must never degrade the author to unknown); The decision states explicitly that detected identity is an unverified claim and may never be used as an authorization input, deferring verified identity to pm-u14c; The decision states the privacy contract: which identity dimensions may reach telemetry, in what hashed form, and which must never leave the machine; The decision states the compatibility rule for workspaces written before model capture existed, so old streams stay valid and verifiable; A superseding or amending decision is required before any later change to the recorded identity shape"
Expand All @@ -19,6 +20,9 @@ why_now: Model capture is about to be implemented; identity fields are append-on
parent: pm-m2u1
risk: medium
confidence: 75
resolution: Accepted durable identity is stable author plus optional harness/model/model-source; session signals remain transient and non-serializable.
expected_result: "A written, privacy-bounded, backward-compatible identity decision governs SDK, CLI, MCP, history, and telemetry."
actual_result: "ADR amended and implemented; raw branch-local session fields were scrubbed and all 2,028 history streams verify without drift."
dependencies[11]{id,kind,created_at,author,source_kind}:
pm-33cw,related,"2026-07-25T12:24:02.830Z",null,null
pm-42p9nk,related,"2026-07-25T12:24:02.830Z",null,null
Expand All @@ -31,4 +35,23 @@ dependencies[11]{id,kind,created_at,author,source_kind}:
pm-gw6uyq,related,"2026-07-25T12:34:57.387Z",null,null
pm-j82fd3,related,"2026-07-25T12:34:57.387Z",null,null
pm-szv11n,related,"2026-07-25T12:34:57.387Z",null,null
body: ""
comments[4]{created_at,author,text}:
"2026-07-25T18:18:16.583Z","harness:codex","Implementation start: active in the cohesive automatic identity platform PR spanning the identity ADR, structured SDK provenance, precedence-safe observation, declarative harness registry, MCP/plugin configuration, and token-minimal help guidance. Duplicate check covered all 2,028 tracker items and live GitHub reports; no new item created."
"2026-07-25T19:14:50.527Z","harness:codex","Implementation evidence: accepted agent identity ADR is now embodied in shared SDK/runtime contracts. History records author_source independently from observed agent_harness, agent_model, agent_model_source, and local-only transient_session_signal. Telemetry emits only presence at minimal capture and installation-keyed harness/model hashes plus fixed model-source enums at redacted/max; session is never emitted. Verification: 6,376 tests passed with 100/100/100/100 coverage, strict 100% docstring/static/API/token gates passed, secret scan clean, packed isolated acceptance passed."
"2026-07-25T19:51:54.821Z","harness:codex","Review amendment: session identifiers are transient host context only and are no longer serialized to durable history or telemetry. Exact branch-local history streams were scrubbed of the mistakenly persisted top-level field. Additional review hardening covers bounded settings validation, executable-basename argv matching, inherited environment values, cached descriptor normalization, deterministic telemetry tests, and failure-safe registration cleanup."
"2026-07-25T20:06:38.334Z","harness:codex","Final evidence: PR #713 exact head 446d00ae passed all 6,376 tests and 100/100/100/100 coverage (44,010 statements, 31,205 branches, 8,996 functions, 42,752 lines); strict 100% docstring/static/token/API gates; packed unrelated-directory SDK and CLI acceptance; CodeQL, DeepScan with zero findings, Semgrep, Trivy, TruffleHog, CodeFactor, Hound, Windows, compatibility, smokes, and benchmarks. All 13 CodeRabbit findings were individually fixed/dispositioned/reacted and every thread is resolved. Follow-up CodeRabbit and Greptile requests reached external free-review limits after the complete first review."
files[4]{path,scope,note}:
src/core/history/history.ts,project,local provenance fields
src/core/shared/author.ts,project,decision implementation
src/core/telemetry/runtime.ts,project,privacy-safe telemetry contract
src/types.ts,project,accepted optional history shape
tests[4]{command,scope,timeout_seconds}:
node scripts/run-tests.mjs coverage,project,1200
node scripts/run-tests.mjs test,project,1200
node scripts/run-tests.mjs test -- tests/unit/sdk/agent-runtime-primitives.spec.ts tests/unit/core/telemetry/telemetry-runtime.spec.ts,project,240
"pnpm quality:static",project,1200
docs[2]{path,scope,note}:
docs/AGENT_RUNTIME_PRIMITIVES.md,project,identity ADR and privacy semantics
docs/SDK_CUSTOMIZATION_PRIMITIVES.md,project,explicit override semantics
close_reason: "Implemented and verified in PR #713 with complete local, packed-consumer, hosted-gate, and review evidence."
body: "## Decision\n\nAccepted: keep `author` as the stable effective principal and record durable runtime observation separately as optional `agent_harness`, `agent_model`, and `agent_model_source` history fields. Widening author to `harness:<harness>/<model>` is rejected because it breaks existing equality filters, increases cardinality, and conflates stable selection with volatile observation. Signed principals remain deferred to pm-u14c.\n\nSession identifiers are accepted only as transient host input to `DetectedAgentIdentity`. They are deliberately excluded from `HistoryEntry`, item metadata, logs, and telemetry because a durable or exported session identifier creates correlation and privacy risk without improving stable project context.\n\n## Contract\n\n- `agent_harness?: string`: normalized low-cardinality harness namespace. Missing means no bounded signal matched.\n- `agent_model?: string`: bounded model identifier exactly observed from an allowed signal. Missing means unknown and never changes the effective author to `unknown`.\n- `agent_model_source?: override | environment | mcp_client | argv`: fixed-cardinality provenance for the model value. It is absent whenever `agent_model` is absent.\n- `session?: string` on transient detection results only: bounded invocation identifier available to the current embedding host and never serialized.\n\nAuthor precedence remains explicit argument, `PM_AUTHOR`, configured default, detected harness, then `unknown`. Detection always executes independently, so asserted or configured authors may still carry observed durable agent fields. These observations are unverified claims: they are attribution/context only and MUST NOT authorize access, ownership takeover, or privileged operations.\n\n## Privacy and compatibility\n\nTelemetry may emit only presence booleans at minimal capture, or installation-keyed one-way hashes of harness/model plus the fixed model-source enum at redacted/max capture. Session identifiers must never enter durable history or leave the process. Legacy entries without the optional durable fields remain valid and replay/verifiability semantics are unchanged.\n\nThis amendment was made during PR review before merge. The exact affected branch-local history streams were mechanically scrubbed of the mistakenly serialized transient field; PM replay and history-drift validation must remain green. Any future author-string incorporation, durable-field rename, cardinality expansion, session persistence/export, or authorization use requires an explicit superseding or amending Decision item linked to this ADR."
38 changes: 34 additions & 4 deletions .agents/pm/features/pm-03pq3o.toon
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ id: pm-03pq3o
title: "Model-aware agent identity: detection resolves harness, model, and session so an agent never types an identity flag and history still records which model acted"
description: "Today src/core/shared/author.ts:detectHarnessIdentity returns only a harness slug from bounded env and argv signals, and resolveAuthorIdentity stamps author 'harness:<slug>'. The model is never captured on any path. The consequence is that the entire fleet collapses into seven author values, and history cannot answer which model wrote a decision, produced a defect, or held a claim. This item extends the resolved identity to a structured value — harness, model, model_source, session — resolved by the same pure, bounded, non-blocking detector, and threads it into the history entry as first-class provenance beside the existing author_source discriminator. Signal sources, in precedence order: an explicit PM_AGENT_MODEL override; harness-specific environment (for example ANTHROPIC_MODEL, AIDER_MODEL, CODEX_MODEL, OPENCODE_MODEL, PI_MODEL); MCP initialize clientInfo name and version for MCP-hosted callers, which is the only reliable channel when the harness runs pm out-of-process; and a bounded argv scan. Absence must be silent: an undetectable model yields provenance without a model field and must never degrade the author to unknown. Detection stays pure and bounded per the pm-z9x1r2 contract — no process traversal, no subprocess, no network — so the mutation hot path keeps its startup budget."
type: Feature
status: open
status: closed
priority: 1
tags[7]: agent-ux,"area:cli","area:mcp","area:sdk",author,identity,provenance
created_at: "2026-07-25T12:25:00.960Z"
updated_at: "2026-07-25T12:41:50.313Z"
updated_at: "2026-07-25T20:06:44.528Z"
closed_at: "2026-07-25T20:06:43.416Z"
author: "harness:claude-code"
estimated_minutes: 480
acceptance_criteria: "The public SDK resolver returns a structured identity carrying harness, model, model_source, and session alongside the existing author and source, and the CLI and MCP hosts both consume it; A mutation run under a supported harness with no PM_AUTHOR, no --author, and no author_default records the detected harness AND the detected model in its history entry; An undetectable model records provenance without a model field and never degrades the author to unknown, proven by an explicit negative test; Detection remains a pure function of caller-supplied bounded signals with no process traversal, subprocess launch, or network access, and the mutation-path latency budget is asserted in CI; MCP-hosted invocations resolve identity from the initialize clientInfo handshake when environment markers are absent; The provenance fields match the shape decided in the identity ADR exactly, and a contract test fails if the SDK emits a field the ADR does not define; Telemetry receives only the hashed identity dimensions the ADR permits, asserted by a test that inspects the exported event payload"
Expand All @@ -19,11 +20,13 @@ why_now: The harness half shipped and closed on 2026-07-25; capturing the model
parent: pm-mpbb
risk: medium
confidence: 70
dependencies[15]{id,kind,created_at,author,source_kind}:
resolution: "Delivered public structured agent identity types, pure detection, invocation/workspace scoping, MCP client provenance, and supported SDK exports."
expected_result: Packages and embedding hosts can customize automatic harness/model provenance without PM_AUTHOR or private runtime probing.
actual_result: Packed unrelated-directory consumer proved custom SDK descriptors and installed CLI automatic provenance; session data is absent from durable history.
dependencies[14]{id,kind,created_at,author,source_kind}:
pm-3oqjnc,related,"2026-07-25T12:25:00.960Z",null,null
pm-42p9nk,related,"2026-07-25T12:25:00.960Z",null,null
pm-j82fd3,related,"2026-07-25T12:25:00.960Z",null,null
pm-qwuber,blocked_by,"2026-07-25T12:25:00.960Z",null,null
pm-u14c,related,"2026-07-25T12:25:00.960Z",null,null
pm-w7ccmv,related,"2026-07-25T12:25:00.960Z",null,null
pm-z9x1r2,related,"2026-07-25T12:25:00.960Z",null,null
Expand All @@ -35,6 +38,33 @@ dependencies[15]{id,kind,created_at,author,source_kind}:
pm-sx52hr,related,"2026-07-25T12:34:58.859Z",null,null
pm-szv11n,related,"2026-07-25T12:34:58.859Z",null,null
pm-zqsrt5,related,"2026-07-25T12:34:58.859Z",null,null
comments[6]{created_at,author,text}:
"2026-07-25T18:18:19.318Z","harness:codex","Implementation start: active in the cohesive automatic identity platform PR spanning the identity ADR, structured SDK provenance, precedence-safe observation, declarative harness registry, MCP/plugin configuration, and token-minimal help guidance. Duplicate check covered all 2,028 tracker items and live GitHub reports; no new item created."
"2026-07-25T19:14:51.252Z","harness:codex","Implementation evidence: SDK now exports structured agent/model provenance types, pure detection, invocation signal scoping, workspace descriptor scoping, history provenance lookup, and collision-safe package registration. MCP initialization contributes bounded client name/version/model/session signals. Packed isolated consumer proved the public SDK configures a custom harness and the installed CLI persists model provenance without PM_AUTHOR. Full 6,376-test suite and exact 100/100/100/100 coverage passed."
"2026-07-25T19:26:50.893Z","harness:codex","Release-gate evidence: repository-owned release pipeline passed type tests, docs/skills, strict static/docstring/token/API gates, exact 100% coverage, version policy, version sync, secret scan, packed npx smoke, and 88-command package-first dogfood. The only pre-push failure is hosted-analysis-gate because DeepScan cannot have an exact-commit status for the current uncommitted main-derived SHA; this gate will be rerun against the pushed PR head."
"2026-07-25T19:36:56.149Z","harness:codex","CI round 1 triage: static failed only because the generated full CLI/MCP contract fixture had not been refreshed; updated it with package-owned pnpm contracts:update and contracts:check now passes. Coverage shard 2 and Windows regression shared one platform-sensitive telemetry assertion: hosted runners expose CI as a built-in harness, so a model-only test now snapshots, clears, and restores every built-in environment/model/session signal instead of assuming a Codex-only environment. CI=1 focused telemetry (44/44), exact shard 2, contracts check, and strict static gates all pass locally."
"2026-07-25T19:51:56.473Z","harness:codex","Review amendment: session identifiers are transient host context only and are no longer serialized to durable history or telemetry. Exact branch-local history streams were scrubbed of the mistakenly persisted top-level field. Additional review hardening covers bounded settings validation, executable-basename argv matching, inherited environment values, cached descriptor normalization, deterministic telemetry tests, and failure-safe registration cleanup."
"2026-07-25T20:06:41.844Z","harness:codex","Final evidence: PR #713 exact head 446d00ae passed all 6,376 tests and 100/100/100/100 coverage (44,010 statements, 31,205 branches, 8,996 functions, 42,752 lines); strict 100% docstring/static/token/API gates; packed unrelated-directory SDK and CLI acceptance; CodeQL, DeepScan with zero findings, Semgrep, Trivy, TruffleHog, CodeFactor, Hound, Windows, compatibility, smokes, and benchmarks. All 13 CodeRabbit findings were individually fixed/dispositioned/reacted and every thread is resolved. Follow-up CodeRabbit and Greptile requests reached external free-review limits after the complete first review."
learnings[1]{created_at,author,text}:
"2026-07-25T12:41:50.313Z","harness:claude-code","Treating an observation as a fallback is a design error that keeps recurring in identity code. resolveAuthorIdentity returns early as soon as a higher-precedence branch supplies an author, so detected harness — and soon the detected model — is computed only when nothing else answered. Precedence over WHICH value is authoritative is a separate question from whether an observation is worth recording: the assertion decides the author, the observation decides the provenance, and both belong in the entry. The general rule for any future precedence chain in this codebase: resolve the authoritative value by precedence, but record every cheap observation unconditionally, and keep a discriminator saying which is which."
files[10]{path,scope,note}:
src/core/history/history.ts,project,history provenance persistence
src/core/shared/author.ts,project,structured detector and registry
src/core/telemetry/runtime.ts,project,hashed harness and model telemetry dimensions
src/mcp/server.ts,project,MCP client model provenance
src/sdk/core.ts,project,supported SDK exports
src/sdk/index.ts,project,main SDK exports
src/sdk/runtime-primitives.ts,project,host runtime exports
src/types.ts,project,public history and settings contracts
tests/fixtures/contracts/full.json,project,Generated CLI/MCP contract snapshot for automatic author guidance
tests/fixtures/sdk/public-surface.json,project,Generated public SDK surface contract for identity exports
tests[4]{command,scope,timeout_seconds}:
node scripts/run-tests.mjs coverage,project,1200
node scripts/run-tests.mjs test,project,1200
node scripts/run-tests.mjs test -- tests/unit/sdk/agent-runtime-primitives.spec.ts,project,240
"pnpm quality:static",project,1200
docs[2]{path,scope,note}:
docs/AGENT_RUNTIME_PRIMITIVES.md,project,structured SDK usage and field semantics
docs/SDK_CUSTOMIZATION_PRIMITIVES.md,project,automatic attribution usage
close_reason: "Implemented and verified in PR #713 with complete local, packed-consumer, hosted-gate, and review evidence."
body: ""
Loading