Why: The sandbox hides the host home directory and has no network, so pip install --user cannot supply python-docx, and the service PATH resolved python3 to a linuxbrew path that does not exist inside the sandbox.
Evidence: SELF go test of execenv, tools, store, app, server, runmgr, config, and cmd/agent-system on this worktree. CI has not run.
Impact: Sessions inherit a read-only base layer. Extra packages are requested through python_env, auto-approved only from the allowlist, and mounted per conversation. Schema 35 adds the request and binding tables.
Refs: .task/feature-layered-python-env.md
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: The active secret_keys row overrides settings plaintext, so a replaced chat key kept returning 401. Migration also mutated the settings map in place, so clearing a matching plaintext never reached the database.
Evidence: go test ./internal/settings/ ./internal/runtime/ -count=1 (SELF, worktree).
Impact: System settings writes adopt a changed secret; conflicting plaintext is kept and logged; 401 errors name the key layer and an 8-hex fingerprint.
Refs: fix/model-key-secret-overlay
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Account disable could be followed by late Backend business writes, API key creation could implicitly create users, account bootstrap locks could invert, and directory cursors were process-local or leaked out-of-scope changes.
Evidence: Local go test ./... and isolated PostgreSQL package suites passed on the staged candidate; exact committed-head SELF replay and stage 6 human review remain pending.
Impact: Adds final account transactions and external-effect checks across HTTP, Host, Bus and run manager; tightens API key issuance and persists versioned cursor signing. Delegated RDM rename still needs the separately proposed real-operator contract, so A1 and stage 6 are not complete.
Refs: Documents U3 r1, approved A1-A4 amendment fb3a821, pending delegated-projection amendment 5783940, Dev feature/iam-u3-account-directory-recovery.
Why: U7 account audit and identity gates advanced on main while U3 account initialization and recovery were in progress.
Evidence: SELF merge-tree checks passed with go test ./... and isolated PostgreSQL store/server tests; exact-head replay follows.
Impact: Preserve pending-account grants, proof-linked recovery, protected CLI delivery, account serialization, and atomic audit.
Refs: IAM U3 r1; U7 PR #185
Why: A disable could commit after the run manager checked account state but before its final business message was stored.
Evidence: SELF receipts /tmp/iam-u3-final-settle-sqlite.json, /tmp/iam-u3-final-settle-pg.json, /tmp/iam-u3-backend-settle-all.json, /tmp/iam-u3-backend-settle-pg.json, and /tmp/iam-u3-http-two-instance-pg.json.
Impact: The final run transaction locks and rechecks the account, rejects post-disable business output, and permits only an account-denial failure record. Auth-off implicit local ownership remains explicit.
Refs: IAM U3 r1 stages 4-5; Dev feature/iam-u3-account-directory-recovery
Why: Administrator-issued password and login-key paths could take over target accounts, while old credentials and plugin handles ignored current account state.
Evidence: SELF receipts /tmp/iam-u3-backend-all-replay.json, /tmp/iam-u3-backend-final-pg-core.json, /tmp/iam-u3-backend-build.json, and focused HTTP/concurrency receipts in /tmp/iam-u3-*.json.
Impact: Adds trusted pending-account initialization and reissue, preexisting owner-session proof, proposal/rotation/grant transactions, server-side admin search, current Host guards, and legacy HTTP/CLI closure. Production cutover and downstream pins remain pending.
Refs: IAM U3 r1 stages 4-5; Dev feature/iam-u3-account-directory-recovery
Why: Concurrent password changes, recovery key reissue, and session admission could accept retired credentials or omit rejected audits.
Evidence: Local Go vet and full tests passed; real PostgreSQL store suite, deterministic interleavings, and two-process contention passed with SELF receipts.
Impact: Account writes and session admission serialize per owner; stale sessions fail closed; checked rejections carry an audit row.
Refs: Agent-System-Dev #486; Agent-System-Backend #185; merge queue Issue #518
Why: Deliver U7 account transactions and audit without losing main auth_version, restricted-session, project or migration behavior.
Evidence: SELF go vet and all Go tests passed; isolated PostgreSQL store tests, 20 repeated two-process admission rounds, and real SIGTERM/SIGKILL persistence passed. Original failures remain in receipts; exact-head CI and independent Review follow.
Impact: Adds schema v31, noncreating account CLI opens, preflight credential output, same-transaction audit, and bootstrap admission guards. No live database touched.
Refs: Backend PR #185; Dev PR #486; original U7 r2 account specification; 2026-10-14 Root takeover
Why: The old account lister exposed a global, always-valid directory without a domain locator or field authorization.
Evidence: SELF receipts /tmp/iam-u3-u3-backend-sqlite.json and /tmp/iam-u3-u3-backend-pg.json.
Impact: Adds versioned optional query and exact lookup, trusted RDM scope registration, visible-field cursor binding, and restricts legacy EXT-19 to effective system administrators. RDM consumption remains a separate U3-5 unit.
Refs: IAM U3 r1 stages 4-5; Dev feature/iam-u3-account-directory-recovery
Why: Disabling an account must stop in-flight work as well as new HTTP requests.
Evidence: SELF receipts /tmp/iam-u3-u2-runtime-regression.json and /tmp/iam-u3-u2-app-compile.json.
Impact: Run start, tools, HITL, streaming output, child runs and final settlement recheck the account independently of project authorization.
Refs: IAM U3 r1 stages 4-5; Dev feature/iam-u3-account-directory-recovery
Why:
Legacy project streams replayed upload filenames and parser metadata to newly
authorized members even though the underlying cards remained owner-only.
Evidence:
SELF real HTTP red regressions exposed legacy replay, spoofed sharing claims,
private-history pagination, and live delivery after membership removal. The
affected packages, uncached full Backend suite, isolated PostgreSQL Store suite,
and agent-system build pass after applying the event boundary.
Impact:
Registered lifecycle streams resolve trusted resource ownership and require an
internal publication proof for cross-owner delivery. Event and proof commit in
one transaction; v30 adds an additive SQLite/PostgreSQL sidecar without granting
access to historical events. Seen and visible cursors remain separate, revoked
members leave live streams, and unregistered base behavior remains compatible.
The storage migration tool preserves the new proof rows.
Refs:
project-member-access-implementation-plan.md Task 1 / R5; authorized legacy SSE
privacy follow-up; project-member-composed-legacy-project-history.json
Why:
Shared project reads previously doubled as write permission, project mutations
bypassed the domain lifecycle, and coarse retrieval shared private resources.
Evidence:
SELF red-before-implementation logs cover projection, lifecycle, private work,
resource filtering, canonical retrieval scope, publication source and namespace.
SELF go test ./..., isolated PostgreSQL go test ./internal/store -count=1,
and CGO_ENABLED=0 go build ./cmd/agent-system passed; task owner owns replay/CI.
Impact:
Add optional actor-scoped projection/lifecycle capabilities; registered providers
control public lifecycle and live work. Preserve owned conversation history and
ordinary unregistered behavior. Authorize knowledge by stored ID/source, map
current host scopes through trusted service metadata, and filter artifact lists.
Refs:
Dev project-member-access implementation plan r1 Task 1; approved design r0.1;
2026-10-13 trusted publication Source hardening ruling
Why: The login recovery contract leftovers and KTD12/KTD14 require:
concurrent same-name account creation must not overwrite the winner,
first-admin bootstrap must serialize across processes, the redeem
endpoint backoff must be shared across instances, revoked API keys
must close established SSE streams, and CLI credentials need an
env-DSN path plus a non-interactive 0600 file delivery mode.
Evidence: go test ./... green; new tests cover 16-way concurrent
create (1 win/15 conflict, winner credentials intact), 8-way
concurrent bootstrap (single admin, refuse takeover after), redeem
guard shared across two store handles on one DB, SSE stream closed
after key revocation within the recheck window, and HTTP 429 after
the failure cap (SELF worktree run; CI is the GATE, PG via test-pg).
Impact: Migration v29 (redeem_attempts); CreateAccount becomes a
single-row INSERT with unique-violation conflict; BootstrapFirstAdmin
advisory-locks (PG) / rechecks (SQLite) and commits admin+key+audit in
one transaction; SSE revalidation covers API-key streams; redeem
backoff moves to the shared DB; CLI gains AGENT_SYSTEM_DSN fallback
and --out file delivery for create/reset-password/issue-login-key/
bootstrap-admin.
Refs: docs/svc-deploy/2026-10-13-login-recovery-contract.md leftovers;
proposal r2 KTD12/KTD14/R5/R11.
Why: Since the system-managed settings change (#188), runtime.* writes
at the user scope are rejected, so the mock startup flag failed with
"system-managed settings require admin" and the serve process never
became healthy - the Dev multi-instance integration regression.
Evidence: go build ok; internal/app and internal/settings suites green
(SELF); the Dev composite CI on the follow-up PR re-runs
make test-multi-instance against this fix (GATE).
Impact: The mock startup flag now seeds runtime.mock via MergeSystem
(trusted operator input, effective for every tenant through the
Effective merge chain); no HTTP surface changes.
Refs: Dev PR #508; backend #188.
Why: The login recovery contract (2026-10-13) requires admin-issued
one-time keys, in-transaction revalidation of restricted sessions, a
login race guard, and audited password writes; the previous
implementation validated sessions outside the change-password
transaction and let stale password verifications create sessions.
Evidence: go test ./... green (SQLite); store tests switch to
openTestStore so the CI test-pg job covers real PostgreSQL, including
100-way concurrent redeem single-winner and auth-version race cases
(SELF, local run).
Impact: New migration v28 (users/sessions.auth_version,
account_events). New admin endpoints POST/GET
/api/admin/users/{owner}/login-keys and DELETE
.../login-keys/{id}. Login binds session creation to the verified
auth version and creates restricted sessions for must-change accounts;
redeem gains per-IP backoff; cookies gain Secure under TLS; active
change-password and admin/CLI resets become single transactions that
bump auth_version, revoke keys and sessions, and write audit events.
Refs: modules/documents/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md r2; Dev task feature/svc-login-recovery-flow
Why: identity open and the unknown-subcommand check landed on main, and this branch still has to refuse account migration while advertising capabilities.
Evidence: go test ./internal/store ./internal/app ./cmd/agent-system ./pkg/identity passed after the merge.
Impact: identity verify uses the no-migrate opener and returns the schema version. Account open still does not migrate. v28 is registered as readable by older artifacts.
Refs: cmd/agent-system/main.go, internal/app/app.go, internal/store/store.go, internal/store/migrate_compat.go
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: creating an account and its activation key, and changing a password, were separate commits, so a crash could leave a user without a key or a new password with a still-valid login key.
Evidence: SELF go test ./internal/store including TestConcurrentCreateOneWinner, TestPasswordChangeIsAtomic, TestOpenExistingDoesNotMigrateOrCreate, and TestBootstrapRefusesExistingBusiness. PostgreSQL cases are NOT_RUN locally.
Impact: strict insert returns ErrConflict instead of overwriting. Account CLI opens an existing database without migrating. --dsn and --password still work and warn. capabilities --json does not touch the database.
Refs: docs/svc-deploy/u7-account-tx-audit.md
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: identity ensure/verify went through the normal store open, which
creates a database and runs migrations. A deploy gate that calls the
candidate before stopping the old service could migrate production
ahead of the switch, and a missing database was turned into an empty one.
Evidence: go test ./pkg/identity/ ./internal/store/ ./cmd/agent-system/ -run 'TestCapabilities|TestEnsure|TestVerify|TestDSN|TestUsage|TestSystemIdentity|TestOpenIdentity|TestUnknownSubcommand' passed in this worktree.
Impact: identity CLI refuses a missing file or a missing agent_system_identity table, does not migrate, reads DSN from the environment or a 0600 file, and version --json plus identity capabilities emit one capability document. Unknown top-level commands exit 2.
Refs: recovery plan r3.1 D1; Dev feature/svc-d1-identity-flow
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: U1 I3 needs a DB-side instance identity anchor matching
manifest.instance_id so wrong/missing DB blocks startup (I4).
Evidence: go test ./internal/store/ ./internal/app/; CLI smoke
ensure/verify on SQLite temp dir.
Impact: migration v26; store Ensure/Verify; identity subcommand;
serve checks AGENT_SYSTEM_INSTANCE_ID when set.
Refs: docs/recovery/u1-identity-manifest.md §5.2; Dev feature/recovery-u1-db-identity
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: passwordless activation/recovery must redeem only into a
set-password session; account ops must not create empty stores.
Evidence: SELF go test store/server login-key and OpenExisting cases.
Impact: auth middleware gates; CLI user create defaults to activate key.
Refs: docs/svc-deploy/u4-one-time-login-key.md
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: compiled-in plugins (generative-ui, rdm) never appeared in the admin
plugins list: GET /api/plugins only scanned the directory host, so binary-
level capabilities were invisible to operators (user-reported gap).
Evidence: go test ./internal/app/ ./internal/server/ green locally incl.
new TestApplyCompiledRecordsSummary and TestListPluginsMergesCompiled;
CI (make test) is authoritative.
Impact: applyCompiled records each plugin's registered commands/intents/
skills into a summary handed to the server; /api/plugins merges synthesized
inproc entries (backend.mode=inproc, apiVersion=extension surface version,
provides from the registration record). Directory entries win on id
collision. No public extension-surface change.
Refs: WP3-I4; task card feature-plugins-compiled-listing.
Why: plan U5 remainder (KTD5/KTD9 + exit criteria) - commands must commit atomically with business writes, artifacts need a shared object store for multi-instance, and the two-real-process acceptance matrix must run in CI.
Evidence: full suite green on SQLite and real PostgreSQL 18.6 (35 packages each tier) - outbox tx test (rollback removes the command, commit makes both visible, idempotent re-enqueue), S3 store tests (SigV4-signed round trip, 404 sentinel, idempotent delete, presigned GET, env fallback), real-process acceptance (testbinary self-spawn of two serve processes with per-process identity and command consumers against one schema: same-conversation contention, cross-instance cancel command claimed exactly once, stale-owner settle fenced with run unchanged).
Impact: EnqueueCommandInTx for in-transaction command outbox and AppendEvents now notifies in the same transaction (KTD6 front half); blobstore.S3 (SigV4, presign, prefix isolation) injected from BLOBSTORE_S3_* env when configured, local fallback otherwise; realproc_test provides the process-level multi-instance acceptance gate (PG-env gated, runs in CI test-pg job).
Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U5 KTD5/KTD9, section 5 exit criteria; R4/R7/R10.
Why: The approved U5 scope needs the action half of the loop: an
idempotent ledger (migration v24), a single-choke SubmitAction (plugin
activation, current-revision, action whitelist, params-hash
idempotency), dispatch through the command bus so DangerHigh lands on
the existing inline confirm card with no Confirmed passthrough (the
endpoint does not even bind the field), the button-only
generative-ui.submit storing form data in the plugin KV ledger, and
catalog discipline rejecting unknown action ids at present time.
Evidence: go build/vet clean; full go test ./... green; surfacesvc/
genui/store suites also green under AGENT_PG_TEST_DSN; red matrix
covers disabled/stale-revision/cross-owner/unknown-action/idempotent
same-and-different-params/danger-high-await-confirm and the endpoint
forged-confirmed case.
Impact: Additive migration v24 + new endpoint/command; existing
endpoints and command semantics untouched (B-class whitelist starts
empty per the approved scope).
Refs: U5 action-scope r2 (approved, Documents #71); UI #46/#47;
Frontend #56; Dev task feature/generative-ui-u5
Why: plan U5/KTD4+KTD5 - before a second instance may serve writes, conversation execution must have a single valid owner (DB lease, epoch increments on takeover), stale owners must not settle (in-transaction fence check), and cancel/HITL must reach the executing instance via a persistent command inbox.
Evidence: full suite green twice-relevant on SQLite and real PostgreSQL 18.6 (35 packages each tier) - lease tests (claim/contention/re-claim/renew fencing/expiry takeover/monotonic epoch, command inbox idempotent enqueue, atomic concurrent claim) and multi-instance tests (same-conversation contention rejected, stale-owner settle fenced with run unchanged, cross-instance cancel consumed exactly once by the owner instance, non-owner does not consume).
Impact: v23 migration (conversation_executions + run_commands); ClaimConversation stacks a DB lease on PG tiers (15min, release on conversation release); settle path fenced (fenced runs emit run.fenced, no terminal write); StartCommandConsumer polls the inbox for commands on locally-owned executions (cancel routes to local cascade or DB-level close-out; HITL revalidates gate and rejects expired explicitly); server cancel/HITL fall back to command enqueue with 202 when the run is not local; app wires instance identity (host:addr on PG tiers) and starts the consumer.
Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U5 KTD4/KTD5; R4/R10.
Why: Generative UI U3 - the agent needs a real submission path and the
next turn needs to see prior pages: a built-in in-process plugin
registers generative-ui.present (exposeAsTool) carrying the catalog
(prompt=validation single source) with a schema-repair strategy
measured against real MiniMax-M3 deviations; the command bus gains an
owner-scoped tool gate so a disabled plugin stops injecting its tool
(execution guard remains in surfacesvc); ctxasm projects saved surfaces
back into context so the model can revise existing structure; doc-refs
are authorized against the owner's real artifacts.
Evidence: unit suites green (genui guards/epoch/doc-ref, gate fail-closed,
projection content); full go test ./... green; cmdbus/ctxasm also green
under AGENT_PG_TEST_DSN; real-model closed loop (env-gated
TestRealModelSurfaceLoop) passes: task->spec->save->projection->revise
with revision 1->2 and structure change, CNY 0.08 total.
Impact: New internal/genui package; additive cmdbus/ctxasm/runmgr/
runtime hooks; no storage or contract changes (U2 layer untouched).
Refs: Documents proposal r2 U3; Core PR #25/#26; Backend #143; Dev task
feature/generative-ui-u3
Why: Generative UI proposal U2 needs the host side of the contract:
owner-isolated surface storage with revision CAS, an execution-level
enable/disable ledger (default-off, epoch bumped on every transition so
in-flight submits after a disable are rejected), a single-choke-point
service that validates specs (strict decode + catalog rules) before
saving, event publish with pending recovery, the optional SurfaceHost
extension capability, and direct API endpoints that share the same
guard (no bypass by entrance).
Evidence: go build/vet clean; full go test ./... passes (SQLite);
surface store tests also pass under AGENT_PG_TEST_DSN (PostgreSQL);
surface.txt regenerated via the AST snapshot test.
Impact: Additive migration v22 (new tables only); existing endpoints and
plugin_grants semantics untouched; old consumers unaffected. U3+ (data
binding, actions, frontend) deliberately out of scope.
Refs: Documents proposal 2026-10-10-generative-ui-plugin.md (r2 U2);
Core PR #25; Dev task feature/generative-ui-u2
Why: plan U3 remainder (R8/KTD13) - execution admission must be bounded and shared (leases in the database, parents yield while waiting so budgets cannot deadlock parent-child), and project authorization must distinguish read/edit/approve/execute/admin with default-deny for unconfigured actions.
Evidence: full suite green on SQLite and against real PostgreSQL 18.6 + Redis (isolated instance); new tests - admission_pg_test (enforcement, per-user, concurrent no-oversell), runmgr admission tests (saturated-budget sync spawn progresses, background children share the budget, bounded queue 429), server action-matrix tests (default deny, legacy adapter read-only, action-aware authoritative + fail-closed).
Impact: admission_leases (v21) with atomic lease accounting under an advisory lock; runtime.execBudgetGlobal/PerUser/execQueueMax settings (all zero = off, historical behavior preserved); conversation turns, background and sync subagents share the pool, parents yield around synchronous children and HITL waits; queue-full rejects 429 before writing; server gains ProjectAction matrix + SetProjectActionAuthorizer with legacy EXT-8 read fallback.
Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U3 R8/KTD13; docs/guides/team-storage.md section 9.
Why: the approved collaboration plan U2 (KTD1/KTD8/KTD12) requires an explicit fail-closed team deployment tier, DDL-and-ledger-atomic migrations serialized across migrators, and a configurable PG connection budget with sanitized effective values.
Evidence: real PostgreSQL 18.6 + pgvector + Redis 8.10.2 local gate - full backend suite green twice with AGENT_PG_TEST_DSN/AGENT_REDIS_TEST_ADDR (isolated svc.sh instance collabtest:8897, redis 6399); SQLite suite green without env.
Impact: config tier+pool keys and validation; store PoolOptions + statement_timeout DSN param + single-transaction migration with PG advisory lock and SQLite _txlock=immediate + unknown-schema-version refusal; app tier guard fail-closed (team requires DSN+auth, no SQLite fallback); CLI flags and explain rows; tests for tier/pool parsing, atomicity fault-injection, racing migrators, old-schema upgrade; fixed pre-existing real-PG test defects (blind &search_path= appends in runmgr/pgbus helpers, pg_trgm per-schema install race, exhausted seq-conflict retries).
Refs: proposals/2026-10-11-collaboration-storage-and-distribution.md U2, KTD1/KTD8/KTD12; R2/R3/R7.
Why: The sandbox tier wrote the session directory directly, so a buggy
or runaway script could leave the workspace half-mutated and nothing
bounded what a timeout had already written. The plan's first landing
shape (section 4.4) swaps the session bind for a frozen-base overlay:
each exec freezes the session dir (hardlink clone + sha256 baseline),
runs on a private upper, and only a clean exit promotes the change set
back via CAS (baseline hash match -> atomic replace/remove; externally
changed targets double-store as *.conflict-* instead of clobbering).
Timeouts and kills discard the upper entirely - half-written state
never lands.
Evidence: go test ./... green including bwrap integration roundtrips
(TestSandboxWorkspaceOverlayRoundtrip: add/modify/delete through a real
overlayfs upper with whiteout handling and ws cleanup;
TestSandboxWorkspaceOverlayTimeoutDiscards: partial writes discarded on
timeout) and unit anchors for freeze manifest (.agentx excluded), CAS
add/modify, conflict double-store, and the change summary.
Impact: Opt-in via --exec-workspace overlay / AGENT_SYSTEM_EXEC_WORKSPACE
(only with --exec-backend sandbox; fail-closed on unknown modes). The
model sees a one-line change summary appended to the tool output, so
discards and conflict files are visible. Default behavior is unchanged.
Refs: proposal 2026-10-10-agent-delegation-routing-sandbox.md section
4.4; Dev task feature/agent-s0-workspace-overlay.
Why: Real runs were fully serial: the direct path never set the kernel's
parallel tool mode, delegate_task handed the parent only the child's
160-char summary (the full text was dropped), MiniMax streamed its
reasoning inside content <think> blocks, and the EXT-16 sandbox hid
~/.local so python-docx/openpyxl/pptx could not even import. All four
were measured defects (F1/F2/F3/F5) in the delegation/routing proposal.
Why: Serial-only mutual exclusion is not enough for order-sensitive
tools - the card-stream test failed with out-of-order appends - so the
ordering moved into the kernel (SerialTools partition, Agent-Native
#44); process events pair by CallID (#42) and tool results write back
through the injected call context (#43).
Evidence: go test ./... green, including new regression anchors:
TestDelegateToolReturnsFullText, TestToolEventsPairByCallID,
TestToolExecModeAndSerialSet, TestOpenLLMClientReasoningSplitAuto,
TestSandboxArgvDepsLayer, TestExecEnvJoinsPythonPath.
Impact: Direct runs now execute independent same-turn calls
(searches, reads, delegate_task, review_findings) concurrently by
default (runtime.parallelTools=false restores sequential); card flow,
plans, workflows, exec primitives and file edits keep model-declared
order. delegate_task returns the capped full child text. MiniMax-*
models get reasoning_split=true so thinking streams via
reasoning_content. --exec-deps-dir/AGENT_SYSTEM_EXEC_DEPS_DIR mounts a
read-only dependency layer into the sandbox and merges PYTHONPATH.
Bumps deps/agent-native to c348441.
Refs: proposal 2026-10-10-agent-delegation-routing-sandbox.md (E1,
F1-F5); Agent-Native #42/#43/#44; Dev task feature/agent-e1-parallel-fixes.
Why: User rulings 4/5 plus the P2-P4 live evidence. Keyword scoring dimensions
(readability, actionability) kept failing valid documents - normal Chinese
section headings flagged as column titles, loops of 4 corrections - because
they grade writing preferences, not verifiable facts. Unverified numbers
(~10-13 per run) remained the largest quality leak through every phase.
And the verifier runs on the same model as the worker (lightweight falls back
to chat), so "independent" verification was self-review. Separately, svc
seeding after boot never registered the tavily tools until a restart because
keys were snapshotted at startup.
Changes: quality.HardFacts (lint actually ran + zero errors) replaces the
full ScoreBytes projection in CheckArtifacts - keyword dimensions remain in
ScoreBytes for eval visibility only. New fact-consistency check
(runtime.factCheck, default on): extract percentages/dates/large numbers from
deliverable text, trace each against the material corpus (attachment text +
tool evidence); misses get exactly one correction round (fix, drop, or mark
as target/estimate), never a loop. runVerifier skips same-source model
verification unless runtime.verifierSameModel is set (hard facts + fact check
still run). Search tools now register lazily, reading tavily keys per call
(settings/seeding take effect immediately).
Evidence: SELF - TestHardFactsIgnoresKeywordDimensions,
TestHardFactsKeepsLintUnavailableBlocking, TestUnverifiedFactsAndNotice,
TestFactCheckContinuationOnce (fact note fires, corrected run passes);
go vet + go test ./... pass; live before/after on the golden task set
recorded on the phase05 task card per the policy clause.
Impact: Gate stops rejecting valid documents on stylistic grounds; invented
figures get one forced correction round; same-model verification no longer
pretends to be independent; tavily config is hot. No contract or storage
changes.
Why: Q2 ruled exec tools stay disabled for now but code execution must
return later; the recovery path treats model-generated code as
untrusted. This abstracts the interpreter launch point in
exec_interpreter.go into an ExecBackend port (direct = byte-identical
status quo; sandbox = bwrap isolation) so downstream products can
re-enable execution behind isolation without further base surgery.
Evidence: go build/vet clean; go test ./... 32/32 packages green;
sandbox escape negatives all blocked locally (bwrap 0.11.1): home
secret unreadable (tmpfs /home), sibling session unreadable
(session-only bind), network blocked (--unshare-net), 400-process
spawn storm capped by ulimit -u 256 (fork: retry), 60s sleep killed at
3s timeout, orphans die with the namespace; session-dir write visible
on host; direct backend regression (exit=7 / exit=timeout texts)
unchanged.
Impact: run_shell/run_python route through the backend; workflow
ScriptCommand and the squad kernel ExecConfig stay direct (follow-up
scope); config key execBackend + env AGENT_SYSTEM_EXEC_BACKEND + CLI
--exec-backend; extension.Options.ExecBackend (SurfaceVersion
2.6.0-experimental); DisableExecTools remains the top-priority
fail-closed switch.
Refs: proposal 2026-10-09-ext-g1-b1-b3-exec-backend.md section 4
(EXT-16, G2-8 prototype); Backend #110 (DisableExecTools).
Why: the EXT-14 wiring made runmgr import cmdbus for the CommandSource
interface signatures, which adds a new edge backend/runmgr ->
backend/cmdbus outside the architecture baseline ratchet; the Dev
umbrella lint (lint-architecture) rejects the gitlink bump because of
it. The dependency direction was always meant to be inverted: runmgr
defines the port, the composition root adapts the bus.
Evidence: go build/vet clean; go test ./... 32/32 packages green;
grep confirms no internal/cmdbus import left in non-test runmgr files;
Dev-side lint re-run scheduled on the gitlink bump PR.
Impact: runmgr.CommandTool/CommandRequest/CommandResponse are local
view types; app.busAdapter now converts cmdbus types at the boundary
(Entrance still fixed to agent by runmgr). No behavior change; the
runmgr tests speak the view types instead of cmdbus ones.
Refs: Dev umbrella make test failure 'architecture: new dependency
edges backend/runmgr backend/cmdbus'; proposal 2026-10-09-ext-g1-b1-b3
(EXT-14); Backend #114.
Why: RDM's capabilities are rdm.* commands; the agent run has no bridge
to them, so the V0.1 end-to-end goal (full-conversation operation) and
the agent-driven two-trees-one-net access are unreachable (Q4 option A).
Evidence: SELF - red tests first: TestCommandToolsProjected and
TestCommandToolDispatchesThroughBus failed on undefined symbols, then
green; TestCommandToolsFiltering and TestCommandToolDispatchEnvelope
cover projection filtering (risk default low, description falls back to
title, unexposed commands absent) and the full dispatch receipt with
Entrance=agent preserved through CanonicalEntrance; go test ./... 32/32
packages ok.
Impact: agent-command pin cc1ad77 -> 5c6dd0c (library PRs #4/#5: optional
ExposeAsTool field + "agent" entrance). cmdbus gains CommandTool view and
Bus.CommandTools; runmgr gains SetCommandSource with projection into
runCtx.Tools (dedup: registry tools win) and routing in ExecuteTool -
model calls dispatch through the bus with Entrance=agent, Actor/Owner =
conversation owner, ConversationID set; high-danger commands keep the
inline-confirm-card flow via the bus; unregistered source = current
registry behavior. Composition root wires a busAdapter. No
pkg/extension change.
Refs: proposal 2026-10-09-ext-g1-b1-b3 section 2; Agent-Command #4/#5
Why: A member's agent cannot see published project knowledge inside a run
(runCtx.Retrieve and hostcaps.search are owner-only), and members can
neither see shared projects nor open conversations in them - both are P0
prerequisites for RDM G1 (EXT-13/EXT-15, proposal
2026-10-09-ext-g1-b1-b3-exec-backend).
Evidence: Red tests first - TestRunContextRetrieveShared (undefined
SetSharedKnowledgeAllow), TestInprocHostKnowledgeSearchShared (0 shared
hits), TestSharedProjectListAndConversation (empty list) all failed before
and pass after; go test ./... 32/32 packages ok.
Impact: runmgr gains SetSharedKnowledgeAllow and routes Retrieve through
RetrieveShared when the predicate is registered (nil = unchanged); hostcaps
search consults the same EXT-8 slot; GET /api/projects appends
adapter-authorized shared projects (projectView with shared flag, deduped);
POST /api/projects/{id}/conversations falls back to
CreateConversationInProject when the own-project path misses and the
adapter authorizes; store gains ListAllProjects (candidates only, callers
must filter through the adapter) and CreateConversationInProject.
Revocation takes effect immediately on both paths; absence of an adapter
is byte-for-byte the previous behavior. No pkg/extension surface change.
Refs: docs/proposals/2026-10-09-ext-g1-b1-b3-exec-backend.md (EXT-13, EXT-15)
Why: The DOCX parser only read w:r runs that were direct children of w:p, so
text inside w:ins, w:hyperlink and w:fldSimple was dropped with no warning,
violating the no-silent-degradation rule. Separately, runtime.exec is a
user-writable setting, so multi-user deployments could not reliably turn the
exec primitives off.
Evidence: SELF - red tests TestParseDocxTrackedChangesAndHyperlinks and
TestExecHardDisabledOverridesSettings failed before and pass after; backend
go test ./... (32 packages) passes; a mock-mode binary started with
--disable-exec-tools hides run_shell/run_python/register_artifact from
/api/tools even after the user sets runtime.exec=true.
Impact: DOCX paragraphs are decoded from the token stream at any depth;
deleted/moved-from text, field codes and mc:Fallback are excluded and
revised documents carry an explicit warning. New Options.DisableExecTools
(SurfaceVersion 2.5.0-experimental), CLI --disable-exec-tools, config key
disableExecTools and env AGENT_SYSTEM_DISABLE_EXEC_TOOLS; zero value keeps
current behavior.
Refs: Agent-System-RDM docs/proposals/2026-10-09-V22-review-and-implementation-plan.md (G0-7, B-5)
Why: EXT-8 closure needs the vector channel shared (not just fulltext), the /host/v1 knowledge face honoring the authorizer, and citation-ref-to-artifact consistency pinned as an acceptance test.
Evidence: TestRetrieveSharedVectorChannel (hash embedder: authorized shared vector hit retrievable, denied yields zero), TestSharedSearchFace (hostapi switches to SharedSearch when wired), TestSharedCitationRefDownloadable (shared hit -> Ref -> artifact content download for the authorized member); go test ./... 32/32 packages ok.
Impact: store.SearchKnowledgeVectorsShared; rag.Pipeline.RetrieveShared (own + shared fulltext + shared vector, RRF-merged); server searchKnowledge prefers RetrieveShared when the retriever implements it; hostapi Server.SharedSearch wired in the composition root through the same authorizer slot. Default behavior unchanged.
Refs: EXT-8 proposal acceptance; slices 1-2.
Why: The red run pinned the missing wiring; downstream recovery paths need a legal handle outside dispatch.
Evidence: TestScopedHostFactory green (fail-closed before wiring; Owner/PluginID, KV roundtrip, prefix enforcement, empty-arg rejection after); go test ./... all packages ok.
Impact: wireScopedHostFactory injected in app.Run after hostcaps assembly; no dispatch-path change.
Refs: EXT-11; red run at 182d8b5.
Why: Knowledge retrieval cross-owner and conversation-card mirroring are the registered EXT-8 slice-2 items; the fields/wiring land with the acceptance reds pinned first.
Evidence: mirror red (project channel still emitted with switch off); shared-retrieval red (grant yields 0 hits); SSE-scope red (grant yields non-200); rows follow on the task card.
Impact: Options.DisableConvCardMirror passthrough (extension/link/app); cardsvc.MirrorConvCards (default true = current behavior); SurfaceVersion 2.3.0-experimental. Behavior unchanged.
Refs: EXT-8/EXT-12 proposals; task card.
Why: EXT-9 is the other step-4 hard prerequisite; the surface (Options.DisableUploadIndexing passthrough, Host.KnowledgePublish idempotent replace, Host.KnowledgeDelete prefix-enforced revoke, SurfaceVersion 2.2.0-experimental) must land with the acceptance reds pinned before implementation.
Evidence: app red = publish not implemented; server red = switch-on still indexes (hits=1); rows recorded on the task card.
Impact: pkg/extension additive surface (surface.txt updated); internal Options passthrough; Server.DisableUploadIndexing field; host method stubs. Behavior unchanged.
Refs: EXT-9 proposal; task card.
Why: EXT-8 is accepted (Documents #49); the surface (Registry.RegisterResourceAuthorizer, ResourceAuthorizer, SurfaceVersion 2.1.0-experimental) plus the Server injection seam must land before the read-path consultation, and the behavioral red run proves the gap.
Evidence: go test ./internal/server -run TestProjectResourceAuthorizerSharesReads FAIL (shared read 404 with adapter set); default-deny section passes; row recorded on the task card.
Impact: pkg/extension additive surface (surface.txt updated); projectAuthz slot in hostcaps; Server.ProjectAuthz + setter; app wiring after compiled load; declarative registry fails closed. Read behavior unchanged.
Refs: EXT-8 in Documents 2026-10-08-ext-c1-c7-rdm-shared-contracts; task card.
Why: spans now follow the OTel GenAI convention (Agent-Native#32); the
product needs the settings surface for the exporter, a meaningful
service.name, and per-profile agent names.
Evidence: go test -count=1 ./... green; TestTelemetryFlagsDefaults
(otlpEndpoint registered default empty = no export, serviceName
default agent-system-backend); nested pins carry the convention work.
Impact: nothing is exported unless telemetry.otlpEndpoint (or the env
var) is set; agent spans are named by profile id.
Refs: Agent-Native#32, Agent-Squad#36, N3 plan WP4
Why: child runs had no independent transcript, no resume path (sealed
interrupted only), in-memory completion notices lost on restart, and
the subagent Background declaration had no consumer.
Evidence: go test -count=1 ./... green; TestSubagentTranscriptFilesWritten
(request/transcript/done files), TestResumeInterruptedChildrenRespawns
(re-spawn with original task + transcript-path hint, resumed.json
idempotent), TestNoticesPersistAndRedeliverAfterRestart (persist →
reload → deliver → delete), migration v17 pending_notices with up/down
on both dialects.
Impact: per-run transcript dirs under the workspace root (auxiliary,
write failures never abort spawns); interrupted children with a stored
request re-spawn as background runs at startup (pre-WP5 runs stay
sealed); notices survive restart; delegate factory honors
Request.Background with a sync fallback when the host lacks background
support.
Refs: Agent-Native#29, Agent-Squad#33, N2 plan WP5