scripts/scaffold_projection.py derives per-component cards (subsystem,
dependencies, consumers, mirrors, proof obligations + evidence state) from
the umbrella manifest, canary registry, AST import graph (incl. relative
lazy imports), and tests/ filesystem. No new authority: projections only.
docs/SCAFFOLDING.md records the mechanism audit (KEEP/EVOLVE/REPLACE/RETIRE)
and the real-change proof on the context-discovery fix.
#292/#293/#297 FIXED_VERIFIED (closed with evidence comments — LOCAL_FIX
live-proven by held-out tasks, DESIGN-LITE implemented, task_gate shipped);
#294/#295/#296/#299/#301 DEFERRED_FUTURE (canonical remaining-obligations
list); #300/#315/#316/#284 VALID_OPEN. Resolves the ADAPT-LIVE-complete vs
open-issues tension: the authorized tranche is complete; the backlog never
was its scope. Checker green (72 records). PE-1789102658-0269 SEED→VALIDATED
recorded in the canonical intent state.
ADAPT-1 v2 baseline experiment framing (#315/#316) is historical — the
adaptive pipeline went live without the pre-registered comparison; the
underlying work items (#158, #162) remain open. FINAL-12 (#301) blocked on
PE-0269 substrate. Consistency checker green (72 records).
Merges prototype/openai-compat-transport (7b268e1). The operator's execution
substrate had exactly one transport (OllamaChatTransport, localhost:11434) —
send_task(model='<Provider>/<model>') posted cloud model names to Ollama's
/api/chat and 400'd (observed live: Verboo Code/glm-5.3-flash, 0.2s). The
supported model= override could not execute ANY cloud provider.
OpenAICompatTransport speaks the OpenAI wire format (/chat/completions) and
returns Ollama-shaped responses (LocalToolRuntime loop unchanged). Selection
is deterministic on routing_mode=='cloud' — no router, ladder, or escalation
change. Provider config resolved from the same source of truth the mimo CLI
uses (mimocode.jsonc baseURL + auth.json key).
Translation unit tests (6) + live smoke against the real Verboo API
(TRANSPORT-SMOKE-OK). Umbrella manifest updated. Stray experiment files
removed. 1295 tests green; ratchet 352/80; henxels clean.
- docs/GITEA_ISSUE_RECONCILIATION.md: human-readable projection (states,
bug-label audit with per-issue evidence, open-issue reconciliation table)
- docs/gitea_issue_reconciliation.json: machine-readable authority
(72 records; all open issues covered; single live defect #324).
Placed under docs/ because state/ is the gitignored runtime dir.
- scripts/gitea_reconciliation_check.py: deterministic drift check —
state/label/coverage invariants; bug-label invariant applies to OPEN
issues (closed labels are historical); exit 1 with itemized drift.
- Part K audit: closed#139#157 (FIXED_VERIFIED with evidence comments);
bug labels removed from #204#145#126#37#16 (not defects) and the
stuck label on closed#314. Open bug-labelled: 8 → 1.
- 1289 tests green; ratchet 352/80; henxels clean.
Part A-J: 15 issues closed (HISTORICAL_EVIDENCE/SUPERSEDED/ACCEPTED_LIMITATION)
with evidence. Bug label cleaned (24→8 open). #259/#258 updated to current
architecture. Remote tracking fixed (master tracks gitea/master). PL1 metrics
corrected to NOT_YET_MEASURABLE where evidence doesn't support numbers.
D7 recorded as ROOT_CAUSE_UNKNOWN_DEFERRED. Clean recursion experiment:
version converges (0.66.8 stable) but 5 duplicate bump commits per logical
change (queue-drain artifact). PL1 held-out task 1: LOCAL_FIX route correct,
task genuinely running on deployed 3B model (slow but alive).
Pre-PL1 closure Part A (handoff 2026-09-10):
1. Presentation: CLI prints '⏳ Research required' with task/status for
research_required dispositions — never '✗ Task failed' (the ✗ path
remains for genuine failures). Legacy migration map accepts
research_required statuses from pre-cutover operator.json.
2. Terminal-outcome semantics corrected: task.outcome = terminal result
ONLY. The research_required path no longer emits a terminal outcome —
the routing decision lives in route.jsonl (INITIAL_ROUTE, the
authoritative routing record) referenced by route_ref; task.outcome
fires at the genuine terminal transition when the research consumer
closes the task. Verified: zero task.outcome events for the
research task in the durable journal.
3. docs/RUNE_CANONICAL_INTENT_STATE.md: canonical intent artifact —
primary intent, detour record, return conditions, deferred defects
(D1 memory FTS ghosts, D2 hook deployment ownership, D3 ephemeral
fire-trace, D4 recall_uplift provisional, D5 cloud telemetry theater,
D6 dead subnet disposition), parked innovations, supersessions, the
full ADAPT status matrix, and the next-step recommendation.
Epic #284 carries the reconciliation comment (id 3873).
1227 tests pass; ratchet 353/80; henxels clean.
Per-stage cognition metrics (elapsed where recorded, tool calls, queries,
sources read, failures), research quality (sources/contradictions/
limitations), adversarial outcomes (attacks/survivors/rejected/mitigations/
kill-tests/dispositions), old-process baseline (300s foreground sleeps,
model-claimed receipts, no read provenance), and quality outcomes
(architectural mistakes prevented per run, implementation ambiguity
reduction, rework loops).
Honest data note: stage elapsed_s only recorded where the last artifact
write set it (reconciliation zeroed earlier stages on #161) — per-stage
timing persistence is a TUNE recommendation, not a measurement blocker.
RP11/#274 step 1 — consolidate to ONE canonical authority. The RSC0-9
research scripts on master (DEFINE/OUTWARD_DISCOVERY/OUTWARD_READING stage
model) are superseded by the canonical pipeline proven through RP2-RP10
(epic #257, children #264-#273): ISSUE→INWARD→OUTWARD→APPLICABILITY→
conditional INNOVATION→ADVERSARIAL(disposition)→SYNTHESIS→QUALIFY.
Zero conflicts vs current master; the #161 harness (PR #279) is preserved.
The two lint-job henxel failures on PR #279 were pre-existing master debt
surfaced by the FIRST pull_request CI run in this repo's history (master
pushes only run merge-green):
1. umbrella manifest phantom check: umbrella_impact.module_of() routes
subpackage modules by stem (orchestration/retrieval_benchmark.py ->
'retrieval_benchmark') but the manifest completeness henxel's 'actual'
set only globbed TOP-LEVEL src/rune/*.py — so a legitimately-mapped
subpackage module looked phantom. Fix: phantom direction now checks
existence across the whole tree (rglob); the 'unmapped' direction
preserves the historical top-level contract unchanged. Test mirrored.
2. workflow registry: research-dispatcher.yml had no registry entry.
Registered as SUPERSEDED-legacy (canonical pipeline replaced it; labels
stripped 2026-09-08; retirement is RP11/#274's job).
Also re-baselined lint-baseline.json to measured master reality (82/356 —
ratchet doctrine preserved: floor may only shrink) and resynced the CI
dependency lock (platformdirs 4.11.7 -> 4.11.8 upstream drift).
Full suite: 1069 passed. henxels check --all: 0 failures locally.
THE HEAVY RUNNER IS THE DESKTOP PC, NOT THE PI.
- scripts/runner_evidence.py: runtime execution evidence capture (hostname,
runner identity from env, labels, execution class, stage, process id,
issue, research process id, timestamp) — identity captured at runtime,
never inferred from configuration alone
- Deterministic placement gate (validate_placement): desktop-heavy stage
executed on Pi → PLACEMENT_REJECTED; hostname checked too (cannot hide
the Pi behind a desktop runner name); missing evidence fields rejected;
unverified runners rejected (no silent fallback); pi-lightweight forge
operations (metadata, labels, eligibility) explicitly allowed
- Placement gate wired into StageExecutor.execute(): every stage result
embeds runner_evidence; Pi execution fails the tree and cannot count
as acceptance
- docs/RESEARCH_CODE_CLASSIFICATION.md: aggressive detection, conservative
classification (CURRENT/SUPERSEDED/COMPATIBILITY/TEST_FIXTURE/
UNKNOWN_PURPOSE); NO deletion in #265 — retirement is RP11 after RP10
proof; run_full_research() self-walk + --watch poll classified SUPERSEDED;
tui-restart-pending marked SUPERSEDED CANDIDATE (verify before removal)
Acceptance: canonical order PASS; conditional INNOVATION PASS; ISSUE
deterministic PASS; earliest-stage refinement PASS; heavy-runner requirement
encoded PASS; Pi rejection PASS; runtime identity/hostname/labels captured
PASS; stage/run/process identity PASS; Gitea stage authority preserved
(one-stage executor unchanged) PASS; no self-walking production loop in the
canonical path PASS; no premature retirement PASS.
125 tests pass, ruff clean. Pre-existing henxels digest env failure unchanged.
## Bumps are bookkeeping, not reviewable code
auto-version now commits the 5 version surfaces DIRECTLY to master via the
contents API — no bump branch, no bump PR, no bump CI wave, no staleness
cascade, no concurrent-bump race (230/231 proved it). In-memory gate: all 5
surfaces must agree on the new version BEFORE any commit (TUI footer renders
rune.__version__ at call time — the displayed version IS __init__.py).
Commit messages carry the provenance link to the earning PR.
## Robot: transient 405 'Please try again later' retried (3x backoff)
Forge mergeability recompute was failing the robot on every merge burst —
transient is 'not ready', not a refusal. Fail-loud applies to refusals and
to exhausted retries (both paths tested).
## Future-proofing: docs/pipeline-extension-guide.md
Placement decision tree (merge-deciding → required-checks; work → narrowest
event; bookkeeping → direct commit), event-delivery quirk table (every entry
learned by a live failure), per-type checklists, the three invariants.
Registry links it. Any future agent reads the guide BEFORE adding a process.
Baseline {BLE001: 351, S110: 79} (was 455/117): 103 handlers in
memory_store.py, warm_router.py, curator.py, tool_executor.py now log
tracebacks via logger.debug(.., exc_info=True) or carry reasoned
# noqa: BLE001 (warm_router P0-06 record_failure paths). Ledger table
regenerated from the live tree; Completion Record appended to the plan.
Blast radius at ab4dbf8: BLE001 455 / S110 117 over src/ shared/ scripts/
(T201 1625 measured, not enforced). Enforcement mirrors the pyright ratchet:
scripts/lint_ratchet.py + lint-baseline.json, wired as an append-only step in
the ci.yml lint job. Contract tests red->green in
tests/test_ci_lint_contract.py; debt ledger docs/silent-handler-debt.md.
Seeds the pipeline with the REAL #192 CONVERGED case-mismatch payload: the
safety-net convergence step exported Python-cased True/False from
json.load while the steps compared env.CONVERGED == 'false' — both
conditionals unreachable (discharged on the release-safety-net branch,
public in PR #211's diff). Captured via the pipeline itself
(--class env-case-mismatch --source ci, 0 redactions — the payload is
already public and credential-free). The generated regression test asserts
the boolean-export checker still FLAGS the recorded payload
(checker_expectation: flags), so a recurrence of the class fails CI.
Manifest gains checker_expectation: capture records whether the class's
checker raises on the payload ('flags' — the raise IS the recurrence alarm)
or must stay quiet ('passes'); the generated tests enforce the recorded
expectation, so a checker that stops catching its recorded defect rots the
suite red.
Docs: bugfix-contract §10 gains the operational capture step + explicit
trivial-bug exemption list; README dev section points at the pipeline;
tests/fixtures/production/README.md documents the flow.
Henxels: capture_failure.py required in scripts/; production fixtures
governed (manifest.json + README.md required); payload.json and
manifest.json travel together (changed_with both directions, verified to
bite on a payload-only staged change).