Why: Goal-sensitive workflow verification persisted model prompts and prior output text in trusted receipt rows, while cross-step model inputs could reuse stale machine output.
Evidence: RED receipt privacy test; full Go suite, targeted race, isolated PostgreSQL store/runmgr/storage-migrate tests, vet, and static build passed locally before commit. A known unrelated TempDir cleanup flake failed once and passed on targeted and serial full replay.
Impact: Add optional same-provider source recheck, verify every included item and evidence body before reuse, gate cross-step outputs, reject unsettled attempts, remove raw scope columns, scrub isolated candidate v34 SQLite/PG schemas, and reject unsafe backups.
Refs: Approved RDM stage6 W6 source-recheck design adjustment r1; W6 independent review.
Why: Compiled workflow critics could resend a prior prompt output after document duty or publication changed across separate model guards.
Evidence: RED cross-guard revocation and retry tests; go test ./... -count=1 and targeted go test -race passed locally before commit.
Impact: Bind materialized prompt bytes to the engine step attempt and responded model receipt; recheck current project sources and epochs before judging, failing closed for unproven or ambiguous output.
Refs: RDM two-trees stage5 W6; stage6 X1 public extension request; W6 independent review P1.
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: 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 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