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
79 changes: 79 additions & 0 deletions docs/adr/0163-persistent-specialist-task-brief.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# ADR 0163: Persistent Specialist task constraints and pinned attempt briefs

Status: proposed

Date: 2026-10-01

## Context

A consumed parent instruction disappears from the no-tool Specialist's actual
request after the recent-history window. Child-owned WorkItem descriptions and
acceptance criteria can also be truncated or omitted. Durable source records do
not themselves prove delivery. Mutable WorkItems and an empty prepared inbox
currently allow the same attempt to observe different task state after recovery.

## Decision

Reuse immutable parent messages and current child-owned WorkItems as task truth.
Schema 175 stores one bounded `specialist_task_brief.v1` snapshot per attempt,
including complete active instructions and unfinished WorkItems, ordered source
IDs, protocol/sequence or item versions, and SHA-256 bindings. Its effective
fingerprint excludes attempt and lease identity. Preparation is the cutoff:
same-attempt reads recover this snapshot, including an empty snapshot; later
source changes enter a fresh attempt. Current direct-parent, child, Run and active
lease checks still control preparation and dispatch.

Keep `specialist_instruction.v1` as the existing additive writer. A separate
strict `specialist_instruction.v2` adds explicit append, replace and withdraw
operations. Replace/withdraw bind an earlier active message ID and its exact
stored payload hash in the same child/root/Run scope. Prose never implies a
withdrawal. Consumed instructions remain effective; explicit retirement records
remain retained so replay cannot resurrect old constraints.

Complete task constraints and WorkItems are mandatory before optional Notes.
Existing history bounds and model-window fitting stay bounded. Old child-context
user envelopes are excluded from historical replay so retired constraints are
not delivered again. Verify the complete current input after final fitting and
in repair/transport retries. A content fingerprint in `model.started` binds the
current attempt snapshot; it carries no new authority. Pending inbox deliveries
still consume exactly once only with the existing continue/finish transaction.
Repeated active constraints do not create new consumption of their old message.

Request construction and completion checks share deterministic redacted task
projections. Source hashes and the snapshot fingerprint continue to bind original
stored task truth. Delivery JSON escapes assignment separators inside string
values so existing completion and Session text redaction cannot consume escaped
whitespace or following required text; decoded JSON meaning stays the same.
Dispatch refuses an encoding that is not stable under those redaction boundaries.

Bounds are explicit: 256 instruction source operations, 32 active instructions,
20 active child WorkItems and 128 KiB snapshot JSON. Existing 4,096-token context,
28 KiB selected-source and 32 KiB final-input limits remain dispatch fences. Count,
size, identity or fingerprint failure stops the attempt before model dispatch;
the original records are retained. No model summary, paid call, tool loop,
credential, network, approval or execution grant is added.

## Compatibility, recovery and rollback

Migration 175 is forward-only. Historical migration checksums and the v1
delegation-application writer/binding remain unchanged; only the current delivery
guards gain v2 support. New snapshots and eligible source payloads are immutable;
source deletion is blocked while their Run exists. Whole-Run cascade semantics
are retained. A new attempt rebuilds task truth under its own lease and receives
its own snapshot and dispatch receipts. Old delivery receipts or leases never
authorize it. A lost pre-upgrade running attempt is terminalized by existing
lease recovery and rebuilt; migration does not invent delivery evidence.

Older binaries reject schema 175. Roll back writers only with the new readers and
guards retained, or restore a pre-upgrade backup; never remove migration history
or reinterpret v2 records as v1. Original Session history and task records remain
available for audit; no automatic summary alters them.

## Validation

Verify actual outbound requests independently of model replies: history count
and byte pressure, full WorkItem text, Notes competition, final-window fit and
refusal, explicit correction/retirement, two-child isolation, reopen and pinned
empty recovery, crash/fresh leases, idempotent consumption, immutable sources,
transaction rollback, v174 upgrade and v1 compatibility. Independent parent
review and exact-HEAD CI remain required before any merge.
2 changes: 2 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ Schema v26 establishes the first child Provider boundary. `SpecialistRunner` is

Schema v27 establishes the parent-to-child context boundary. Only a strict `specialist_instruction.v1` message routed from the direct root parent to the child can enter `specialist_context_deliveries`; SQLite also verifies the active AgentAttempt, Run lease generation, payload shape, and pending status. Up to four sequence-ordered messages are prepared. `continue` and `finish` commit deliveries and consume messages in their existing lifecycle transaction, while crash, interruption, and lease takeover supersede deliveries after terminalizing the Attempt so the messages remain pending for a fresh attempt. Prepared metadata participates in graph snapshots and restore validation. The child context builder adds active WorkItems owned by the child and active `run`/`owner` Notes owned by and visible to that child under a 4,096-token estimate and 32 KiB input cap. Mandatory mission and parent instructions must fit; lower-priority memory is deterministically omitted. Message IDs stay out of the model input, while content-free source IDs and token estimates enter `model.started` provenance.

