# Scaffolding V1 — Tranche 1 _2026-09-12. Scaffolding is the controlled need-to-capability system: NEED → DISCOVERY → GAP → REUSE/ACQUIRE/BUILD → IMPACT+PLAN → SAFE IMPLEMENTATION → VERIFICATION → PROVISIONAL USE → TRUST/REVISE/RETIRE → REUSABLE CAPABILITY. Tranche 1 is deliberately narrower: make Rune stop rediscovering how Rune is built every time Rune changes._ ## Tranche 1 contract `scripts/scaffold_projection.py` — a PROJECTION over existing authorities, never a new one: | question | authority projected | |---|---| | what subsystem owns X? | `config/umbrellas.json` (umbrella manifest + henxel-enforced completeness) | | what does X depend on? | AST import graph over `src/rune/*.py` (incl. relative/lazy imports) | | who consumes X? | reverse import edges | | what changes if X changes? | mirrors + `depends_on` umbrellas + consumers | | what proof obligations arise? | unit-test file, canary registry, umbrella gates, suite/lint/henxels | | which are satisfied? | filesystem + registry evidence (static); suite/ratchet/henxels are runtime-check commands | Commands: `component ` · `impact ` · `obligations ` · `all [outfile]`. If the projection disagrees with an authority, fix the authority — never the projection. ## Mechanism audit (2026-09-12, deployed 0.66.22) | mechanism | verdict | basis | |---|---|---| | Umbrella manifest + impact map + propagation gate | KEEP | ownership/impact authority; henxel-enforced completeness; consumed by projection | | Henxels structural contract | KEEP | cross-cutting obligations (silent-handler ratchet, registries, coverage debt) | | Canary registry (`canary_native.MODULES` + per-track canaries) | KEEP | per-subsystem proof obligations; consumed by projection | | CI/deploy contract (required checks, TUI startup canary, atomic promote) | KEEP | deployment proof chain live-proven repeatedly | | Version surfaces + auto-version + semver | KEEP | bump fast lane + push convergence working (0.66.22 earned this session) | | Lint/pyright/coverage ratchets | KEEP | shrinking-baseline gates, all green | | Authority map + dead-subnet ledger (D6) | EVOLVE | static doc today; Scaffolding projections make it derivable; D6 retire-disposition still owed | | Issue reconciliation artifact + checker | KEEP | tracker truth with drift detection | | PL1 experience ledger | KEEP | the trust/revise/retire input for future capability crystallisation | | Intent continuity ledger | KEEP | PART 6 state machine, 7 invariants | | `MIMO_AUTOMATIC_RESUME` / W/R interactive injection | KEEP (bounded) | headless single-flight proven; interactive auto-resume NOT YET SAFE until a supported busy signal exists | | Duplicate authorities risk | REPLACE (avoided) | Scaffolding v1 adds NO new registry — projections only | ## Real-change proof (this tranche) Change: context discovery hit Ollama's `/api/show` with cloud-pinned model names — `400 invalid model name` noise on every cloud task + 8192 misbudget for a 131072-window model (observed live in every PL1 Task A/B run). 1. BEFORE mutation: `scaffold_projection.py impact local_tool_runtime` derived — subsystem `capability`; consumers `rune_operator`; gates: full suite, lint ratchet, henxels, inference+orchestration canaries; unit-test obligation `tests/test_local_tool_runtime.py` (exists). 2. Change made: `is_cloud_pinned` — THE provider-prefix rule, single authority in `openai_compat_transport.py`; consumed by context discovery (new) and transport selection (deduped); red-first regression tests. 3. Obligations tracked: suite 1314 green · lint ratchet PASS · henxels exit 0 · the projection itself caught two gaps mid-flight (relative imports hidden consumers; a broad except biting the lint ratchet) — both fixed at the source the projection pointed to. 4. Deploy: normal release chain → deployed identity verified. ## Maturity (honest) - Projection engine: **UNIT-PROVEN** + proven on one real change. - Not yet: CI integration of `scaffold_projection.py all` (drift detection), capability discovery / gap recognition / reuse-before-build / external acquisition / provisional-trust lifecycle — FOUNDATIONAL ONLY (architecture does not block them; the projection source-list is the extension surface). - Deferred with reasons recorded: none blocked by Tranche 1. --- # Scaffolding V1 — Tranche 2: Construction Substrate (2026-09-13) _Tranche 2 (contract SCAFFOLD-TRANCHE-001) built the construction substrate itself: a shared structural-store primitive, the Project Scaffold layer over it, and durable Construction Contracts — Rune's first build tracked by the system it builds._ ## Architecture src/rune/structural_store.py shared generic primitive — NO Rune constants ↓ ↓ src/rune/spine.py src/rune/scaffold.py (Rune Spine — canonical (Project Scaffold — canonical structural self-model) construction/structural truth about EXTERNAL projects) Authority map (no duplicates): | fact | authority | others | |---|---|---| | Rune's structure | `spine.py` + `store/spine/current.json` | scaffold only references | | external project structure | `scaffold.py` store | Spine holds bridge facts only | | content history / rollback | Git | both reference commits | | coordination (issues/PRs/CI) | Gitea | scaffold stores observations | | why work exists | Task/Intent | contracts reference task ids | Construction Contract = ONE durable object (`contract:`, kind `construction_contract`) with plain `phase`/`status` fields governed by a small legal-transition map (draft → approved → building → verifying → migrating → superseding → closed; failed/abandoned terminal-or-retry). No workflow engine. Resumability = store durability, proven across real process boundaries. ## Mechanics - **Repo binding** (`bind_repo`): forge/owner/name/branch/root/placement as scaffold DATA. No secrets — schema rejects secret-named fields AND every `save()` recursively redacts credential-named keys (defense in depth in the shared core, so Spine inherits it too). - **Scope check** (`check_scope`): changed files vs approved scope paths → green / red / **unknown** (an unscoped contract is never silently green). Out-of-scope change = RED until explicitly amended; amendments recorded, original RED preserved in history. - **Predicted vs observed**: frontier snapshot at approval; observed impact captured at closure from INDEPENDENT evidence (git, tests) — never from re-walking the prediction's own graph. Missed entities become CANDIDATE corrections awaiting evidence. - **Drift**: authority-owned facts that fail re-observation go STALE — never silently fresh, never force-reverted. Reality wins. - **Bridge** (`spine_bridge_entity`): identity + repo surface only. Project internals NEVER leak into Rune Spine (test-enforced). Contract evidence may cite `spine://` URIs — citations are inert on the referenced authority. ## Real proof (this tranche on itself) SCAFFOLD-TRANCHE-001 migrated from its pre-scaffold JSON into the new store, advanced through phases with evidence checkpoints, closed with predicted-vs-observed from git/test evidence, scope check caught the store's own runtime artifacts (RED → explicit amendment → green, history kept), and construction provenance attached into Rune Spine without duplicating authority. A fresh interpreter answers what/why/state/ evidence/changed/next from the store alone — no transcripts. ## Maturity (honest) | component | state | |---|---| | structural_store core | EXERCISED (unit-proven + real use) | | Rune Spine after refactor | LIVE_PROVEN behavior-neutral (68 tests + identical rebuild) | | Project Scaffold | EXERCISED | | Construction Contract | EXERCISED (resumability proven cross-process) | | repo binding (identity model) | UNIT-PROVEN (local git fixture) | | external-repo live proof | BLOCKED ON USER REPO SELECTION | | Scaffolding overall | substrate only — capability-fit discovery, gap decisions, toolchain selection, patterns, maintenance TUI all NOT BUILT (data seams exist) | --- # Scaffolding Tranche 4 — Live Need → Decision → Construction Contract (2026-09-13) _The adoption tranche: a real Need now flows automatically through the Tranche 2/3 mechanisms and produces a governed Construction Contract. The model no longer has to remember the procedure — it is durable Scaffolding._ ## Live flow NEED (reference to Task/Intent — pointer, never a copy) ↓ normalization (gaps recorded, never invented) ↓ structural discovery + fit + resolution (Spine + Project Scaffold) ↓ toolchain decision (existing project toolchain wins) ↓ layout obligations (USER-LOCKED authority inherited) ↓ user-approval gate (material changes require approval; approved bounded work never re-asks) ↓ DecisionTrace (durable, model-independent) ↓ generated Construction Contract → existing build/verify pipeline ## Authority map (unchanged — the path CONNECTS, never duplicates) | authority | owns | |---|---| | Task/Intent | why work exists | | Rune Spine | Rune structural truth | | Project Scaffold | external-project structural/construction truth | | Layout Contract | desired interface constraints (USER-LOCKED = user authority) | | Construction Contract | governed build obligations/history | | Git / Gitea | history / execution | ## Boundary honesty - **ADAPT/research**: the live path records a research ROUTE (TARGETED_EVIDENCE_PROBE / FULL_RESEARCH_PIPELINE) when evidence is insufficient — a seam, NOT an executed pipeline call. No fake integration claimed. - **BUILD_NEW** is never a fallback: insufficient evidence blocks it; normalization gaps block it; merge precedence across authorities requires every consulted authority to agree. - **No second task engine**: one decision function + one trace object. ## Contract-quality repair (Tranche 3 defects) Closure now distinguishes: predicted_existing_affected planned changes to existing entities expected_new entities the build PLANNED to create correctly_predicted predicted AND independently observed predicted_but_unaffected predicted, NOT observed expected_new_observed planned creation happened expected_new_missing planned creation did NOT happen genuinely_unexpected_new observed, planned by neither list Prediction cannot self-certify observation: the observed set comes ONLY from caller evidence (git/tests/build/deploy). Legacy keys (missed/ needless/observed) preserved — old contracts readable without migration. ## Layout-obligation inheritance A change touching a UI component/region/implementation inherits its Layout Contract as a build obligation. USER-LOCKED obligations state that changing placement requires explicit user authorization. Unrelated backend changes inherit nothing. USER-LOCKED drift is never reconciled by editing the contract — code adapts. ## Maturity (honest) - Need intake: EXERCISED (real live proof) - decision orchestration: LIVE-PROVEN for the bounded live flow - capability discovery adoption: EXERCISED - fit/gap adoption: EXERCISED - toolchain adoption: EXERCISED - contract generation: LIVE-PROVEN (one real generated contract) - contract-quality prediction: EXERCISED (repaired semantics, one live closure) - layout-obligation inheritance: UNIT-PROVEN (fixtures) + real TUI binding - Scaffolding overall: adoption path live for one bounded flow — NOT general autonomous construction, NOT universal discovery/toolchain intelligence, NOT Scaffolding complete. --- # Scaffolding Tranche 9 — Release History + Evidence Correction (2026-09-13) _Gitea Releases are now an evidence-derived human-readable history of Rune's evolution. Plus the Tranche 8 builder-evidence correction._ ## Release semantics (audited) | surface | meaning | |---|---| | VERSION | semver in pyproject/init (e.g. 0.66.44) | | TAG | v, created by auto-version at the BUMP commit | | release commit | the auto-bump SHA — NOT necessarily final state | | converged deployed identity | last commit deployed under the same VERSION | Same-version convergence commits (closure/accounting/lock fixes landing and deploying after the bump) are normal; the notes record BOTH the tag commit and the final deployed identity, distinction exposed honestly. ## Mechanism `release_notes.py`: deterministic evidence extraction from governed records (closed contracts, resolved maintenance, contract-quality records) → structured ReleaseNote → Markdown → Gitea API (POST create / PATCH update). Idempotent: publishing twice for a tag UPDATES, never duplicates. Notes are historical documentation — NOT Memory, NOT structural authority. ## T8 evidence correction (§1) The T8 report claimed a close-from-verifying refusal + reactive superseding transition. Durable checkpoints show NO superseding transition and the phase map permits verifying→closed; live output showed first-attempt close success. The claim was RETRACTED with full provenance (original claim, correction, reason, evidence preserved in the contract record) and recorded as process-defect:unsupported-causal-claim. MiMo adoption maturity survives on the SUPPORTED evidence: scope constrained file edits, pattern obligations forced preservation proof, interface-reported observations, fresh resume. ## Maturity Release-note generator: LIVE-PROVEN (real Gitea, 10 releases). Backfill: 0.66.35→0.66.44 carrying historical-backfill provenance. Pre-0.66.35 history: skipped (weak evidence — honest limitation). ## Contract discovery → spine (2026-10-05, #2465 CI correction) The closed construction contract is the authority for discoveries. Spine rebuild reads its observed entities and candidate corrections; it does not claim a correction has been built. Qualified IDs such as `rust-crate:cognition_core` keep their declared kind. Bare file paths, test suites and other unqualified references become `construction-surface:`, never `module`. An observed surface may be PRESENT; a candidate stays DECLARED until independently observed. Existing bad records are migrated with their evidence and edge references intact. This matters: the first write-back mapped bare paths to modules, made 22 false module records and crashed CI on the next rebuild. The per-contract quick-reference markdown is generated from the scaffold store at close; it is a view, not another authority.