Why: Missing Usage must stop a paid sequence before a tool terminal is executable; exact attachment names and host-owned choices must also remain reliable.
Evidence: Each reported behavior had a failing regression before its fix. Full Backend vet/Go tests, live-tag budget tests, ten race replays, and six task-owned HTTP/Playwright scenarios passed with the aligned Agent-Native and Agent-Squad pins.
Impact: Evaluation terminal accounting becomes durable before delivery; material fallback matches bounded filenames; ready choices use host options without redundant model fields. No new model calls or budget authorization.
Refs: U3 r0.4 independent review Critical 1 and Important 3-4
Why: failed or ungrounded material notices still asked nontechnical users to choose deliverables and could act on invented model options.
Evidence: failure, partial, no-suggestion, forged-marker, source-drift, reload and host-option RED→GREEN tests; race, isolated PostgreSQL, full Backend vet and tests pass.
Impact: only a completed source-bound result with 3-4 bounded suggestions can offer a choice; failed or stale notices preserve truthful status and block unsolicited delegation.
Refs: U3 r0.4 design; internal/runmgr/material_notice.go; internal/runtime/material_choice_notice.go
Why: wrapper-side tool deltas raced with serialized run events and could disappear under load.
Evidence: TestToolCallDeltaBeforeExecution race reproduced on the old path, then passed ten race runs with Agent-Native e86e74b; full Backend vet and tests pass.
Impact: one owner emits conversation events; Backend pins the Agent-Native event identity contract.
Refs: Agent-Native PR #46; internal/runtime/llm_direct.go
Why: Valid but underdetermined model claims must become pending without losing the batch or leaking unsupported status text.
Evidence: Mixed-batch, source-input binding, approval-status, tool-receipt and prompt regressions failed before changes; go test ./... -count=1 and selected live-tag fake-provider tests passed.
Impact: Validate all task-bound sources, normalize once, return a safe receipt, and version material processing as v9; no extra provider call.
Refs: Dev task feature/fast-slow-u2-u3-plan; r0.3 evidence implementation plan Task 3
Why: One paid A01 run split into multiple prompt-fingerprint groups, and persisted Usage omitted real checkpoint tool calls.
Evidence: Stable-run grouping, missing-ID refusal and tool-call usage regressions failed before and passed after; full Go, race and live-fixture checks passed.
Impact: Future controlled evaluations count per-run calls and deadlines by host run identity and persist tool-call usage. The failed r0.2 A01 record is unchanged.
Refs: U3 r0.2 A01 independent replay, Task 6
Why: Independent review found false approval rejections, duplicate checkpoint counting and final-only reminder changes to evaluator grouping.
Evidence: Three focused regressions failed before fixes and passed after; go test ./... -count=1, race and live-tag fixture checks passed.
Impact: Valid questions and denials persist, only distinct checkpoint IDs count, and final-only requests keep their original run fingerprint.
Refs: U3 quality revision r0.2, independent final review
Why: Material runs could spend the remaining budget on checkpoints and leave no final response.
Evidence: go test ./... -count=1; go test -race ./internal/runtime -run TestMaterialFinalReserve -count=1; offline replay of the prior A01 usage boundary.
Impact: Material subagents enter final-only mode or stop before another provider request; ordinary subagents retain their existing behavior.
Refs: U3 quality revision r0.2, Task 4
Why: A source-valid analysis in the approved A01 sample promoted a requirement into an approved decision.
Evidence: The observed claim and six display fields failed before the guard, then passed with negative/question and mixed-clause regressions; full runmgr tests passed.
Impact: Keep exact material records while rejecting model-authored affirmative approval assertions before persistence; final model quality remains unverified.
Refs: Agent-System-Backend#193; Agent-System-Dev#512
Why: The bounded A01 model call produced a five-finding malformed payload and an abbreviated quote that strict validation correctly rejected.
Evidence: Full Backend suite passed; original paid failure and rejected source citations remain unchanged.
Impact: Advertise one to three findings per publication and continuous literal quotes, bumping material recipe identity to v7; Core authority and budget remain unchanged.
Refs: U2/U3 failed A01 assessment and proposed bounded follow-up
Why: Preserve the newest protected main for the combined review candidate.
Evidence: Exact incoming object fetched; affected checks will replay.
Impact: Retain both histories without relaxing source or task authority.
Refs: Dev main aa6364f
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: Authentic quotes do not establish an unstated approval, and the evaluation wrapper must honor tighter production output limits.
Evidence: Approval-overstatement and 780-token-cap regressions failed first; complete Backend suite and fixture cap checks now pass.
Impact: Render material records from trusted labels and validated quotations, reserve interpretation for explicit finding kinds, bump recipe identity and cap the fixture without overriding smaller limits.
Refs: Approved R05; independent model assessment; original failed samples preserved
Why: Delayed notices, plugin name collisions and startup recovery exposed stale sources or silently created new attempts; deletion lost search index cleanup.
Evidence: Meaningful red regressions and the corrected complete Backend suite passed; production startup was exercised through an isolated subprocess.
Impact: Revalidate notices at delivery, retain plugin dispatch, restore index cleanup and complete all service wiring before recovery and public intake. Scope fixture processes and wait for owned transcript writes.
Refs: Agent-System-Dev feature-fast-slow-u2-u3-plan; independent review findings 1-3 and startup supplement
Why: Real source-backed discoveries should reach the same task card before the slow channel completes.
Evidence: SELF receipts record runtime and manager checkpoint red-green tests, scoped source/version checks, privacy filtering, quota corrections, and SQLite/PG regressions; fixed composition and live comparison follow.
Impact: Adds a local material-only checkpoint sink with no summary model calls, uses version witnesses for source commits, and preserves existing reading and notification paths.
Refs: fast-slow-u2-u3 Tasks 6 and 7; test-only live HTTP harness bounds shared provider requests without approving HITL
Why: after material organization completes, weak models report and end the turn without offering the user a choice of formal deliverables, and even after a user picks one the model may close the turn without starting the background task.
Evidence: new tests (notice-choice chain, deliverable backstop, free-input path, invalid args, notice contract) pass; full go test ./... exit 0 (local, SELF).
Impact: new confirm_choice tool issues a HITL choice card and routes the answer into a hard delegate instruction; material notices instruct the model to report then offer choices; stop hook adds two one-shot backstops (choice not offered in material notice runs; choice made but no background delegation).
Refs: Dev task .task/feature-material-intake-flow.md I2.
Why: the dual-speed entry hint is advisory only; real runs (MiniMax, 3 attachments, no text) end with a clarifying question and zero delegation, so background cards and result backfill never start.
Evidence: new unit tests in runmgr/material_test.go and runtime/material_flow_test.go all pass; full go test ./... exit 0 (local, SELF).
Impact: attachment-carrying runs now guarantee a material-organization background task (pre-spawn on attachment-only/heavy sends, stop-hook backstop otherwise when the model did not delegate); subagent receives inline parsed text with budget plus knowledge_search guidance; content-key dedup prevents duplicate spawns (in-flight, completed, resend); model-authored delegate_task gains a materials appendix; settings runtime.materialIntake (default on) and runtime.materialIntakeChars added.
Refs: Dev task .task/feature-material-intake-flow.md I1; user ruling 2026-10-11.
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: Reminders are attached to the request copy and never reach the
session journal, so a transcript grep proves nothing about whether the
R4 trigger fired - the first verification attempt was invalid evidence.
The dual-speed nudge already logs for exactly this reason.
Evidence: go test ./internal/runtime green; the follow-up live probe
must show the [runtime] r4 escalation reminder injected line in the
instance log.
Impact: Two log lines, nothing else.
Refs: Dev task feature/agent-e4-escalation-ledger (third fix-up).
Why: The consecutive-failure counter never fired in the live suite (0
reminders despite 20 failures) because real failures interleave with
successes - each success reset the streak. The pattern to catch is
"spinning overall", not "N in a row".
Evidence: go test ./... green; the anchor test now covers scattered
failures (3 in the last 6 outcomes escalates, 2 does not, once per run);
the next live run must show the reminder actually appearing in the
transcript.
Impact: recentOutcomes ring (last 6) replaces consecToolFailures; the
zero-hit search trigger keeps its own threshold (2); message wording
matches the window semantics.
Refs: Dev task feature/agent-e4-escalation-ledger (second fix-up).
Why: The first E4 live comparison regressed badly (toolFailures 10->24,
toolCalls 63->166) and the instance transcript shows the loop: tagging
kernel read_file/grep results put a trailing [src_N] line on the
model's own workspace files, the model treated it as external
tampering, and re-read/re-edit cycles cascaded into the read-before-
write and file-changed guards.
Why: The ledger only ever needed SOURCES - searches always, and
workspace reads only under inputs/ (the upload material area). Grep
cannot distinguish materials from self-produced files, so it stays
untagged.
Evidence: go test ./... green; new anchor TestEvidenceLedger
OnlyTagsMaterialReads pins the inputs/-only rule; the re-run live
comparison follows on the Dev side.
Impact: evidenceTools loses read_file/grep; isEvidenceRead gates
workspace reads to inputs/; everything else (search tags, escalation
reminders, prompts) unchanged.
Refs: Dev task feature/agent-e4-escalation-ledger (fix-up of #131).
Why: The plan's E4 remainder under the MiniMax-only constraint: the
harness must detect the model going in circles and inject a
change-of-strategy instruction (R4 - the model cannot be trusted to
notice its own repeat-fail loop), and number sourcing needs addressable
evidence: tool results carry [src_N|tool] tags so "found in materials"
becomes "found in source src_N" for both the model and the fact-check
notice.
Why: Failure counting lives in one place (onEvent end, keyed by the
slot status) because tool execution is parallel; the ledger and tag
append are serialized by the same mutex, and escalation reminders fire
once per condition streak - following the dual-speed nudge finding that
MiniMax ignores vague reminders but follows concrete instructions.
Evidence: go test ./... green; new anchors TestEscalationOnConsecutive
ToolFailures, TestEscalationOnZeroHitSearches, TestEvidenceLedger
TagsSource, TestEvidenceLedgerSkipsNonEvidenceTools. Live before/
after comparison runs on the Dev side per ruling 6.
Impact: knowledge/web/tavily searches, fs_read_file and the workspace
read_file/grep results now end with a source tag and enter the run
ledger (2k-char head); two consecutive tool failures or two empty
search results inject a concrete change-of-strategy reminder;
base.deliverables v7 and agent-sub-research v3 explain the tags;
fact-check notice points at src results. Non-evidence tools and
failures are unchanged.
Refs: proposal 2026-10-10-agent-delegation-routing-sandbox.md (E4,
R4); Dev task feature/agent-e4-escalation-ledger.
Why: The E1 live comparison was the only metric that got worse
(unverifiedFacts 7 -> 12): the gate gave one correction round and then
shipped bare numbers. The design (E3) calls for number sourcing with a
mechanically checkable marking escape: numbers labeled as
targets/assumptions are honest planning quantities, not fabricated
facts, so the gate must let them pass - and the model must be told that
marking is the sanctioned way out.
Why: The marking decision is clause-scoped, not a fixed window - a
window wrongly blessed "3,500" because a neighboring clause said
"target 85%" (caught by the existing test). The second round only
fires when the unverified set actually changed, because the
continuation budget is shared across all final gates and a repeat
block on identical tokens starves the downstream gates (also caught by
an existing test).
Evidence: go test ./... green; new anchors TestMarkedAsEstimate,
TestUnverifiedFactsMarksPass, TestFactCheckGateRounds; the live eval
gains an unverifiedUnmarkedFacts field sharing the same marking rule.
Impact: base.deliverables v6 adds the hard number-sourcing rule;
research/explore/general sub-agent profiles v+1 require citations for
key numbers; fact gate: marked-in-clause numbers pass, round 2
escalates to "last interception" with the marking instruction, then
passes through with the check line. Eval report keeps the strict
series and adds the E3-series field.
Refs: proposal 2026-10-10-agent-delegation-routing-sandbox.md (E3,
D4); Dev task feature/agent-e3-evidence-gate.
Why: the round-6 real-model dual-speed run showed MiniMax writing its
reasoning as inline <think> blocks; finishChild's partsText fed them into
the background notice turn and the inbox result card verbatim.
Evidence: new runmgr test covers closed-block stripping with body preserved
and conservative handling of unclosed blocks; go test ./... 32 pkgs green.
Impact: partsText removes closed <think>...</think> spans before summary,
notice, and card assembly; unclosed blocks are kept as-is.
Refs: Dev task feature/dual-speed-real-path.
Why: the dual-speed slow lane shipped as an observable capability plus soft
prompt guidance, but on the real (non-mock) path models routinely grind
through heavy document tasks synchronously for minutes with zero user-visible
output - the pattern only engages when the model happens to think of it.
Evidence: five new unit tests over an injected clock cover fire-after-threshold,
quiet-before-threshold, disabled-by-setting, and the replied/delegated guard
paths (reminders observed in the captured kernel requests); full go test
./... 32 pkgs green. Real-model run recorded in the Dev task card.
Impact: runDirect tracks run start, user-reply, and background-delegation
state; reminders() injects a one-shot dual-speed nudge (SR-B10) once elapsed
time crosses runtime.dualSpeedNudgeSeconds (default 75s, 0 disables) while
the user has neither a reply nor a background lane. New setting registered.
Refs: Dev task feature/dual-speed-real-path; SR-B10 (RDM requirements/01 V2.1).
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: real run run_b520bf2e3037 showed the user-facing reply being displaced by
internal bookkeeping - the fact-check correction round's closing text plus the
same-source verifier skip notice became the visible answer while the actual
summary was folded into the process timeline (frontend splits at the last
process part). Same tail pollution reproduced on every same-model run since.
Evidence: go test ./... -count=1 green (32 pkgs); new regression tests cover
the demotion of the pre-check summary and the skip notice becoming a check
part; three old-contract tests updated to assert notices land as process
checks instead of final text.
Impact: stop() fact-check branch now demotes the standing summary (aligned
with the gate and cap branches) and asks the model for a fresh full reply;
verifier errors record as process checks (pass-state for same-source skip,
fail-state for real errors) instead of StopDecision.Notice text; the cap
notice likewise becomes a failed check line.
Refs: Dev task feature/final-reply-pollution-fix; diagnosis in
.task/feature-dual-speed-tasks.md lineage and session analysis 2026-10-10.
Why: SR-B10 (RDM requirements/01 V2.1, ruling J-03) defines the task-level
dual-speed pattern: a fast lane gives immediate feedback while deep work runs
in background with queryable progress and results posted back to the inbox.
The base system had the background spawn/notice machinery but nothing the
user could see while it ran or collect afterwards, so heavy tasks just made
the user wait on a synchronous turn.
Evidence: go test ./... -count=1 green (32 pkgs); new runmgr tests cover the
card lifecycle on success (progress card -> done/ok with result summary and
artifact line, card.created/updated/status events) and on failure
(done/danger with the error), plus the cards==nil no-op path.
Impact: spawnBackground now registers an inbox progress card linked to the
child run and rewrites it with the result on completion; the delegate_task
description and base-method working prompt teach the fast-feedback-first
pattern; a #background mock demo exercises the whole path end to end.
Refs: RDM docs/requirements/01 UR-27/SR-B10; .tmp 03-V2 §任务快慢双速通用模式;
Dev task feature/dual-speed-tasks.
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: User rulings 4 plus the P3 live evidence. The base library taught layout
standards but not how to work: no planning discipline (plan tool used in 2 of
31 tool runs), no retry-escalation rule (same failing call retried verbatim),
no check-API-first rule (phantom API calls), and nothing about edit
granularity - the P3 after-run showed one turn of 27 single-line edits plus a
self-review spiral (117 tools). The final-reply rewrite layer sees only
160-char summaries and fabricated chapters/promised unfinished work; with the
transcript now authoritative the working model already has full evidence, so
per ruling 4 the rewrite defaults off (kept as fallback when a work loop ends
with no user-facing text at all, plus opt-in setting).
Changes: new base.method module (plan-first for 3+ steps, switch approach
after two failures, check API signatures before scripting, batch edits with
multi_edit, persist to completion - never end on a promise, trace numbers/
dates/names back to source material or mark speculation, honest final
report); tool-description overrides for read_file/edit_file/grep/glob/
run_python/run_shell (dedicated tools over cat/sed, build pipeline for Word);
plan reminder now also nudges once when NO plan exists after several tool
turns (ignorable, once per run); runtime.composeFinal default true->false
with empty-body fallback.
Evidence: SELF - TestPlanlessNudgeFiresOnce (fires once, never repeats),
TestResolveSystemDefaultBase updated for the ninth base block; go vet +
go test ./... pass; live before/after on the golden task set recorded on the
phase04 task card per the policy clause.
Impact: Behavior-surface change only; no contract or storage changes.
Why: User rulings 1 and 3. The direct conversation path exposed only
run_shell/run_python, so any file edit meant rewriting and re-running whole
generation scripts (diagnosis: 24 calls with 9 failures in one turn, 6KB
scripts regenerated 8 times). The kernel already ships line-numbered reads,
exact edit/multi_edit with read-before-write, grep and glob; they were wired
only into the squad path. Deliverables had no editable source: docx output
came from one-shot python scripts, so "make section 3 more detailed" rebuilt
everything.
Now: WorkspaceToolsCheckpointed (sandbox = conversation workspace, checkpoint
hooks wired) is registered into the direct run and its decls join the tool
surface (plan mode keeps the read-only subset). Word deliverables get a
markdown-source pipeline - python3 -m housestyle.build renders .md
deterministically via docx_kit and runs lint + outline on every build
(write-time diagnostics, exit 1 on error so the model fixes the source and
rebuilds). run_python kits remain for xlsx/pptx/images (ruling 3).
base-tools/base-deliverables prompts and the house-style SKILL document the
new loop.
Evidence: SELF - TestDirectRunExposesKernelWorkspaceTools (read->edit->grep
against the real sandbox FS), TestDirectRunWithoutSandboxHidesKernelTools,
three new BuildTests in recipes (renders+lint passes, heading-skip errors
exit 1, CLI entry); go vet + go test ./... pass; live before/after on the
golden task set recorded on the phase03 task card per the policy clause.
Impact: Direct conversations can now read and edit workspace files
surgically; docx deliverables become edit-source + rebuild instead of
regenerate. No contract or storage changes.
Why: Every turn rebuilt context from UI messages with 160-char tool-result
summaries and truncated arguments (quality diagnosis root cause 1). The kernel
session transcript already persists full-fidelity messages; P2-I2 switches the
direct path to it as the authority, per the approved plan (Documents
2026-10-09 §4 P2, user ruling 2).
First run (or after structural divergence) seeds the transcript once with the
full ctxasm assembly; later runs pass only the current user message. Dynamic
context - tail notes (personal instructions, session notes, world-book
entries), env update (date, workspace files) and newly hit task-layer prompt
modules - refreshes once per non-seed run via Reminders, so the frozen seed
system prompt stays accurate. Structural divergence (excluded messages,
variant switching, regeneration) changes a fingerprint and reseeds the
transcript from the message store - the regenerate/exclude/variant mapping.
Legacy transcripts without a fingerprint are adopted, not wiped, preserving
crash-pairing repair. Near the window threshold a 9-section compaction
(aux.session-compact, extractive fallback) summarizes older turns with the
kernel's append-only compaction entry; the kernel request-side micro-clear
still bounds within-run spikes. Backend's nested agent-native pin moves to
the reasoning-capture/replay kernel head.
Evidence: SELF - new tests TestContextRevisionStableOnAppendAndChangesOnDivergence,
TestTranscriptReseedsOnVariantSwitch, TestBuildCurrentUserCarriesAttachmentsAndKnowledge;
TestDirectRunSeedsStoreHistoryOnce updated to authoritative semantics; go vet
+ go test ./... pass; live before/after on the golden task set recorded on
the phase02 task card per the policy clause.
Impact: Direct conversations with a workspace sandbox now carry full tool
results, arguments and attachment text across turns; MiniMax thinking replays
from the transcript via the kernel change. No-conversation fallback keeps the
pre-I2 assembly path.
Why: The live after-run (golden minutes-pm-tool) showed the truncation spill
artifact tool-run_shell-<call>.txt entering CheckArtifacts as a .txt
deliverable; its non-UTF-8 payload failed the scorer four times in a row.
These files exist to keep oversized tool output reachable - they are context
relief, not deliverables, and must not occupy delivery cards either.
Evidence: SELF - TestLatestDeliverablesKeepsLastPerName extended with a
tool-dump ref and asserts exclusion; go test ./internal/... passes; single-task
live rerun recorded on the phase02 task card.
Impact: latestDeliverables (gate input, verifier refs, reply deliverable list,
final artifact_ref cards) skips kind=data tool- prefixed refs. The spill files
remain artifacts for context backfill.
Why: Real-run before/after evidence (phase01 card) showed later turns never
re-read the uploaded source (0 original reads in plan-followup) because the
attachment only existed in the current turn's injection and the context window
hard default was 32000 chars - a 25k-char transcript tripped the clear-on-first
request, replacing old tool results with a pointer the model has no tool to
follow. MiniMax is an interleaved-thinking model whose docs require <think>
blocks in assistant history; dropping them degrades later turns.
Evidence: SELF - new tests TestThinkReplayWrapsAssistantHistory,
TestContextWindowScalesFromTokens, TestThinkReplayEnabled,
TestPersistInputTextsAndListWorkspaceInputs; go test ./internal/... passes;
live before/after comparison on the golden task set recorded on the phase02
task card per the new policy clause.
Impact: models.chat.contextWindow/outputReserve/contextBuffer (tokens,
defaults 128k/16k/4k) drive the in-run clear threshold, converted to chars;
cleared tool results spill to <sandbox>/.agent/results with readable paths;
attachment parse text persists as inputs/<name>.md and the env section lists
all workspace inputs every turn; context.thinkReplay (auto|on|off, auto =
MiniMax) replays thinking blocks into request-side assistant history only.
Why: lint-boundaries rejects new app->quality edges (architecture ratchet);
runtime already depends on quality for the scorer and holds SkillsDir, so the
injection belongs there. Same behavior, allowed dependency direction.
Evidence: SELF - go vet + go test ./internal/runtime ./internal/app pass;
lint-boundaries edge list unchanged.
Impact: quality.SetLintEnvRoot now called from LLMRunner.Execute when
SkillsDir is configured (idempotent, process-wide).
Why: Real transcripts (dev instance, 62 assistant turns) showed the artifact
gate silently off and self-deadlocking. lintFile ran python3 -m housestyle.lint
without the skills PYTHONPATH, so the import failed and nil was treated as "no
issues" (same docx: 9 lint errors with PYTHONPATH, 0 without). stop() re-scored
every artifact registered in the run, including superseded versions, so a fixed
document could never pass and the composed reply reported the old verdict.
ctxasm rendered history artifacts as "[产出工件 …]" - the exact pattern
ClaimGate treats as a forged tool marker, so models copying the format were
rejected. scoreReadable flagged table cells like "项目概述撰写" as column
headings. Prompts and recipes said "python -m" (no python on PATH; exit 127)
and housestyle.summarize was invoked as a module that does not exist.
Evidence: SELF - new tests TestLintUnavailableFailsVisibleWhenSkillsRootSet,
TestLintCommandEnvCarriesSkillsRoot, TestDocxHeadingMarkedAndTableCellNotFlagged,
TestLatestDeliverablesKeepsLastPerName, TestRecipesUseRunnablePythonCommands,
TestLibraryUsesRunnablePythonCommands; go test ./internal/... passes; manual:
python3 -m housestyle.outline_cli reads a real artifact docx cleanly, lint
without PYTHONPATH exits 1 with ModuleNotFoundError and is now surfaced as
自检未运行 when the skills root is configured.
Impact: compose root injects quality.SetLintEnvRoot(<data>/skills). Final-turn
checks score only the newest artifact per name; deliverable lists and reply
cards follow the same dedupe. History artifact placeholders no longer collide
with the forged-marker regex. docx text extraction marks Title/HeadingN styles
so readability only judges real headings, with line numbers in the reason.
Check reminders no longer invite the model to ignore failed checks. Oversized
tool output is truncated by runes, not bytes.
Refs: Dev task feature/agent-quality-phase01 (quality gap diagnosis 2026-10-09).
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: 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: 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: 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: 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: 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: 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>