Schema v175 adds the persistent Specialist task brief ([ADR 0163](adr/0163-persistent-specialist-task-brief.md)). Consumed direct-parent instructions remain current task constraints until a strict `specialist_instruction.v2` replacement or withdrawal retires an exact earlier source/hash. The v1 additive writer and delegation-application binding remain readable and unchanged. One immutable `specialist_task_brief.v1` snapshot pins complete effective instructions, unfinished child-owned WorkItems and their source/version/hash manifest to the current attempt, including empty preparations. A fresh attempt refreshes current task truth under its own lease; re-preparing the same attempt recovers its snapshot. Required task text precedes optional Notes and survives recent-history and final-window fitting, or dispatch stops explicitly. Old child-context user envelopes do not replay retired task text. Source fingerprints enter attempt-bound `model.started` receipts; successful input must match the prepared task content. Existing exactly-once inbox consumption, authority and no-tool constraints remain intact. No automatic summarization or new tool loop is introduced.

Schema v28 establishes the child lifecycle-repair boundary. `specialist_model_calls` now carries a durable global model sequence, a phase-local transport sequence, and a bounded `protocol_repair` phase. A usage-bearing invalid primary response atomically records its generic diagnostic, cumulative Attempt/Agent usage, one pending `specialist_protocol_repairs` row, and a metadata-only repair-request event. The one repair request reuses trusted context but never includes the invalid response; its transport retry counter restarts at one. Success resolves the repair and may enter the child Session, a second invalid response exhausts it, and cancellation, budget exhaustion, interruption, crash, or stale-worker takeover aborts a pending repair before the Attempt becomes terminal. SQLite triggers reject skipped phase calls, uncharged repair requests, invalid resolution, terminal mutation, and `continue`/`finish` while repair is unresolved. The Runner rechecks Run-wide total-token and execution-time remainder before dispatch and gives repair only the post-primary remainder.

