Why: The red acceptance tests pin the EXT-9 semantics - held material must not enter retrieval until published, revoke must stop retrieval immediately and idempotently, manual sources must stay out of plugin reach.
Evidence: TestKnowledgePublishIdempotentAndRevoke and TestUploadPreIndexSwitch green; go test ./... 32/32 packages ok; rows follow on the task card.
Impact: hostcaps KnowledgePublish (per-ref row+vector cleanup then existing write path) and KnowledgeDelete (plugin:<id> prefix enforced); store DeleteKnowledgeBySource with vector cleanup; upload indexing gated by DisableUploadIndexing (default false = unchanged).
Refs: EXT-9 proposal; red run at surface commit.
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: With the surface and injection seam in place, the read endpoints must fall back to the adapter when owner-scoped lookup misses, keeping default-deny and fail-closed semantics.
Evidence: TestProjectResourceAuthorizerSharesReads green (default deny, shared list/meta/content via adapter, third-party denied, authorizer error fail-closed); go test ./... 32/32 packages ok.
Impact: listArtifacts/getArtifact/artifactContent consult authorizeSharedProject; store gains gated helpers (GetArtifactByID/ArtifactContentByID/ListProjectArtifactsAll) documented internal-only; writes untouched; SSE project stream and project card aggregate deliberately deferred to EXT-12 (conversation-card mirroring privacy).
Refs: EXT-8; red run at d89e748; 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: GET /api/commands/audit leaked every tenant's audit rows (command ids, entrances, conversation ids, param digests) to any authenticated user; owner was never recorded nor filtered.
Evidence: Red run at a7cc69b FAIL (alice sees bob's row); after fix go test ./... 32/32 packages ok, including TestCommandAuditOwnerScoping and the v18 backfill test (rows recorded on the task card).
Impact: v18 migration adds command_audit.owner with actor-based backfill (empty-actor rows stay invisible via API, kept in-table); AppendAudit/ListAudits gain owner params; cmdbus port and fakes updated; handler passes authenticated owner. No public extension surface change.
Refs: Task card R1; U0 proposal section 5 C7 finding.
Why: GET /api/commands/audit returns every tenant's audit rows; the regression test pins the desired owner-scoped behavior before the fix.
Evidence: go test ./internal/server -run TestCommandAuditOwnerScoping FAIL (owner alice sees bob's row; output recorded on the task card).
Impact: Test only; suite red on this commit by design.
Refs: Task card R1; U0 proposal section 5 C7 security finding.
Why: Q3 WP5 requires a same-batch dual-run harness (direct vs squad
compiled graph) that records differences without demanding byte-identical
output, feeding DecideSwitch evidence for the runtime.entry default-switch
decision.
Evidence: eval/ab_test.go mechanics (theme-based scoring, status/theme/
latency diff notes, P50, DecideSwitch wiring, RunFunc error tolerance,
empty batch); wfcompile TestABDemoBriefDualRun runs the demo.brief scenario
on both entries (direct = scripted single-agent answer; squad = real
RunCompiled with stub backend and judge) and logs the report: both sides
100/100, summary-form difference recorded, decision '切换条件已满足…合入前
需要产品确认'. Full backend suite green (SELF); CI authoritative (GATE).
Impact: new eval/ab.go harness (pure mechanics, no runtime dependency);
no product default is flipped - runtime.entry stays direct until product
confirmation per the DecideSwitch report semantics (evidence recorded in
the task card and PR).
Refs: Q3 plan WP5 (2026-10-07-agent-stack-q2q3-plans.md); task card
.task/feature-agent-stack-q3.md
Why: Q3 acceptance requires the delegation template to state goal, output
format, tools and boundaries; SubagentFactory's brief had four of six
sections and the kernel Request gained the two carriers (agent-native #40).
Evidence: adapter_test task-brief assertions extended (输出格式/工具面
sections present with declared values); full backend suite green (SELF);
CI authoritative (GATE).
Impact: nested deps/agent-native 1ac21c6 -> 37c5e6f (Request.OutputFormat/
Tools + delegate_task schema); SubagentFactory renders the two sections
when declared, omits them when empty (no behavior change for existing
callers).
Refs: Q3 plan WP3; task card .task/feature-agent-stack-q3.md
Why: Q3 WP2 retires the SpawnSubagent-compression execution path: all
WorkflowDef execution now goes through the wfcompile compiled graph, and
squad steps run on the agent-native kernel backend instead of the
agent-system step backend.
Evidence: runtime-level P4 parity tests (workflow_compiled_test.go):
registered branch lookup/errors, planned branch confirmation gate +
dynamic 8-step cap fail-closed before any HITL, model script switch
default-off, missing-slot HITL collection with compile-time rendering,
judge stream routed to the configured lightweight model (nil = fail-closed
verifier-unavailable). squadadapter TestOrchestrateRunsOnKernelStub:
four-phase skeleton runs end-to-end on the kernel stub (write_file
materialization, seeded skills, exec allowlist). server TestSquadOrchestration
reworked: kernel steps run in-process (no subagent child runs). Full
backend suite green; wfcompile/squadadapter/runmgr green with -race
(pre-existing llm_test fake race on main recorded as debt, CI does not
gate -race).
Impact: DELETED runtime/workflow.go + workflow_script.go (legacy step loop,
critic, script host) and their tests; squadadapter stepBackend
'agent-system' + profileForRole deleted; BuildBackends exported and
registers only agent-native; Orchestrate DefaultBackend -> agent-native;
builtin roles declare agent-native with write_file added to allowlists and
writer run_shell -> run_command (kernel tool name); runmgr default workflow
runner -> CompiledWorkflowRunner; mock #workflow demo runs compiled
(host-only steps). Model script branch keeps the single script-level
confirmation (no extra plan confirmation), matching legacy.
Refs: Q3 plan WP2 (2026-10-07-agent-stack-q2q3-plans.md); task card
.task/feature-agent-stack-q3.md
Why: Q3 WP1 requires core.WorkflowDef workflows to run as compiled squad
graphs (P4 limits and DeniedTools enforced at the compile entry) so the
legacy SpawnSubagent-compression executor can be retired in WP2.
Evidence: internal/wfcompile conformance (zero model, zero network; script
step runs the real codeorch host like the legacy tests): demo.brief shape
(hitl/prompt+critic/artifact/card mapping, evaluator-optimizer loop budget
= maxRetries+1, needs chain), P4 limits (dynamic >8 rejected, dynamic
script rejected, DeniedTools, critic >3, workflow retries >6), demo.brief
E2E (critic fail->retry->pass, drops record, artifact from step-ref file,
card, hitl sequence without plan confirmation for registered workflows,
BB out_length visible in the draft task brief), critic exhaustion fails
closed, demo.script E2E (plugin script exempt from confirmation, wf.tool/
ask/artifact/step callbacks), workflowScripts off fails, model script
double confirmation with reject paths. Full backend suite green (SELF);
CI authoritative (GATE).
Impact: new package internal/wfcompile (compiler + host IntentRunner +
RunCompiled driver); nested deps/agent-squad 06934bc -> 633e853 (StepSpec
.Brief). No existing backend behavior changes (legacy executor untouched
until WP2).
Refs: Q3 plan WP1 (2026-10-07-agent-stack-q2q3-plans.md); task card
.task/feature-agent-stack-q3.md
Why: run terminal status persists before the conversation claim is
released; on the slow CI runner the rewind POST landed inside that
window and got a 409. Retry the POST until the claim frees (bounded).
Evidence: go test -count=5 ./internal/server/ -run TestRewindFilesHTTPHappy
green; full suite green.
Impact: test-only.
Refs: Agent-System-Backend#94 #97
Why: subagent runs recorded zero tokens, cache hits were invisible in
run records, the usage event skipped terminal paths, and stream retry
existed only on the direct-chat path (audit N20 residual).
Evidence: go test -count=1 ./... green; TestRetryAttemptsMapping
(setting 0=off→-1, N→N), TestDirectRunUsageSplitOnRecord (Last* and
cache land in the run usage), TestSubRunAccountsTokens (subagent
accounting), TestAddUsageAccumulatesSplitFields (handle chain); pins
carry Agent-Native#35/#37/#38/#39, Agent-Squad#41, Core Usage fields.
Impact: run.Usage carries Last*/cache on every path; subagent runs are
accounted; runtime.llmRetries maps onto the library default (setting 0
disables via -1); the verifier wraps retry+fallback explicitly; retry
events surface as process parts.
Refs: Agent-Native#35-#39, Agent-Squad#41, N3 plan WP6
Why: memory recall lived as a product-side interface assertion with no
library port, AgentSpec.MemoryScope had no consumer, and the model had
no write-back path. The port (Agent-Native#34) now exists; the product
adapts it over memory_entries.
Evidence: go test -count=1 ./... green; TestStoreMemoryRecallScopeAndLimit
(scope filters and limit), TestStoreMemoryAppendRoundtrip (project
context inheritance), TestRunCtxStoreMemory (runCtx outlet),
TestDirectRunInjectsMemoryBlock (the [记忆] block reaches the request
with the pre-migration text shape and deterministic order).
Impact: assembly-side injection removed (the loop injects per request
— same text, no duplication); memory_write available on the kernel
path; recall defaults to all scopes (pre-migration semantics), with
AgentSpec.MemoryScope narrowing where hosts pass it.
Refs: Agent-Native#34, Agent-Squad#38, N3 plan WP5
Why: the library now pins eligibility, guards symlinks, reports partial
restores, and bounds the log (Agent-Native#33); the product wires
retention after successful rewinds and needed the HTTP-layer and
eligibility evidence.
Evidence: go test -count=1 ./... green; TestRewindFilesHTTPHappy and
TestRewindFilesHTTPBusy409 (HTTP happy + conflict),
TestBackendCheckpointEligibilityIsWriteFileOnly (the product surface
checkpoints exactly {fs_write_file}).
Impact: checkpoints.jsonl is compacted to the latest 200 anchors after
each successful rewind.
Refs: Agent-Native#33, Agent-Squad#37, N3 plan WP3
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: the product conversation path had zero mid-turn durability
(llm_direct ran without Session — intents, recovery pairing, and
side-effect replay semantics never applied). Transcript-as-authority
would have frozen the assembled prefix, so the journal is wired in
JournalOnly mode: recovery runs against the transcript, the context
stays on the ctxasm pipeline, and recovered outcomes inject as a
system note.
Evidence: go test -count=1 ./... green;
TestDirectRunPairsAfterKillSeed (crash-window transcript gets the
crashInterrupted pair, run proceeds) and
TestDirectRunSeedsStoreHistoryOnce (history appears exactly once in
every request, never enters the journal); the forged-marker and
harness suites pass unchanged.
Impact: conversation runs now journal tool intents and recover them on
the next run; no transparent resume (sealed interrupted stays; the
user keeps chatting). Opening the transcript fails soft (falls back to
the old no-session behavior).
Refs: Agent-Native#31, Agent-Squad#35, N3 plan WP2
Why: Stop.Replacement no longer rewrites the in-memory assistant; the
correction reaches the model as a user note. The guard's protective
intent is unchanged (forged body never replays as assistant speech).
Evidence: go test -count=1 ./... green.
Impact: test only.
Refs: Agent-Native#30, N3 plan WP1
Why: InterruptRunning wrote done.json{status:interrupted} for every
child, and ResumeInterruptedChildren skipped anything with done.json —
graceful shutdowns never resumed (only SIGKILL-style deaths did). done
markers now split by status: terminal states block resume, interrupted
does not. Nested pins carry repairOrphanTail and the N6 fix.
Evidence: go test -count=1 ./... green; TestResumeAfterGracefulInterruptMarker
(resumed once and only once), TestResumeSkipsCompletedMarker (terminal
states still block).
Impact: after any restart, interrupted children with a stored request
re-spawn exactly once regardless of how the process stopped.
Refs: Agent-Native#30, Agent-Squad#34, N3 plan WP1
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
Why: plugin skills were written to the skill root unvalidated and the
bundled recipes carried no name — both now go through the library's
spec validator (name required + kebab-case + equals dir, description
required, known-keys whitelist).
Evidence: go test -count=1 ./... green; TestV2InvalidSkillRejected pins
the fail-closed path with plugin context + field location; Seed
validates each SKILL.md before write (recipes dogfood-compliant);
nested pins carry agent-native#28 (the validator).
Impact: invalid plugin skills now abort the plugin load with a located
error instead of landing silently; the architecture baseline gains
backend/plugins→backend/skills.
Refs: Agent-Native#28, Agent-Squad#32, N2 plan WP4
Why: trimOldest dropped single messages without tool-pair awareness —
after leading users were evicted it could orphan tool results or leave
dangling calls (acceptance clause 2's product-side gap).
Evidence: go test -count=1 ./... green; TestTrimOldestKeepsToolPairs
(pairing holds across repeated trims), TestTrimOldestDropsLeadingOrphanToolRun,
TestTrimOldestStopsWhenGroupCrossesCurrentTurn, TestPrefixHashStableForIdenticalInput;
native pins carry the spill and cache-contract work (Agent-Native#25).
Impact: trimming now evicts whole tool groups; the window may be
slightly exceeded when a group would cross the current turn — pairing
is never broken. Report.Truncations still records the count.
Refs: Agent-Native#25, Agent-Squad#29, N2 plan WP1
Why: I2 increments 1-2 shipped the agent-intent ports (SemanticScorer,
CommandGenerator); the backend still had no implementation, so the slow
lane could not be enabled in the product.
Evidence: go test ./... green; lint-boundaries ok; the two new
runtime.intentSemantic / runtime.intentGenerator flags are registered
with default false and the gate defaults to the I1 recognizer when both
are off (TestIntentSlowLaneFlagsDefaultOff, TestGate*).
Impact: no behavior change by default; enabling runtime.intentSemantic
routes ambiguous rule matches through embedding cosine scoring, and
runtime.intentGenerator lets the lightweight model propose commands on
fallback with library-side fail-closed validation. Nested agent-intent
pin moves to 343b1e6 (I2 increments 1-2).
Refs: I2 increment 3
Why: The boundary linter allows agent-intent imports only in the
adapter layer; route and runmgr consume aliases from intentgate
instead of importing the ecosystem library directly.
Evidence: lint-boundaries passes below; backend suite green.
Impact: intentgate re-exports Command/ActionRef and the kind
constants; route drops the agent-intent import.
Why: I1 WP3 - chat routing and the HITL free-text pivot now share one
router consuming the library's command list, and both intent hosts
fold compatibility-equivalent input.
Evidence: go vet clean; go test ./... 30 packages ok, including the
existing workflow-route and server e2e suites unchanged (behavior
parity) and the new route package tests.
Impact: new internal/route package (unique router with explicit
priority rules); intentgate carries Commands and folds NFKC;
server.go and runmgr.go route through it; nested pins at intent
2554b50 and squad 6b7a991. Blueprint actions resolve to a squad
decision at the router level; per-run squad entry stays a recorded
follow-up (no silent misrouting).
Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md I1 WP3/WP4
Why: N1 WP5 host side - directRun.stop and the checklist reminders
now call the library gates package behind product ports, and the
nested native pin moves to the merged WP5 head.
Evidence: go vet clean; go test ./... 29 packages ok, including the
characterization suite unmodified and the new wp5_ab_test.go
(verify-cap continuation counts and gate-reason text parity).
Impact: llm.go drops the local regex family and deliverableGate;
verify.go drops checkDeliverables/parseVerdict/stripFence and the
local caps; workflow.go switches to gates.Verdict; reminders run
through gates.ProgressReminder. Behavior is pinned identical by the
existing suite plus the A/B tests. Squad reminders stay out of this
increment (adapter lacks per-member tool-turn signals - recorded as
WP6b).
Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md WP5/WP6
Why: N1 increment three host side - plugin agent assets must reject
hooks/mcp/permissionMode declarations (WP1 acceptance), and squad
members need the kernel ask port wired to the HITL card (WP4).
Evidence: go vet clean; go test ./... 29 packages ok, including new
agent-asset tests (banned keys located to the field, unknown keys,
missing id) and the V2 asset suite. Nested pins at native c5b9dca
(PR #18) and squad fc9620e (PR #17).
Impact: plugins agents/ assets now parse via parseAgentAsset
(strict JSON with banned-key rejection); PermissionAskOf exported
and takes any host with the optional method; app.go wires
cfg.PermissionAsk for the squad path. Legacy behavior unchanged when
nothing registers the port.
Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md WP1/WP4
Why: N1 WP2/WP3 host side - the kernel ask loop must reach the HITL
confirm card, and tool gating should run through the typed Policy with
the session-allow store port instead of a hand-built Request.
Evidence: go vet clean; go test ./... all packages ok, including new
TestConvAllowStoreKeysByName, TestPermissionAskRoutesToHITL, and
permissionAskOf tests. Nested agent-native pin at 9758a8d (PR #17).
Impact: runmgr.ExecuteTool decides via agentpolicy.Policy with
convAllowStore (keying unchanged: conversation x tool name);
runCtx.PermissionAsk routes kernel asks to the shared toolConfirmCard
HITL; direct and subagent loops pass PermissionAsk into the kernel
config (nil for hosts without the method, preserving legacy ask=reject).
Refs: Documents proposal 2026-10-07-agent-stack-n1q1i1-plans.md WP2/WP3; Agent-Native PR #17
Why: review of EXT-5 found a column-cap cell (common styled XFD cells) wrongly reported the 200k-cell cap and aborted every remaining worksheet; malformed sheet XML was also dropped silently, contradicting the explicit-failure contract; the legacy-office parser id was missing from the registry.
Evidence: local GOWORK=off go test ./... 29 packages pass with new regressions (wide column keeps later sheets, bad sheet XML warns, registry maps doc/xls/ppt); go vet clean; recorded as SELF on the Dev task card.
Impact: xlsxSheetBlocks returns wide/badXML signals; wide cells skip with a per-sheet warning, cell-cap truncation unchanged; builtin:legacy-office added to ParsersDescription.
Refs: review of backend 727f370; documents proposal 2026-10-06-ext-5-host-parse-document sect.2.
Why: downstream parsers are unreachable via extension.Host and the base lacked xlsx/pptx parsers; MS1 needs Excel and PPT ingest (EXT-5 request, documents proposal 2026-10-06-ext-5-host-parse-document).
Evidence: local GOWORK=off go test ./... all 29 packages pass incl. new ooxml_test (hand-built parts), ooxml_python_test (openpyxl/python-pptx round-trip), inproc owner-scope and limit tests, xlsx upload e2e; go vet clean; recorded as SELF on the Dev task card, PR CI to confirm.
Impact: Host gains ParseDocument (pure compute; errors only on ctx cancel or >100MiB input); builtin:xlsx (sheet order via workbook.xml rels, rich-text shared strings, formula cache, 1900/1904 dates, sparse cells) and builtin:pptx (sldIdLst order, titles, group shapes, AlternateContent Choice, tables, notes) added with 200k-cell/64MiB-part caps; legacy doc/xls/ppt get an actionable hint; ParsersDescription gains xlsx/pptx and the missing text ext; surface snapshot now records exported interface methods; docx part reads share the 64MiB cap.
Refs: documents 2026-10-06-ext-5-host-parse-document.md; EXT-1 host.go precedent.
Why: GET /api/conversations on the default unarchived view appended
AND archived=0. PostgreSQL stores conversations.archived as BOOLEAN
and rejects boolean = integer (42883), so listTasks returned 500.
The previous dialect fix bound parameters and scans but left this literal.
Evidence: before the change, TestConversationFlagsAndTaskList against
pg1 failed with SQLSTATE 42883. After: AGENT_PG_TEST_DSN set to pg1,
go test ./internal/store -count=1 passed; go vet ./... && go test ./...
passed on SQLite.
Impact: the default task list works on the postgres tier. SQLite still
binds the bool as 0/1. openTestStore accepts URL and keyword DSNs and
keeps public on search_path so an existing pg_trgm extension stays visible.
Refs: Agent-System-Dev feature/store-pg-archived-literal
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: user create/reset-password and conversation flag updates wrote 1/0
literals and boolInt ints into BOOLEAN columns; SQLite tolerates it,
PostgreSQL rejects with 42804. The 10-04 user create on pg1 failed midway
(empty password_hash, is_admin=f), and password reset, user list (bool
scanned into int) and login (GetUserAuthState scan) were all broken on
the postgres tier.
Evidence: store tests green; against the live pg1 the fixed CLI completes
user reset-password and user list (isAdmin=true, mustChangePassword=true,
hasPassword=true).
Impact: auth/account management and conversation list/flag paths work on
postgres; SQLite unchanged (0/1 converts via driver.Bool). No schema
changes.
Refs: dev-repo PR for gitlink bump (feature/store-pg-bool-dialect)
Why: Masks must not be the only copy of a key, and personal instructions, lore hits, and candidate replies have to reach the model without rewriting the system prefix or deleting history.
Evidence: go test ./internal/store ./internal/ctxasm ./internal/settings ./internal/runtime ./internal/server. Migration v16 upgrades and rolls back. Startup snapshots settings before moving raw keys.
Impact: One labeled key is active per service. Excluding a message hides its whole run from the model. Regenerating appends another candidate and rewinds files to the user turn. User slash commands expand to prompt text and do not fire on their own.
Refs: docs/records/2026-10-04-sillytavern-review.md
Why: The embedded tier starts without auth, and nothing checked Origin or Host, so a public bind or a foreign page could call write APIs.
Evidence: go test ./internal/config ./internal/server covering listen policy, origin rejection, and response headers.
Impact: Non-loopback without auth exits before opening the database. HTML artifacts get a sandbox CSP. Reverse proxies must list their public host in allowedHosts.
Refs: feature/sillytavern-review
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: A dotted-key PUT was stored beside the nested object and never read, so replacing a key kept the old pool. GET also returned tools.tavily.apiKeys in clear text, and saving settings would write the mask placeholder back over a real key.
Evidence: go test ./...
Impact: Dotted writes take effect on the next read. Startup expands stored dotted keys, and the existing nested value wins when both forms exist. GET masks schema secrets, including apiKeys. Writing the mask placeholder no longer overwrites a stored secret.
Refs: fix/settings-dotted-keys
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: workflow scripts and run_tool_script should share one Python host, while a slow MCP server must not block the first prompt.
Evidence: GOWORK=off go test ./internal/runtime/ ./internal/app/ ./internal/settings/ ./internal/tools/ ./internal/runmgr/
Impact: runtime.codeOrchestration defaults to false, so the tool stays hidden. Workflow script confirmation and its longer timeout cap stay as they were.
Refs: feature/code-orchestration
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: workspace writes had no checkpoint, and a 5xx before any output stopped the turn instead of trying the next configured model.
Evidence: GOWORK=off go test ./internal/runtime/ ./internal/runmgr/ ./internal/tools/ ./internal/settings/ ./internal/server/ ./internal/app/
Impact: models.chat.fallbacks defaults to empty, so existing runs keep their model. Rewind restores only tracked writes and appends a system note. Usage records the model that served.
Refs: feature/durable-rewind
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Plan mode has to block writes, confirmations dropped the argument preview, and direct chat did not share its stop gate with squad members.
Evidence: GOWORK=off go test ./internal/store/ ./internal/tools/ ./internal/runmgr/ ./internal/runtime/ ./internal/server/ passed. Default mode still runs write_artifact; plan mode rejects it.
Impact: Empty permission mode keeps the profile allow, deny, and confirm lists. High-risk shell commands now ask. There is no bypass-all mode.
Refs: feature/permission-hooks
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: A dropped subscription had no retry hint, and a reconnect had no test that the gap is filled from the cursor.
Evidence: The stream starts with retry: 1000. A live publish is delivered, and Last-Event-ID after an overflow replay skips events the client already has.
Impact: EventSource waits one second before reconnecting. Persisted events are unchanged.
Refs: feature/runstate-shell
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Byte truncation split UTF-8, subagent results could return unbounded text, and a write could overwrite a file that changed after it was read.
Evidence: cutRunes keeps a two-character Chinese prefix; tool selection honors -name; checklist reminders go through the reminder bus.
Impact: Tool output limits count characters. A subagent result over 32000 characters is stored as an artifact and the parent sees the path. fs_write_file rejects an existing file that was not read in this run.
Refs: feature/context-engineering
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: The direct path never retried provider timeouts, so a single 429 failed the run.
Evidence: go test ./internal/settings/ ./internal/runtime/ passed. Default runtime.llmRetries is 2.
Impact: Retries happen only when the stream has not forwarded a delta. Injected test streams are not wrapped.
Refs: feature/llm-robustness
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Refreshing or switching back only knew the latest event cursor, so process that had already happened was missing until the run finished.
Evidence: GOWORK=off go test -count=1 -run TestConversationResumeSeq ./internal/server passed. While a hitl run waits, resumeSeq is the run's first seq minus one and is less than lastSeq; after the run completes the two cursors match.
Impact: Conversation detail gains resumeSeq beside lastSeq. No core contract change. Clients that ignore the field keep the old cursor.
Refs: Dev fix/live-run-visibility
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: A hard kill left runs in pending, running, or waiting_hitl, a busy send stored a message before the 409, finishRun could mark a run completed without an assistant message, and a full SSE buffer dropped events without closing the stream.
Evidence: GOWORK=off go vet ./... and GOWORK=off go test -count=1 ./... passed, including store, runmgr, bus, and server recovery tests.
Impact: Migration v14 adds runs.instance_id and messages.request_id. Startup reconciliation and shutdown share one seal. Turn and workflow sends claim a slot before writing. Duplicate request ids return the existing message. SettleRun updates the run and appends the assistant message in one transaction. A full subscriber buffer closes the channel so SSE can replay from the cursor.
Refs: Dev feature/pi-durable-borrow
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Backend has to keep the same squad runs after the core stopped importing agent-native. The adapter module owns the concrete client.
Evidence: GOWORK=off go test -count=1 ./internal/... passed.
Impact: AgentNativeOptions now returns the adapter config. Default roles still use the agent-system backend.
Refs: D1
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: The composed reply copied the registered artifact id and file size out of the tool summary.
Evidence: go test ./internal/runtime/ -run 'TestComposeUserPromptOmitsArtifactIDs|TestComposeReplyDropsInternalRefs'
Impact: Those tokens are removed from the compose input and from the reply before it is shown.
Refs: feature/final-reply-compose
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: The first live run wrote its deliberation, including a think block and the quality score, as the reply the user sees.
Evidence: go test ./internal/runtime/ -run TestCompose
Impact: Think blocks are stripped before the reply is stored or shown. The compose prompt forbids paths, scores, and step-by-step reasoning.
Refs: feature/final-reply-compose
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: End-of-turn checks were injected as user messages, so the model answered the checker instead of the user, and the last draft was treated as the reply.
Evidence: go test ./internal/runtime/ ./internal/prompts/ ./internal/settings/ ./internal/ctxasm/
Impact: Rejections are system reminders. A main-model compose step writes the user-facing reply when tools were used. Deliverable cards stay after that reply.
Refs: feature/final-reply-compose
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: Tool calls stayed invisible until execution finished, and turn, tool, timeout, and output caps stopped long tasks early.
Evidence: go test ./internal/runtime/ ./internal/tools/ ./internal/prompts/ ./internal/squadadapter/ ./internal/runmgr/ ./internal/app/ ./internal/settings/
Impact: tool.call.delta and tool.output reach the client; default profile, subagents, and squad no longer cap turns or tool calls; exec timeout defaults to 600s with no hard ceiling. A profile or subagent maxTurns above 0 still applies.
Refs: feature/stream-display-overhaul
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: A conversation run has no launch of its own, so a script step looked up an empty copy and refused to run.
Evidence: go test ./internal/runtime/ -run TestRegisteredWorkflowUsesItsOwnScriptCopy passed. The body is taken from the launch passed into the runner.
Impact: Intent-started runs still use the copy made at start.
Refs: feature/agent-harness-p4
Co-authored-by: Cursor <cursoragent@cursor.com>
Why: The planner treated the goal as work to do, and the critic accepted a draft that missed the required line.
Evidence: go test ./internal/runtime/ ./internal/prompts/ passed. The planner task now says to output JSON and not perform the goal.
Impact: A missing required sentence is a failed check. The planner still cannot add script steps.
Refs: feature/agent-harness-p4
Co-authored-by: Cursor <cursoragent@cursor.com>