Migrate 22 malformed contract-discovery IDs to construction-surface, retain evidence/edges, keep candidates DECLARED, unify cold/warm language projection, and refresh the pinned aiohttp lock. Red regression tests precede the fix; local full suite 2301 passed, spine canaries 19/19 and 21/21.
14 KiB
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 <module> · impact <module> · obligations <module> ·
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).
- BEFORE mutation:
scaffold_projection.py impact local_tool_runtimederived — subsystemcapability; consumersrune_operator; gates: full suite, lint ratchet, henxels, inference+orchestration canaries; unit-test obligationtests/test_local_tool_runtime.py(exists). - Change made:
is_cloud_pinned— THE provider-prefix rule, single authority inopenai_compat_transport.py; consumed by context discovery (new) and transport selection (deduped); red-first regression tests. - 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.
- 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:<id>, 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 everysave()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 citespine://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:<reference>, 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.