The internal `SpecialistScheduler` lifts lease ownership above an individual child turn. One schedule holds one Run execution lease and starts at most two ready direct children per round. A shared cancellable context fans parent cancellation, heartbeat loss, or the first child failure out to every active sibling; the scheduler waits for each child to persist its Attempt terminal state before returning and releasing the lease. It stops on all-terminal, no-ready, round-limit, cancellation, child-error, aggregate-token, or aggregate-execution conditions. Aggregate usage is rebuilt transactionally from the root Supervisor checkpoint, Specialist Agent/Attempt token projections, and every Specialist model-call duration before and after each round. Remaining total-token and execution allowance is split deterministically by sorted Agent ID.
Expand Down
11 changes: 6 additions & 5 deletions docs/convergence/protocol-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ This document is generated from [`protocols/registry.json`](../../protocols/regi
| [browser-ui-evidence-ledgers](#browser-ui-evidence-ledgers) | `internal-durable` | Browser and UI evidence maintainers | 44 | true |
| [capability-readiness-projection](#capability-readiness-projection) | `projection` | Application readiness maintainers | 4 | true |
| [cli-headless-contract](#cli-headless-contract) | `external-durable` | CLI and headless surface maintainers | 2 | true |
| [control-plane-ledgers](#control-plane-ledgers) | `internal-durable` | Core Go control-plane maintainers | 110 | true |
| [control-plane-ledgers](#control-plane-ledgers) | `internal-durable` | Core Go control-plane maintainers | 111 | true |
| [credential-provider-ledgers](#credential-provider-ledgers) | `internal-durable` | Credential, provider, model-route, and pricing maintainers | 23 | true |
| [desktop-risk-restart-session](#desktop-risk-restart-session) | `ephemeral` | Desktop shell lifecycle maintainers | 1 | false |
| [desktop-web-presentation-state](#desktop-web-presentation-state) | `projection` | Desktop and React workbench maintainers | 15 | true |
| [docker-attach-process-session](#docker-attach-process-session) | `ephemeral` | Docker runtime transport maintainers | 1 | false |
| [exported-evidence-and-handoff](#exported-evidence-and-handoff) | `external-durable` | Evidence, verification, report, and handoff maintainers | 35 | true |
| [extension-package-contracts](#extension-package-contracts) | `external-durable` | Skill, Plugin, Hook, and extension maintainers | 40 | true |
| [extension-package-contracts](#extension-package-contracts) | `external-durable` | Skill, Plugin, Hook, and extension maintainers | 41 | true |
| [http-openapi-contract](#http-openapi-contract) | `external-durable` | HTTP/OpenAPI and generated-client maintainers | 110 | true |
| [in-memory-token-session](#in-memory-token-session) | `ephemeral` | Credential and bootstrap maintainers | 1 | false |
| [lsp-process-session](#lsp-process-session) | `ephemeral` | Code intelligence maintainers | 1 | false |
Expand Down Expand Up @@ -483,7 +483,7 @@ This document is generated from [`protocols/registry.json`](../../protocols/regi
- Readers:
- `control-plane-ledgers-reader` (`v1, v2, v3`, active) at `internal/store`

<details><summary>110 active identifiers</summary>
<details><summary>111 active identifiers</summary>

- `byte_identical.v1`
- `data_store_scope.v1`
Expand Down Expand Up @@ -542,6 +542,7 @@ This document is generated from [`protocols/registry.json`](../../protocols/regi
- `specialist_operator_schedule_request.v1`
- `specialist_skill_assignment.v1`
- `specialist_skill_context.v1`
- `specialist_task_brief.v1`
- `standard-code-backend-readiness.v1`
- `standard-code-command-result.v1`
- `standard-code-command.v1`
Expand Down Expand Up @@ -785,7 +786,7 @@ This document is generated from [`protocols/registry.json`](../../protocols/regi
- Readers:
- `extension-package-contracts-reader` (`v1, v2`, active) at `internal/skills`

<details><summary>40 active identifiers</summary>
<details><summary>41 active identifiers</summary>

- `extension-control.v1`
- `extension-inventory.v1`
Expand Down Expand Up @@ -827,6 +828,7 @@ This document is generated from [`protocols/registry.json`](../../protocols/regi
- `skill_selection_operation.v1`
- `skill_selection_request.v1`
- `specialist_instruction.v1`
- `specialist_instruction.v2`

</details>

Expand Down Expand Up @@ -1827,7 +1829,6 @@ These identifiers remain inside the scan. Each exemption is bound to exact files
| `skill.v2` | `test-fixture` | `internal/skills/manifest_test.go` | Test-only or golden/negative-vector identifier; exact source binding prevents production classification. |
| `slsa_provenance.v1` | `test-fixture` | `internal/analyzer/provenance_verification_test.go`, `internal/analyzer/release_manifest_test.go` | Test-only or golden/negative-vector identifier; exact source binding prevents production classification. |
| `specialist_delegation.v2` | `test-fixture` | `internal/domain/specialist_delegation_test.go`, `internal/toolgateway/specialist_delegation_test.go` | Test-only or golden/negative-vector identifier; exact source binding prevents production classification. |
| `specialist_instruction.v2` | `test-fixture` | `internal/domain/agent_context_test.go` | Test-only or golden/negative-vector identifier; exact source binding prevents production classification. |
| `standard_code_fixture_manifest.v1` | `test-fixture` | `internal/packagede2e/manifest.go`, `internal/packagede2e/testdata/fixture-manifest.json` | Packaged E2E fixed-repository fixture manifest. |
| `standard_code_fixture_set.v1` | `test-fixture` | `internal/packagede2e/manifest.go`, `scripts/standard-code-packaged-e2e.ps1` | Packaged E2E fixed-repository fixture set. |
| `standard_code_packaged_e2e.v1` | `test-fixture` | `internal/packagede2e/manifest.go`, `scripts/standard-code-packaged-e2e.ps1` | Packaged E2E harness report, not a shipped product protocol. |
Expand Down
1 change: 1 addition & 0 deletions docs/development-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,5 +243,6 @@ The complete slice ledger remains in [PROGRESS_BOOK](PROGRESS_BOOK.md), current
| v172 | 原子转换排队文字为当前引导,持久保存原消息、替代消息和执行身份的不可变关联收据 | atomically promote queued text to steering with immutable source, replacement and execution identity receipts |
| v173 | 将只读内置技能发现与读取纳入已有 Supervisor 账本,保留旧行身份与权限约束,并从成功收据重建精确版本指导 | admit read-only built-in skill discovery and reads to the existing Supervisor ledger, preserve row identities and authority guards, and reconstruct exact-version guidance from successful receipts |
| v174 | 在原协议失败事务中原子保存有界脱敏的原生工具请求拒绝诊断,保持原 attempt 身份,不生成可执行调用、Provider 回放或历史回填 | atomically preserve bounded redacted rejected native request diagnostics in the original protocol-failure transaction, retaining attempt identity without executable calls, Provider replay or historical backfill |
| v175 | 为 Specialist 固定有界的 attempt 任务快照与原始来源绑定,保留完整有效委托和工作项,并支持精确替代或撤回;投递与消费仍绑定当前 attempt | pin bounded per-attempt Specialist task briefs and original source bindings, retain complete effective instructions and owned work, and support exact replacement or withdrawal while delivery and consumption stay attempt-bound |

</details>
Loading
Loading