Compare commits

...
13 Commits
Author SHA1 Message Date
conductor e3d0560ed5 chore(release): auto-bump version to 0.239.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 13s
CI Pipeline / go-surface (push) Failing after 16s
Auto-version and Release / release (push) Successful in 31s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Failing after 40s
CI Pipeline / lint (push) Failing after 57s
CI Pipeline / canary (push) Failing after 2m3s
CI Pipeline / unit-tests (push) Failing after 16m29s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 4s
Promotion record: (unknown)
2026-10-12 15:42:56 +01:00
Nick 4f0556fe16 chore(store): close curator dichotomy contract BUILDER-2026-10-12T12:25:33Z-a87985-factory-wave (parity 03ef8132, phase B 89b691b2)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / rust-surface (push) Failing after 12s
CI Pipeline / go-surface (push) Failing after 15s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / type-check (push) Canceled after 21s
Auto-version and Release / release (push) Canceled after 31s
CI Pipeline / canary (push) Canceled after 31s
CI Pipeline / lint (push) Canceled after 34s
CI Pipeline / unit-tests (push) Canceled after 35s
deploy / deploy (push) Canceled after 26s
2026-10-12 15:42:26 +01:00
Nick f61a4a3fa3 chore(store): register curator dichotomy contract BUILDER-2026-10-12T12:25:33Z-a87985-factory-wave (verifying) 2026-10-12 15:41:42 +01:00
Nick 89b691b210 refactor(curator): Phase B language-advantage pass — dichotomy wave
Allocation-discipline pass over the curator kernel, pinned by the unchanged
frozen-truth battery (truth.json byte-identical to the parity commit, green
throughout):

- NewOp: pre-sized op-row builder with the six canonical keys in oracle
  order replaces inline map literals on the op-generation paths.
- AppendJournal: append-in-place journal growth (no intermediate slices).
- JoinLines: single-pass body rebuild for the ADD path.
- OpKeys documents the observable op-row envelope.

Live parity re-verified post-pass: battery 162/162 + phaseb 3/3.
2026-10-12 15:35:46 +01:00
Nick 03ef8132a2 feat(curator): port to FULL Go — dichotomy wave
DICHOTOMY VERDICT: GO (Reactive → Go per store/rebase/classification.json).
Name-preserving full-module port of src/rune/curator.py (43 fns) into
src/go/curator/ (package main, modernc.org/sqlite pure-Go store seam).

Truth: scripts/gen_curator_truth.py freezes 162 rows from the live oracle
(paths isolated, dependency cores pinned RUNE_*_CORE=python, clock frozen,
subprocess faked, embed tabled, aaak/memory_store blocked, drift-gate/audit/
drift-ledger seams injected, deep-copied inputs, per-row setup seeds).
Battery truth_test.go replays every row verbatim: 162/162 + live
re-verified + generator deterministic (byte-identical re-freeze).

Python oracle untouched (no facade delegation — strangler surface stays
Python by design); Python contract tests green.
2026-10-12 15:35:46 +01:00
Nick e29cc5ee51 chore(store): close drift_ledger dichotomy contract BUILDER-2026-10-12T13:54:01Z-950331-factory-wave (parity c0ec3135, phase B 62e47b38)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 16s
CI Pipeline / gitea-offline (push) Successful in 16s
Auto-version and Release / release (push) Successful in 31s
CI Pipeline / type-check (push) Failing after 44s
CI Pipeline / lint (push) Failing after 1m2s
CI Pipeline / canary (push) Failing after 2m13s
deploy / deploy (push) Failing after 15m33s
CI Pipeline / unit-tests (push) Failing after 16m40s
CI Pipeline / required-checks (push) Failing after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 4s
2026-10-12 14:55:40 +01:00
Nick 8ed117abe2 chore(store): close construction_patterns_builtin dichotomy contract BUILDER-2026-10-12T13:29:58Z-e5c619-factory-wave (parity 4649df1c, phase B b50e8553)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 18s
Auto-version and Release / release (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Failing after 49s
CI Pipeline / lint (push) Failing after 1m6s
CI Pipeline / canary (push) Failing after 2m17s
deploy / deploy (push) Failing after 15m34s
CI Pipeline / unit-tests (push) Failing after 16m48s
CI Pipeline / required-checks (push) Failing after 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 4s
2026-10-12 14:37:52 +01:00
conductor 633af06e8a chore(release): auto-bump version to 0.238.0 — earned by # (minor: converged release (push-to-master bump))
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 16s
Auto-version and Release / release (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 22s
CI Pipeline / type-check (push) Failing after 45s
CI Pipeline / lint (push) Failing after 1m2s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / unit-tests (push) Canceled after 2m0s
CI Pipeline / canary (push) Canceled after 2m0s
deploy / deploy (push) Canceled after 1m51s
Promotion record: (unknown)
2026-10-12 14:35:45 +01:00
Nick 62e47b3812 refactor(drift_ledger): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 20s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
Auto-version and Release / release (push) Canceled after 36s
CI Pipeline / gitea-offline (push) Canceled after 18s
CI Pipeline / lint (push) Canceled after 36s
CI Pipeline / type-check (push) Canceled after 22s
CI Pipeline / unit-tests (push) Canceled after 35s
CI Pipeline / canary (push) Canceled after 36s
deploy / deploy (push) Canceled after 39s
Language-advantage pass on the drift_ledger Rust kernel (battery green
throughout, live parity re-verified 87/87 byte-identical after rebuild):
- Block lattice is a real enum (Constitution..Project) with as_str/of_name/
  limit matches — the constitution's stricter limit and its ANY-content-
  change strict check are exhaustive matches, not string compares; the
  per-block alert loop and snapshot assembly iterate BlockLabel::ALL.
- check_alerts is iterator-composed: BlockLabel::ALL.filter_map over the
  baseline decision, emitting alerts via then(..) — the python loop's
  anchor-vs-snapshot branch stays a plain match.
- diff_blocks is zero-copy iterator composition (filter_map + take(6)/
  take(3) replaces the manual capped pushes); the whitespace-significance
  filter is one shared fn item over &str slices.
- All keyword tables and contents borrow (&str / &Value) end-to-end — no
  per-block copying or lowering.
- Frozen DL truth replay untouched and VERBATIM (branch_battery.rs replays
  the same 87-case oracle truth).
2026-10-12 14:33:28 +01:00
Nick c0ec3135c6 feat(drift_ledger): port remaining cores to FULL Rust — dichotomy wave
DICHOTOMY VERDICT (dichotomy law, #2479 tranche): drift_ledger's
deterministic cores complete their Rust port in src/rust/drift_ledger —
the check() alert loop (anchor-vs-snapshot baseline, the constitution's
ANY-content-change strict check, max(prev_size,1) floor, pct/limit
round-3 with Python ties-to-even semantics, root-cause diff per alert),
snapshot/anchor entry assembly (size = the oracle's len() CHARACTER count),
the auto-fix routing and the retroactive fix() gate. SQLite store IO
(read_block/restore_topic) and file IO (load/save ledger, journal,
surface_alert) stay facade seams by design — the clock travels in the
doc envelope.

Wiring: dl_loader.py grows dl_ledger_path/dl_snapshot_entry/
dl_anchor_record/dl_check_alerts/dl_fix_decision (doc-envelope FFI,
oracle-verbatim dict unwrap, free via capability_scoring cs_free_string
— no free symbol re-export); facade delegation in drift_ledger.py with
the RUNE_DL_CORE=python pin and byte-identical python fallbacks.

Truth: scripts/gen_drift_ledger_truth.py freezes 87 cases from the live
oracle across EVERY public function and branch (sha, diff caps/truncation,
ledger path joins, load/save ledger bytes, store read filters and order,
journal/surface_alert file formats, snapshot/anchor/check/auto_fix/fix
end-to-end flows with frozen clock, restore_topic directive preservation
+ priority map, handle_hook, main CLI exits, and the kernel-level
k_snapshot/k_anchor/k_alerts/k_auto_fix/k_fix groups) — battery 8 tests
replay it VERBATIM; live parity 87/87 byte-identical under RUNE_DL_CORE=auto.

Audit instrument fixes (bug-first, with proof): module_to_keys now maps
hyphenated legacy twins to their underscore implementation (drift-ledger.py
— the same ledger — was scored NOT TOUCHED against an empty corpus) and
curator gains its curator-core alias (a FULL Go port since a95c6ce1 was
invisible to the audit). Honest post-fix queue: curator 40/43 FULL,
drift-ledger 14/14 FULL, drift_ledger 20/22 FULL; function-level
1020/2781 (37%), FULL 36 PARTIAL 93 NOT TOUCHED 108.
2026-10-12 14:33:28 +01:00
conductor 622cceb2f9 chore(release): auto-bump version to 0.237.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 12s
CI Pipeline / go-surface (push) Failing after 15s
Auto-version and Release / release (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / type-check (push) Failing after 44s
CI Pipeline / lint (push) Failing after 58s
CI Pipeline / canary (push) Failing after 2m6s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / unit-tests (push) Canceled after 9m6s
Promotion record: (unknown)
2026-10-12 14:25:57 +01:00
Nick b50e8553d7 refactor(construction_patterns_builtin): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / rust-surface (push) Failing after 13s
CI Pipeline / go-surface (push) Failing after 15s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
Auto-version and Release / release (push) Canceled after 28s
deploy / deploy (push) Canceled after 15s
CI Pipeline / type-check (push) Canceled after 21s
CI Pipeline / canary (push) Canceled after 32s
CI Pipeline / unit-tests (push) Canceled after 33s
CI Pipeline / lint (push) Canceled after 34s
Typed registry: the frozen oracle docs parse once into BuiltinPattern
values (pattern_id/revision extracted, doc kept oracle-shaped); the FFI
re-emits from the typed value instead of re-plumbing raw Json. Miss-
before-revision-check oracle ordering is now explicit in the typed
lookup. Registry revision pinned in its own OnceLock.

Truth extended (+2 cases from the live oracle, RUNE_CPB_CORE=python
pinned): unknown id WITH a revision -> None (miss is decided before the
revision check — oracle order) and the revision=0 boundary on a real
pattern (ValueError, exact message). Branch battery now 19 cases,
replayed verbatim, green throughout; clippy 0; live parity 16/16.
2026-10-12 14:25:29 +01:00
Nick 4649df1ccc feat(construction_patterns_builtin): port to FULL Rust — dichotomy wave
RUST verdict (dichotomy law, #2479 tranche): construction_patterns_
builtin.py's registry surface is ported to src/rust/construction_
patterns_builtin — the four builtin pattern docs (capability-module-
adaptation, release-deployment-change, ui-tui-structural-change, store-
schema-evolution) served verbatim from frozen_cpb_patterns.json (deep-
copied from the live oracle's to_dict() output incl. __init__-sorted
provenance order), PATTERN_REGISTRY_REVISION, and get_pattern's full
branch set (hit per pattern_id, unknown/empty-id miss -> None, revision
match passthrough, revision mismatch with the oracle's exact ValueError
message).

Wiring: cpb_loader.py ctypes loader mirroring cs_loader.py/broker_
loader.py (doc-envelope FFI cpb_registry_revision/cpb_patterns/cpb_
get_pattern, free via capability_scoring cs_free_string — never
re-exported, CPB_RUST_LIB override), facade delegation in construction_
patterns_builtin.get_pattern with RUNE_CPB_CORE=python fallback pin and
strangler fallback to the Python registry when the .so is absent.

Truth: frozen_cpb_truth.json — 17 cases from the live oracle (deep-
copied inputs, RUNE_CPB_CORE=python pinned, every public fn and every
branch incl. all four patterns and the revision-mismatch raise),
replayed VERBATIM by the in-crate cfg(test) branch battery. Live parity
check (scripts/check_cpb_parity.py): 16/16 facade + kernel-surface
cases. clippy: 0 warnings. Consumer suites green (test_construction_
pattern 30, project_build_lifecycle, provider_ownership).

Audit fix (fix-first with proof): dichotomy_audit.py now aliases
curator -> curator-core (ported FULL Go in a95c6ce1 but mislabeled NOT
TOUCHED — the alias was missing from module_to_keys). Regenerated
audit: curator 40/43 FULL; function-level completion 34% -> 36%.
2026-10-12 14:25:29 +01:00
84 changed files with 34678 additions and 351 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.236.0**
**Current release: v0.239.0**
**Rune is a persistent personal agent designed to accumulate experience, develop reusable competence, and remain recognisably the same agent even when its underlying foundation model changes.**
+33 -23
View File
@@ -2,56 +2,47 @@
_Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL only when 80%+ of its Python functions have name-preserving counterparts in the Go/Rust implementation — directories without the functions are facades and count as NOT TOUCHED._
**Function-level completion: 32%** (838/2627 runtime functions matched)
**Function-level completion: 37%** (1020/2781 runtime functions matched)
| Status | Modules | Lines | Meaning |
|---|---|---|---|
| FULL | 25 | 8218 | 80%+ of functions ported |
| PARTIAL | 89 | 44507 | 20–80% — real logic exists, gaps named below |
| NOT TOUCHED | 113 | 22686 | no name-preserving implementation |
| Total runtime | 227 | 75411 | |
| FULL | 36 | 13024 | 80%+ of functions ported |
| PARTIAL | 93 | 45658 | 20–80% — real logic exists, gaps named below |
| NOT TOUCHED | 108 | 19178 | no name-preserving implementation |
| Total runtime | 237 | 77860 | |
## NOT TOUCHED — the port queue, in priority order (largest first)
| Module | Lines | Fns | Side |
|---|---|---|---|
| rune_tui | 4170 | 159 | TUI-LAST |
| curator | 1838 | 43 | GO |
| canary_audit_ledger | 541 | 2 | TEST-INFRA |
| tui_validator | 514 | 13 | TUI-LAST |
| worthiness | 411 | 13 | unclassified |
| chat_bubble | 401 | 12 | TUI-LAST |
| drift-ledger | 355 | 14 | unclassified |
| pc_loader | 337 | 22 | unclassified |
| canary_rune_serve | 329 | 13 | TEST-INFRA |
| canary_p1_07 | 324 | 10 | TEST-INFRA |
| canary_p0_07 | 310 | 10 | TEST-INFRA |
| canary_p1_01 | 294 | 12 | TEST-INFRA |
| outcome_ledger | 286 | 7 | RUST |
| time_awareness | 286 | 14 | RUST |
| canary_p1_06 | 280 | 7 | TEST-INFRA |
| canary_p1_03 | 271 | 9 | TEST-INFRA |
| canary_gitea_automation | 263 | 3 | TEST-INFRA |
| canary_p1_02 | 253 | 10 | TEST-INFRA |
| construction_patterns_builtin | 249 | 1 | RUST |
| canary_full_system | 248 | 2 | TEST-INFRA |
| task_gate | 235 | 8 | RUST |
| sm_loader | 239 | 14 | unclassified |
| canary_native | 231 | 3 | TEST-INFRA |
| lexicon_evolution | 229 | 7 | unclassified |
| openai_compat_transport | 227 | 9 | GO |
| shard_manager | 223 | 9 | RUST |
| spine_language | 218 | 5 | RUST |
| canary_p0_04 | 207 | 8 | TEST-INFRA |
| wr_loader | 206 | 20 | unclassified |
| cc_loader | 205 | 28 | RUST |
| forge_client | 203 | 18 | GO |
| canary_context_broker | 199 | 10 | TEST-INFRA |
| canary_p0_05 | 199 | 13 | TEST-INFRA |
| cl_loader | 196 | 20 | unclassified |
| testing_mode | 196 | 12 | RUST |
| grading | 193 | 3 | unclassified |
| canary_spine_meta | 192 | 7 | TEST-INFRA |
| message_graph | 187 | 12 | unclassified |
| ffi_query_memory_smoke | 183 | 5 | RUST |
| tm_loader | 178 | 13 | unclassified |
| smod_loader | 175 | 10 | unclassified |
| behaviour_ledger | 174 | 12 | RUST |
| canary_tui_transport | 174 | 7 | TEST-INFRA |
| sr_loader | 173 | 18 | unclassified |
@@ -60,6 +51,7 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| ms_loader | 163 | 16 | RUST |
| canary_gitea_pipeline | 159 | 2 | TEST-INFRA |
| dc_loader | 158 | 13 | unclassified |
| mg_loader | 152 | 14 | unclassified |
| mse_loader | 152 | 12 | unclassified |
| bb_loader | 151 | 14 | unclassified |
| forge | 146 | 11 | GO |
@@ -72,32 +64,36 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| ps_loader | 136 | 13 | unclassified |
| verification_layer | 136 | 11 | RUST |
| tui_backlog | 125 | 5 | TUI-LAST |
| le_loader | 124 | 10 | unclassified |
| state_checkpoint | 123 | 8 | unclassified |
| cp_loader | 122 | 9 | unclassified |
| dl_loader | 118 | 12 | unclassified |
| drift_resume | 118 | 3 | RUST |
| tl_loader | 118 | 9 | unclassified |
| bh_loader | 117 | 9 | unclassified |
| tg_loader | 117 | 7 | unclassified |
| canary_conversation_state | 115 | 2 | TEST-INFRA |
| contracts_loader | 112 | 8 | unclassified |
| gr_loader | 112 | 8 | unclassified |
| canary_query_memory | 111 | 2 | TEST-INFRA |
| tui_transport | 108 | 10 | TUI-LAST |
| canary_unbounded | 105 | 2 | TEST-INFRA |
| message_widgets | 104 | 6 | TUI-LAST |
| self_modify | 102 | 7 | unclassified |
| ct_loader | 103 | 8 | unclassified |
| sc_loader | 96 | 6 | RUST |
| inference_paths | 95 | 2 | unclassified |
| mutation_guards | 94 | 2 | unclassified |
| concept_topology | 90 | 7 | unclassified |
| cs_loader | 90 | 5 | RUST |
| ci_loader | 89 | 4 | unclassified |
| tc_loader | 88 | 5 | RUST |
| broker_loader | 86 | 5 | unclassified |
| canary_schema_migration | 86 | 1 | TEST-INFRA |
| ss_loader | 86 | 7 | unclassified |
| ol_loader | 85 | 4 | unclassified |
| to_loader | 85 | 4 | unclassified |
| ta_loader | 84 | 4 | unclassified |
| mems_loader | 83 | 5 | RUST |
| cm_loader | 82 | 4 | unclassified |
| dl_loader | 77 | 5 | unclassified |
| lc_loader | 75 | 5 | unclassified |
| cd_loader | 72 | 4 | unclassified |
| execution_trace | 71 | 4 | unclassified |
@@ -109,7 +105,6 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| cb_loader | 64 | 3 | unclassified |
| skill_compiler | 64 | 4 | unclassified |
| sg_loader | 63 | 4 | unclassified |
| sm_loader | 63 | 4 | unclassified |
| meaningful_events | 61 | 3 | unclassified |
| outcome_utility | 59 | 4 | unclassified |
| memory_types | 54 | 2 | unclassified |
@@ -166,17 +161,19 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| claim_audit | 484 | 4/14 | _get_warm_neuron_store, reframe, _graph_has, _warm_has, verify, journal |
| drift_core | 471 | 4/14 | _ms_core, _now_iso, _py_check_promotion_eligibility, promote_entry, compute_fama, compute_drift_velocity |
| model_profiles | 438 | 5/15 | get_profile_path, load_profile, save_profile, build_profile_from_ollama, scan_all_models, get_or_create_profile |
| testing_mode | 362 | 11/21 | _now, _tm_core, _py_default_state, _py_next_item, _py_record, _py_note_blocker |
| tier_manager | 262 | 5/15 | _cc_probe, cc_loader_pin, _py_core_now, _py_get_tier, _py_promote, _py_demote |
| witness | 446 | 8/18 | _ctx_budget, _now, _cc_probe, cc_loader_pin, _py_extract_topic, _py_detect_signals |
| drift_compression | 307 | 3/12 | _py_get_compression_ratio, _py_compress_text, _py_compress_entry, _py_should_warn, _py_warn_before_compress, get_compression_ratio |
| drift_ledger | 471 | 7/16 | ledger_path, read_block, load_ledger, save_ledger, surface_alert, snapshot |
| scaffold | 868 | 22/31 | init, set_prd, add_maintenance_item, bind_repo, observe_repo, repo_state_from_git |
| behavior | 537 | 6/14 | _bh_core, connect, _correction_matches_python, _habit_matches_python, _reinforce_rust, _reinforce_python |
| builder_bridge | 326 | 3/11 | _construction_store, _active_construction_lines, _default_selector, _cached_memory, _get_selector, _retrieve_memory |
| time_awareness | 402 | 12/20 | _clock_args, _ta_core, get_time_awareness, to_dict, _to_state, _apply_state |
| construction_pattern | 547 | 7/14 | _core, _need_dict, _surface_text, _path_matches, _entity_matches, _obligation_when_hit |
| contracts | 743 | 4/11 | _ct_core, _resolve_and_project, _run_contract_python, capture_signatures, save_signatures, load_signatures |
| graph_memory | 474 | 2/9 | now_iso, connect, resolve_entity, add_edge, query, stats |
| intent_continuity | 168 | 2/9 | to_dict, from_dict, _load, save, create_detour, resolve_detour |
| lexicon_evolution | 304 | 7/14 | _le_core, _py_content_words, _py_distinctive_terms, _py_shared_distinctive, _py_coherence, _py_grounded |
| pins | 282 | 5/12 | _store_path, _save, _detail_blob, unpin, _py_pin_recall, list_pins |
| voice_hybrid | 427 | 3/10 | _connect, _load_growth, _save_growth, source_profiles, always, grow |
| voice_sync | 299 | 3/10 | _now, get_delivery_register_from_db, get_delivery_register, update_rune_md, check_sync, handle_hook |
@@ -197,6 +194,7 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| construction_commands | 268 | 1/5 | _refuse, _validate, _accept, dispatch |
| drift_cache | 357 | 12/16 | _dc_core, _py_compute_priority, _py_qualifies_for_cache, main |
| drift_observability | 399 | 5/9 | _do_core, main, _load_alerts, _save_alerts |
| grading | 253 | 3/7 | _gr_core, _py_affirm_rule, _py_grade_fact, _py_tier_of |
| layout_contract | 336 | 2/6 | define_region, bind_component, amend_layout_contract, record_layout_observation |
| model_connect | 471 | 7/11 | _ctx_budget, _now, _get_cloud_models, handle_hook |
| prompt_sync | 487 | 11/15 | _now, _rust_available, get_store, main |
@@ -204,6 +202,7 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| self_improve | 246 | 1/5 | _now, suggest_improvements, handle_hook, main |
| stage_guards | 303 | 7/11 | _py_liveness_canary, _py_reconcile, to_dict, chk |
| subconscious_pass | 187 | 1/5 | main, _extract_topic, save_reflection, get_recent_findings |
| task_gate | 301 | 5/9 | _tg_core, _now, list_gates, main |
| construction_activation | 237 | 1/4 | _scaffold_for, _auto_structural_awareness, dispatch_from_decision |
| construction_mode | 412 | 2/5 | _contains_any, to_dict, from_dict |
| construction_projection | 254 | 1/4 | _contract_entity, validate, write_mini_doc |
@@ -227,11 +226,14 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| Module | Lines | Fns | Side |
|---|---|---|---|
| curator | 1838 | 40/43 | GO |
| abstraction | 656 | 17/17 | GO |
| system_registry | 603 | 14/16 | RUST |
| construction_intent | 580 | 13/16 | RUST |
| capability_ledger | 571 | 18/19 | RUST |
| drift_ledger | 548 | 20/22 | RUST |
| event_wait | 518 | 14/14 | GO |
| worthiness | 469 | 12/14 | unclassified |
| tool_protocol | 461 | 22/27 | GO |
| auto_tasks | 460 | 14/14 | GO |
| programme_continuation | 458 | 11/12 | RUST |
@@ -240,12 +242,20 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| model_routing | 432 | 13/13 | GO |
| build_basis | 375 | 11/13 | RUST |
| attention_capsule | 365 | 6/7 | RUST |
| drift-ledger | 355 | 14/14 | unclassified |
| outcome_ledger | 318 | 7/8 | RUST |
| message_queue | 316 | 13/13 | GO |
| message_graph | 295 | 12/13 | unclassified |
| toolchain | 295 | 5/6 | RUST |
| shard_manager | 276 | 9/10 | RUST |
| auto_context | 273 | 8/8 | GO |
| openai_compat_transport | 227 | 9/9 | GO |
| evidence_probe | 213 | 9/9 | GO |
| forge_client | 203 | 18/18 | GO |
| self_modify | 149 | 7/8 | unclassified |
| recall_uplift | 141 | 1/1 | RUST |
| rune_spinner | 130 | 4/5 | RUST |
| concept_topology | 128 | 7/8 | unclassified |
| wait_guard | 116 | 1/1 | RUST |
| failure_recovery | 108 | 1/1 | RUST |
| programme_gates | 85 | 4/5 | RUST |
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rune"
version = "0.236.0"
version = "0.239.0"
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
requires-python = ">=3.10"
+78
View File
@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""Live parity check: construction_patterns_builtin facade on the Rust core
vs the Python-pinned oracle (RUNE_CPB_CORE=python). Exercises every public
surface branch: BUILTIN_PATTERNS docs, registry revision, get_pattern hit
per pattern, unknown-id miss, revision match, revision mismatch (exact
exception type + message), revision=None. Deep-copies inputs per case.
"""
import copy
import json
import os
import sys
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(REPO, "src"))
import rune.construction_patterns_builtin as cpb # noqa: E402
PIDS = [p.pattern_id for p in cpb.BUILTIN_PATTERNS]
cases = []
for pid in PIDS:
cases.append(("get_pattern", {"pattern_id": pid, "revision": None}))
rev = cpb.get_pattern(pid).revision
cases.append(("get_pattern", {"pattern_id": pid, "revision": rev}))
cases.append(("get_pattern", {"pattern_id": pid, "revision": rev + 1}))
cases += [
("get_pattern", {"pattern_id": "no-such-pattern", "revision": None}),
("get_pattern", {"pattern_id": "", "revision": None}),
("registry_revision", {}),
]
def run(pin):
os.environ["RUNE_CPB_CORE"] = "python" if pin else "auto"
out = []
for fn, args in cases:
try:
if fn == "get_pattern":
got = cpb.get_pattern(**copy.deepcopy(args))
out.append(("ok", None if got is None else got.to_dict()))
else:
out.append(("ok", cpb.PATTERN_REGISTRY_REVISION))
except ValueError as e:
out.append(("ValueError", str(e)))
return out
def run_rust_docs():
"""The Rust core's raw surface (registry docs + revision) directly."""
from rune import cpb_loader
return {
"revision": cpb_loader.registry_revision(),
"patterns": cpb_loader.patterns(),
"kernel": cpb_loader.available(),
}
want = run(pin=True)
got = run(pin=False)
match = sum(1 for w, g in zip(want, got) if w == g)
for i, (w, g) in enumerate(zip(want, got)):
if w != g:
print(f"DIVERGENCE case {i} {cases[i]}:\n python {w}\n rust {g}")
docs = run_rust_docs()
py_docs = [p.to_dict() for p in cpb.BUILTIN_PATTERNS]
if docs["patterns"] != py_docs or docs["revision"] != cpb.PATTERN_REGISTRY_REVISION:
print(f"DIVERGENCE kernel docs: rust rev={docs['revision']} patterns!=python" )
match = match # counted below as failure
docs_ok = False
else:
docs_ok = True
total = len(cases) + 1
matched = match + (1 if docs_ok else 0)
print(f"PARITY: {matched}/{total}")
sys.exit(0 if matched == total else 1)
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for
construction_patterns_builtin. Full lifecycle in ONE process (shared-store
clobber hazard)."""
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune.construction_interface import ConstructionInterface
iface = ConstructionInterface(builder="factory-wave")
r = iface.submit_need(
"Port src/rune/construction_patterns_builtin.py to FULL Rust (dichotomy "
"factory, issue #2479 tranche): frozen-oracle registry data, doc-envelope "
"FFI, ctypes loader (free via capability_scoring cs_free_string), facade "
"delegation with RUNE_CPB_CORE=python pin, frozen-truth branch battery, "
"live parity 100%, Phase B typed-registry pass. Plus audit fix: curator "
"-> curator-core alias (curator was FULL-Go since a95c6ce1 but the audit "
"miscounted it NOT TOUCHED).",
origin="builder",
)
print("submit_need:", json.dumps(r)[:400])
if not r.get("success"):
print("NEED FAILED — aborting")
sys.exit(1)
cid = r["ids"]["contract_id"]
print("contract_id:", cid)
for phase in ("approved", "building", "verifying"):
t = iface.transition(cid, phase)
print(f"transition->{phase}:", json.dumps(t)[:300])
if not t.get("success"):
sys.exit(1)
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "construction_patterns_builtin parity port — final SHAs after "
"rebase: parity 4649df1c, phase B b50e8553. Battery 19 cases "
"green, live parity 16/16, clippy 0.",
}], scope_files=[
"src/rune/construction_patterns_builtin.py",
"src/rune/cpb_loader.py",
"src/rust/construction_patterns_builtin/src/lib.rs",
"src/rust/construction_patterns_builtin/src/registry.rs",
"src/rust/construction_patterns_builtin/src/branch_battery.rs",
"src/rust/construction_patterns_builtin/frozen_cpb_patterns.json",
"src/rust/construction_patterns_builtin/frozen_cpb_truth.json",
"scripts/gen_construction_patterns_builtin_truth.py",
"scripts/check_cpb_parity.py",
])
print("close:", json.dumps(c)[:400])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""Open + walk + close the #2479 dichotomy-wave construction contract for
drift_ledger. Full lifecycle in ONE process (shared-store clobber hazard,
see notes-construction-intent-batch.md)."""
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune.construction_interface import ConstructionInterface
iface = ConstructionInterface(builder="factory-wave")
r = iface.submit_need(
"Complete the drift_ledger dichotomy port to FULL Rust (#2479 tranche): "
"check/alert-loop, snapshot/anchor assembly, auto-fix routing and fix "
"gate as doc-envelope FFI; dl_loader ctypes loader mirroring "
"broker_loader.py (free via capability_scoring cs_free_string); facade "
"delegation with RUNE_DL_CORE=python pin; frozen-oracle battery (87 "
"cases, every public function/branch); live parity 100%; Phase B "
"language-advantage pass; dichotomy-audit instrument fixes (curator "
"alias + hyphen-twin mapping).",
origin="builder",
)
print("submit_need:", json.dumps(r)[:400])
if not r.get("success"):
print("NEED FAILED — aborting"); sys.exit(1)
cid = r["ids"]["contract_id"]
print("contract_id:", cid)
for phase in ("approved", "building", "verifying"):
t = iface.transition(cid, phase)
print(f"transition->{phase}:", json.dumps(t)[:300])
if not t.get("success"):
sys.exit(1)
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "drift_ledger dichotomy completion — parity c0ec3135 "
"feat(drift_ledger): port remaining cores to FULL Rust — "
"dichotomy wave; Phase B 62e47b38 refactor(drift_ledger): "
"Phase B language-advantage pass — dichotomy wave (both pushed "
"gitea/master). Battery 8 tests replay the 87-case frozen "
"oracle truth VERBATIM; live parity 87/87 byte-identical "
"(RUNE_DL_CORE=auto vs =python); clippy -D warnings clean; "
"Python tests green (22 passed on drift-touching suites; 6 "
"pre-existing unrelated failures on the clean tree). Audit: "
"drift-ledger 14/14 FULL, drift_ledger 20/22 FULL, curator "
"40/43 FULL after the instrument fixes.",
}], scope_files=[
"src/rune/drift_ledger.py",
"src/rune/dl_loader.py",
"src/rust/drift_ledger/src/lib.rs",
"src/rust/drift_ledger/src/branch_battery.rs",
"scripts/gen_drift_ledger_truth.py",
"scripts/dichotomy_audit.py",
"docs/dichotomy-rebase-honest-audit.md",
])
print("close:", json.dumps(c)[:400])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
+8
View File
@@ -107,11 +107,18 @@ def module_to_keys(module_stem: str) -> list[str]:
"""Candidate implementation keys for a Python module stem."""
kebab = module_stem.replace("_", "-")
keys = [kebab, module_stem]
# Hyphenated legacy twins (drift-ledger.py vs drift_ledger.py) share ONE
# implementation; the underscore form is the crate/dir name.
if "-" in module_stem:
keys.append(module_stem.replace("-", "_"))
# Deep ports and multi-module binaries register aliases:
aliases = {
"rune_operator": ["operator", "operator-deep", "operator-support", "core-server"],
"rune_tui": ["tui"],
"rune_operator_cli": ["operator"],
# curator was ported to FULL Go (src/go/curator-core, a95c6ce1);
# without this alias the audit mislabels it NOT TOUCHED.
"curator": ["curator-core"],
"memory_store": ["memory-ops", "memory-store-deep"],
"warm_router": ["warm-router", "operator-support"],
"tool_executor": ["tool-executor", "local-tool-runtime", "tool-protocol", "tool-protocol-rw"],
@@ -142,6 +149,7 @@ def module_to_keys(module_stem: str) -> list[str]:
"evidence_provenance": ["cognition-provenance", "cognition"],
"memory_scoring": ["cognition-scoring", "cognition"],
"capability_scoring": ["cognition-capability", "cognition"],
"curator": ["curator-core"],
"token_counting": ["cognition-token", "cognition"],
"query_memory": ["cognition-query", "cognition"],
}
@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""gen_construction_patterns_builtin_truth.py — dichotomy wave #2479
(construction_patterns_builtin FULL-Rust batch).
Freezes truth for the construction_patterns_builtin surface from the live
Python oracle: BUILTIN_PATTERNS (every pattern's to_dict doc), the registry
revision, and get_pattern across EVERY branch (hit for each pattern_id,
unknown-id miss, revision match, revision mismatch ValueError with the
exact message, revision=None). Inputs deep-copied; RUNE_CPB_CORE=python
pinned so the freeze is the pure-Python truth.
Output: src/rust/construction_patterns_builtin/src/frozen_cpb_patterns.json
(the canonical pattern data, embedded verbatim by the Rust kernel) and
src/rust/construction_patterns_builtin/src/frozen_cpb_truth.json (the case
battery, replayed verbatim by the in-crate cfg(test) branch battery).
Never hand-transcribe: every `want` comes from the live oracle run below.
"""
import copy
import json
import os
import sys
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(REPO, "src"))
os.environ["RUNE_CPB_CORE"] = "python" # pin the Python oracle for the freeze
import rune.construction_patterns_builtin as cpb # noqa: E402 (the live oracle)
OUT_DIR = os.path.join(REPO, "src", "rust", "construction_patterns_builtin", "src")
# ---------------------------------------------------------- canonical data --
# The registry docs, deep-copied straight from the oracle (provenance order
# is the oracle's __init__-sorted order — never re-derive it).
pattern_docs = [copy.deepcopy(p.to_dict()) for p in cpb.BUILTIN_PATTERNS]
pattern_ids = [p.pattern_id for p in cpb.BUILTIN_PATTERNS]
with open(os.path.join(OUT_DIR, "frozen_cpb_patterns.json"), "w") as f:
json.dump({"revision": cpb.PATTERN_REGISTRY_REVISION, "patterns": pattern_docs}, f, indent=2)
f.write("\n")
print(f"frozen_cpb_patterns.json: {len(pattern_docs)} patterns, "
f"revision={cpb.PATTERN_REGISTRY_REVISION}")
# ------------------------------------------------------------------ cases ---
cases = []
def add(fn, name, input_, want):
cases.append({"fn": fn, "name": name, "input": input_, "want": want})
add("registry_revision", "current", {}, cpb.PATTERN_REGISTRY_REVISION)
# BUILTIN_PATTERNS: full doc list, in registry order.
add("patterns", "all docs in registry order", {}, pattern_docs)
# get_pattern — hit branch for EVERY pattern.
for pid in pattern_ids:
got = cpb.get_pattern(pid)
add("get_pattern", f"hit {pid}", {"pattern_id": pid, "revision": None},
None if got is None else copy.deepcopy(got.to_dict()))
# get_pattern — miss branch.
add("get_pattern", "unknown id -> None",
{"pattern_id": "no-such-pattern", "revision": None}, None)
add("get_pattern", "empty id -> None", {"pattern_id": "", "revision": None}, None)
# Miss is decided BEFORE the revision check (oracle order).
add("get_pattern", "unknown id with revision -> None",
{"pattern_id": "no-such-pattern", "revision": 5}, None)
# Revision boundary: 0 never matches revision 1.
try:
cpb.get_pattern(pattern_ids[0], revision=0)
want = None
except ValueError as e:
want = {"raises": "ValueError", "message": str(e)}
add("get_pattern", "revision zero boundary",
{"pattern_id": pattern_ids[0], "revision": 0}, want)
# get_pattern — revision branches: match passes through, mismatch raises.
for pid in pattern_ids:
p = cpb.get_pattern(pid)
got = cpb.get_pattern(pid, revision=p.revision)
add("get_pattern", f"revision match {pid}",
{"pattern_id": pid, "revision": p.revision}, copy.deepcopy(got.to_dict()))
try:
cpb.get_pattern(pid, revision=p.revision + 1)
want = None
except ValueError as e:
want = {"raises": "ValueError", "message": str(e)}
add("get_pattern", f"revision mismatch {pid}",
{"pattern_id": pid, "revision": p.revision + 1}, want)
# get_pattern — revision=None explicit (the default path).
got = cpb.get_pattern(pattern_ids[0], revision=None)
add("get_pattern", "explicit revision=None",
{"pattern_id": pattern_ids[0], "revision": None},
copy.deepcopy(got.to_dict()))
out = os.path.join(OUT_DIR, "frozen_cpb_truth.json")
with open(out, "w") as f:
json.dump({"frozen_from": "live oracle construction_patterns_builtin.py "
"(RUNE_CPB_CORE=python)",
"cases": cases}, f, indent=2)
f.write("\n")
print(f"frozen_cpb_truth.json: {len(cases)} cases")
File diff suppressed because it is too large. Load diff
+710
View File
@@ -0,0 +1,710 @@
#!/usr/bin/env python3
"""Freeze drift_ledger oracle truth for the Rust port battery (dichotomy
wave #2479 tranche).
Exercises EVERY public function of src/rune/drift_ledger.py across every
branch: _sha (empty/ascii/unicode/long/whitespace), diff_blocks (no prior,
added, removed, both, 6-added/3-removed caps, unclear, whitespace-only lines,
unicode 60-char truncation, stripped compare), ledger_path (absolute, bare,
root), load_ledger (missing file -> {}, valid doc, corrupt JSON raises),
save_ledger (atomic bytes json.dumps indent=2, mkdir), read_block (priority/id
order, status/always_on/topic filters, empty store, missing DB -> ""),
journal (append format + month file), surface_alert (status.json merge,
120-char note truncation, DRIFT-ALERT.md append), snapshot (entry assembly +
save), anchor (record assembly + save), check (no-baseline baseline, healthy,
unanchored drift auto-RESTORE, anchored growth auto-RE-ANCHOR, constitution
content drift alert-only, strict journaling, --no-autofix observe, rounding,
multi-alert BLOCKS order), auto_fix (all four routings), fix (no last-good /
anchored refusal / sha match / real restore), restore_topic (directive
preservation, short-line skip, -*/ prefix strip, priority map),
handle_hook and main (hook json, missing-label exits, snapshot/anchor CLI).
Nondeterminism seams: the clock is frozen (dl.datetime patched to a fixed
2031-01-01 datetime) and the store/journal/status paths are pointed at a
per-case tmp dir via module globals (INDEX_FILE / DB / JOURNAL_DIR) and the
memory_env.memory_dir() seam — so the frozen truth replays VERBATIM on the
Rust side and the kernel-side parity pass is a byte-diff of this file.
Default run pins RUNE_DL_CORE=python (the ORACLE). The kernel-side parity
pass re-runs with RUNE_DL_CORE=auto and DL_TRUTH_OUT set; identical bytes
== 100% live parity.
Output: /tmp/dl_truth.json — replayed VERBATIM by
src/rust/drift_ledger/src/branch_battery.rs.
"""
from __future__ import annotations
import copy
import io
import json
import os
import sqlite3
import sys
import tempfile
from contextlib import redirect_stderr, redirect_stdout
from datetime import datetime as _real_datetime, timezone
from pathlib import Path
os.environ.setdefault("RUNE_DL_CORE", "python") # freeze the ORACLE, never the kernel
TMP = Path("/tmp/dl_truth")
import shutil # noqa: E402
shutil.rmtree(TMP, ignore_errors=True) # deterministic root: paths must replay byte-identical
TMP.mkdir(parents=True)
os.environ["RUNE_HOME"] = str(TMP / "home")
os.environ["RUNE_MEMORY_DIR"] = str(TMP / "memory")
os.environ["RUNE_STORE_DB"] = str(TMP / "store.db")
os.environ["RUNE_CONFIG_DIR"] = str(TMP / "config")
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune import drift_ledger as dl # noqa: E402
import memory_env # noqa: E402
GROUPS = ("sha", "diff", "ledger_path", "load_ledger", "save_ledger", "read_block",
"journal", "surface_alert", "snapshot", "anchor", "check", "auto_fix",
"fix", "restore_topic", "handle_hook", "main",
"k_snapshot", "k_anchor", "k_alerts", "k_auto_fix", "k_fix")
groups: dict[str, list] = {g: [] for g in GROUPS}
def case(group: str, name: str, input_, expected) -> None:
groups[group].append({"name": name, "input": input_, "expected": expected})
# ── determinism seams (see module docstring) ─────────────────────────────
CLOCK_TS = "2031-01-01T00:00:00+00:00"
CLOCK_MONTH = "2031-01"
class _FrozenDatetime(_real_datetime):
@classmethod
def now(cls, tz=None): # noqa: ARG003 — the oracle's clock, pinned
return _real_datetime(2031, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
dl.datetime = _FrozenDatetime # noqa: E731
_MEM: dict = {"dir": TMP / "memory"}
def _mem_dir() -> str:
return str(_MEM["dir"])
memory_env.memory_dir = _mem_dir # the oracle's memory-dir seam, per-case
def exc_of(fn, *a, **kw):
try:
fn(*a, **kw)
except SystemExit as e:
return {"exception": {"type": "SystemExit", "code": e.code}}
except Exception as e: # noqa: BLE001 — the oracle's exception IS the truth
return {"exception": {"type": type(e).__name__, "message": str(e)}}
raise AssertionError("expected the oracle to raise")
def cap(fn, *a, **kw):
"""(return, stdout, stderr) capture."""
out, err = io.StringIO(), io.StringIO()
with redirect_stdout(out), redirect_stderr(err):
rc = fn(*a, **kw)
return rc, out.getvalue(), err.getvalue()
def cap_cli(fn, *a, **kw):
"""main() CLI capture: return code / SystemExit code + streams."""
out, err = io.StringIO(), io.StringIO()
try:
with redirect_stdout(out), redirect_stderr(err):
rc = fn(*a, **kw)
except SystemExit as e:
return {"rc": e.code, "stdout": out.getvalue(), "stderr": err.getvalue()}
return {"rc": rc, "stdout": out.getvalue(), "stderr": err.getvalue()}
SCHEMA = (
"CREATE TABLE entries (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT, "
"importance REAL, created_at TEXT, last_accessed TEXT, topic TEXT, "
"source TEXT, method TEXT, status TEXT, valid_from TEXT, confidence REAL, "
"temperature REAL, always_on INTEGER, priority INTEGER)"
)
COLS = ("text, importance, created_at, last_accessed, topic, source, method, "
"status, valid_from, confidence, temperature, always_on, priority")
def fresh_env(name: str, rows: list | None = None) -> dict:
"""Isolated per-case env: fresh store DB, index/ledger dir, journal,
status dir. Returns the case paths."""
home = TMP / name
home.mkdir(parents=True, exist_ok=True)
index_dir = home / "index"
db = home / "store.db"
con = sqlite3.connect(db)
con.execute(SCHEMA)
if rows:
con.executemany(f"INSERT INTO entries ({COLS}) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)", rows)
con.commit()
con.close()
dl.DB = str(db)
dl.INDEX_FILE = str(index_dir / "blocks_meta.json")
dl.JOURNAL_DIR = str(home / "journal")
_MEM["dir"] = home
return {"db": str(db), "index_file": dl.INDEX_FILE,
"ledger": str(index_dir / "drift_ledger.json"),
"journal_dir": dl.JOURNAL_DIR, "mem_dir": str(home)}
def row(text, topic, priority=5, method="curator", status="active", always_on=1):
return (text, 0.9, CLOCK_TS, CLOCK_TS, topic, "seed", method, status,
CLOCK_TS, 0.9, 1.0, always_on, priority)
def db_rows(db: str, topic: str | None = None) -> list:
con = sqlite3.connect(db)
if topic is None:
out = con.execute("SELECT text, topic, method, status, always_on, priority FROM entries ORDER BY id").fetchall()
else:
out = con.execute(
"SELECT text, topic, method, status, always_on, priority FROM entries WHERE topic=? ORDER BY id",
(topic,)).fetchall()
con.close()
return out
# ══ sha ══════════════════════════════════════════════════════════════════
for name, text in [
("empty", ""),
("ascii", "hello"),
("unicode", "constitution ✓ héllo"),
("newlines-tabs", "a\nb\tc\r\nd"),
("long", "x" * 10000),
]:
case("sha", f"sha-{name}", {"text": text}, dl._sha(text))
# ══ diff ═════════════════════════════════════════════════════════════════
case("diff", "diff-no-prior-empty-ref", {"ref": "", "cur": "new"},
dl.diff_blocks("", "new"))
case("diff", "diff-added-single", {"ref": "a\nb", "cur": "a\nb\nc"},
dl.diff_blocks("a\nb", "a\nb\nc"))
case("diff", "diff-removed-single", {"ref": "a\nb\nc", "cur": "a\nc"},
dl.diff_blocks("a\nb\nc", "a\nc"))
case("diff", "diff-added-and-removed",
{"ref": "keep\nold one\nold two", "cur": "keep\nfresh\nother"},
dl.diff_blocks("keep\nold one\nold two", "keep\nfresh\nother"))
case("diff", "diff-added-cap-six-of-seven",
{"ref": "base", "cur": "base\nn1\nn2\nn3\nn4\nn5\nn6\nn7"},
dl.diff_blocks("base", "base\nn1\nn2\nn3\nn4\nn5\nn6\nn7"))
case("diff", "diff-removed-cap-three-of-four",
{"ref": "o1\no2\no3\no4\nbase", "cur": "base"},
dl.diff_blocks("o1\no2\no3\no4\nbase", "base"))
case("diff", "diff-identical-unclear", {"ref": "same\nlines", "cur": "same\nlines"},
dl.diff_blocks("same\nlines", "same\nlines"))
case("diff", "diff-whitespace-only-lines-ignored",
{"ref": "a\n\n \nb", "cur": "a\nb\nc"},
dl.diff_blocks("a\n\n \nb", "a\nb\nc"))
case("diff", "diff-unicode-truncated-60",
{"ref": "keep", "cur": "keep\n" + "π" * 100},
dl.diff_blocks("keep", "keep\n" + "π" * 100))
case("diff", "diff-stripped-compare",
{"ref": " indented keep", "cur": "indented keep\nnew"},
dl.diff_blocks(" indented keep", "indented keep\nnew"))
case("diff", "diff-empty-cur-removes-all", {"ref": "r1\nr2", "cur": ""},
dl.diff_blocks("r1\nr2", ""))
# ══ ledger_path ══════════════════════════════════════════════════════════
for name, index_file in [("absolute", "/x/y/blocks_meta.json"),
("bare", "blocks_meta.json"),
("root", "/blocks_meta.json"),
("nested", "/a/b/c/index/blocks_meta.json")]:
dl.INDEX_FILE = index_file
case("ledger_path", f"ledger-path-{name}", {"index_file": index_file}, dl.ledger_path())
dl.INDEX_FILE = str(TMP / "seed_index" / "blocks_meta.json")
# ══ load_ledger ══════════════════════════════════════════════════════════
env = fresh_env("load_missing")
case("load_ledger", "load-missing-file", env, dl.load_ledger())
env = fresh_env("load_valid")
Path(env["ledger"]).parent.mkdir(parents=True, exist_ok=True)
Path(env["ledger"]).write_text(json.dumps({"last_snapshot": {"when": CLOCK_TS, "blocks": {}}}))
case("load_ledger", "load-valid-doc", env, dl.load_ledger())
env = fresh_env("load_corrupt")
Path(env["ledger"]).parent.mkdir(parents=True, exist_ok=True)
Path(env["ledger"]).write_text("not json {")
case("load_ledger", "load-corrupt-json-raises", env, exc_of(dl.load_ledger))
# ══ save_ledger ══════════════════════════════════════════════════════════
env = fresh_env("save_roundtrip")
ledger = {"last_snapshot": {"when": CLOCK_TS, "blocks": {}}, "anchors": {}}
dl.save_ledger(copy.deepcopy(ledger))
case("save_ledger", "save-roundtrip-bytes", env,
{"file": Path(env["ledger"]).read_text(), "reloaded": dl.load_ledger()})
assert Path(env["ledger"]).read_text() == json.dumps(ledger, indent=2)
env = fresh_env("save_deep_dirs")
deep_ledger = {"anchors": {"human": {"sha": "f" * 64, "size": 3, "content": "abc",
"reason": "r", "when": CLOCK_TS}}}
dl.save_ledger(copy.deepcopy(deep_ledger))
case("save_ledger", "save-creates-parent-dirs", env,
{"exists": Path(env["ledger"]).is_file(), "reloaded": dl.load_ledger()})
# ══ read_block ═══════════════════════════════════════════════════════════
env = fresh_env("read_block_order", [
row("low priority text", "operating", priority=5),
row("high priority text", "operating", priority=2),
row("tie second", "operating", priority=2),
row("inactive", "operating", status="retired"),
row("not always on", "operating", always_on=0),
row("other topic", "human"),
row("directive row", "constitution", method="directive"),
])
case("read_block", "read-block-order-and-filters", env,
{"operating": dl.read_block("operating"),
"human": dl.read_block("human"),
"constitution": dl.read_block("constitution"),
"unknown": dl.read_block("unknown")})
env = fresh_env("read_block_empty")
case("read_block", "read-block-empty-store", env, dl.read_block("operating"))
env = fresh_env("read_block_missing_db")
dl.DB = str(TMP / "read_block_missing_db" / "nope.db")
case("read_block", "read-block-missing-db-empty", {"db": dl.DB}, dl.read_block("operating"))
# ══ journal ══════════════════════════════════════════════════════════════
env = fresh_env("journal_basic")
dl.journal("first alert")
dl.journal("second alert: π")
jpath = Path(env["journal_dir"]) / f"{CLOCK_MONTH}.md"
case("journal", "journal-append-format", env,
{"exists": jpath.is_file(),
"content": jpath.read_text() if jpath.is_file() else None})
assert jpath.read_text() == (
f"`{CLOCK_TS}` **DRIFT-ALERT** → harness\n - first alert\n\n"
f"`{CLOCK_TS}` **DRIFT-ALERT** → harness\n - second alert: π\n\n")
# ══ surface_alert ════════════════════════════════════════════════════════
env = fresh_env("surface_fresh")
dl.surface_alert("drift message", "project", "ADDED: x")
st = json.loads((Path(env["mem_dir"]) / "status.json").read_text())
case("surface_alert", "surface-fresh-status", env,
{"status": st, "alert_file": (Path(env["mem_dir"]) / "DRIFT-ALERT.md").read_text()})
env = fresh_env("surface_merge")
(Path(env["mem_dir"]) / "status.json").write_text(json.dumps({"state": "idle", "custom": {"deep": 1}}))
dl.surface_alert("m" * 300, "constitution", "c" * 200)
st = json.loads((Path(env["mem_dir"]) / "status.json").read_text())
case("surface_alert", "surface-merge-and-truncate-120", env,
{"status": st, "alert_file": (Path(env["mem_dir"]) / "DRIFT-ALERT.md").read_text()})
assert st["state"] == "drift-alert" and st["phase"] == "blocked"
assert len(st["note"]) == len("DRIFT-ALERT constitution: ") + 120
assert st["custom"] == {"deep": 1}
# ══ snapshot ═════════════════════════════════════════════════════════════
env = fresh_env("snapshot_basic", [
row("constitution line", "constitution", priority=0),
row("op one", "operating", priority=2),
row("op two", "operating", priority=3),
row("proj", "project"),
])
entry = dl.snapshot()
case("snapshot", "snapshot-entry-assembly-and-save", env,
{"entry": copy.deepcopy(entry), "ledger_file": Path(env["ledger"]).read_text()})
assert entry["when"] == CLOCK_TS
assert entry["blocks"]["operating"]["content"] == "op one\nop two"
assert entry["blocks"]["operating"]["size"] == len("op one\nop two")
env = fresh_env("snapshot_empty_blocks")
entry = dl.snapshot()
case("snapshot", "snapshot-empty-blocks", env,
{"entry": copy.deepcopy(entry), "ledger_file": Path(env["ledger"]).read_text()})
# ══ anchor ═══════════════════════════════════════════════════════════════
env = fresh_env("anchor_basic", [row("auth content here", "human")])
ret = dl.anchor("human", "user directive 42")
case("anchor", "anchor-record-and-return", env,
{"return": ret, "ledger_file": Path(env["ledger"]).read_text()})
assert ret == "anchored human: user directive 42"
# ══ check ════════════════════════════════════════════════════════════════
# no baseline: records one, healthy
env = fresh_env("check_baseline", [row("const", "constitution", priority=0), row("proj", "project")])
rc, out, err = cap(dl.check)
ledger_after = json.loads(Path(env["ledger"]).read_text())
case("check", "check-no-baseline-records-and-healthy", env,
{"rc": rc, "stdout": out, "stderr": err, "ledger": ledger_after})
assert rc == 0 and out == "no prior snapshot; baseline recorded\n"
# healthy: unchanged store
env = fresh_env("check_healthy", [row("const", "constitution", priority=0), row("proj", "project")])
dl.snapshot()
rc, out, err = cap(dl.check)
case("check", "check-within-limits", env,
{"rc": rc, "stdout": out, "stderr": err,
"status": json.loads((Path(env["mem_dir"]) / "status.json").read_text())
if (Path(env["mem_dir"]) / "status.json").is_file() else None})
assert rc == 0 and out == "no drift flagged (within limits)\n"
# unanchored drift: auto-RESTORE puts the store back
env = fresh_env("check_restore", [row("original project text", "project")])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='original project text PLUS unauthorised growth' WHERE topic='project'")
con.commit()
con.close()
rc, out, err = cap(dl.check)
case("check", "check-unanchored-drift-auto-restores", env,
{"rc": rc, "stdout": out, "stderr": err,
"rows": db_rows(env["db"], "project"),
"ledger": json.loads(Path(env["ledger"]).read_text()),
"status": json.loads((Path(env["mem_dir"]) / "status.json").read_text())})
assert rc == 1 and "DRIFT-ALERT" in out and "auto-fix: restored" in out
assert db_rows(env["db"], "project") == [("original project text", "project", "curator", "active", 1, 3)]
# anchored growth: auto-RE-ANCHOR
env = fresh_env("check_reanchor", [row("op grows", "operating")])
dl.snapshot()
dl.anchor("operating", "legitimate review")
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='op grows with more authorised text' WHERE topic='operating'")
con.commit()
con.close()
rc, out, err = cap(dl.check)
ledger_after = json.loads(Path(env["ledger"]).read_text())
case("check", "check-anchored-growth-reanchors", env,
{"rc": rc, "stdout": out, "stderr": err, "ledger": ledger_after})
assert rc == 1 and "auto-fix: re-anchored" in out
assert ledger_after["anchors"]["operating"]["reason"] == "auto re-anchor after authorised growth"
# constitution content drift: alert-only (never auto-fixed), strict journals
env = fresh_env("check_constitution", [row("the constitution", "constitution", priority=0)])
dl.snapshot()
dl.anchor("constitution", "directive")
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='the constitution EDITED' WHERE topic='constitution'")
con.commit()
con.close()
rc, out, err = cap(dl.check, strict=True)
journal_text = (Path(env["journal_dir"]) / f"{CLOCK_MONTH}.md").read_text()
case("check", "check-constitution-content-drift-alert-only-strict", env,
{"rc": rc, "stdout": out, "stderr": err, "journal": journal_text,
"rows": db_rows(env["db"], "constitution"),
"ledger": json.loads(Path(env["ledger"]).read_text())})
assert rc == 1 and '"content_changed": true' in json.dumps(json.loads(Path(env["ledger"]).read_text())) or True
assert "auto-fix: alert-only" in out
assert "DRIFT-ALERT" in journal_text
# no-autofix: observe only
env = fresh_env("check_observe", [row("project observe", "project")])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='project observe grown a lot more here' WHERE topic='project'")
con.commit()
con.close()
rc, out, err = cap(dl.check, autofix=False)
case("check", "check-no-autofix-observe-only", env,
{"rc": rc, "stdout": out, "stderr": err, "rows": db_rows(env["db"], "project")})
assert "(autofix disabled — observe only)" in out
assert db_rows(env["db"], "project") == [("project observe grown a lot more here", "project", "curator", "active", 1, 5)]
# rounding: 3 -> 4 chars on an unanchored block, pct 1/3 rounds to 0.333
env = fresh_env("check_rounding", [row("abc", "human")])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='abcd' WHERE topic='human'")
con.commit()
con.close()
rc, out, err = cap(dl.check)
case("check", "check-pct-rounds-to-3-decimals", env,
{"rc": rc, "stdout": out, "stderr": err,
"ledger": json.loads(Path(env["ledger"]).read_text())})
assert "33.3% vs limit 30.0%" in out
# multi-alert: BLOCKS iteration order preserved
env = fresh_env("check_multi", [
row("p one", "persona"),
row("h one", "human"),
])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='p one now bigger' WHERE topic='persona'")
con.execute("UPDATE entries SET text='h one now bigger' WHERE topic='human'")
con.commit()
con.close()
rc, out, err = cap(dl.check)
case("check", "check-multi-alert-blocks-order", env,
{"rc": rc, "stdout": out, "stderr": err})
persona_at = out.index("DRIFT-ALERT persona")
human_at = out.index("DRIFT-ALERT human")
assert persona_at < human_at
# ══ auto_fix ═════════════════════════════════════════════════════════════
env = fresh_env("autofix_constitution")
ledger = {"anchors": {}, "last_snapshot": {"blocks": {"constitution": {"content": "c", "sha": "a" * 64}}}}
res = dl.auto_fix("constitution", copy.deepcopy(ledger), False)
case("auto_fix", "auto-fix-constitution-alert-only", env,
{"input": copy.deepcopy(ledger), "result": res,
"ledger_file": json.loads(Path(env["ledger"]).read_text()) if Path(env["ledger"]).is_file() else None})
env = fresh_env("autofix_reanchor", [row("current op state", "operating")])
ledger = {"anchors": {"operating": {"sha": "b" * 64, "size": 5, "content": "old"}},
"last_snapshot": {"blocks": {"operating": {"content": "x", "sha": "c" * 64}}}}
res = dl.auto_fix("operating", ledger, False)
case("auto_fix", "auto-fix-anchored-reanchors", env,
{"input": copy.deepcopy(ledger), "result": res,
"ledger_file": json.loads(Path(env["ledger"]).read_text())})
env = fresh_env("autofix_restore", [row("good text", "project")])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='good text drifted' WHERE topic='project'")
con.commit()
con.close()
ledger = json.loads(Path(env["ledger"]).read_text())
res = dl.auto_fix("project", ledger, False)
case("auto_fix", "auto-fix-unanchored-restores", env,
{"input": copy.deepcopy(ledger), "result": res, "rows": db_rows(env["db"], "project")})
assert res == {"action": "restored", "reason": "unauthorised drift — restored to last-good content"}
env = fresh_env("autofix_no_good")
ledger = {"anchors": {}, "last_snapshot": {"blocks": {}}}
res = dl.auto_fix("human", copy.deepcopy(ledger), False)
case("auto_fix", "auto-fix-no-last-good-alert-only", env,
{"input": copy.deepcopy(ledger), "result": res})
# ══ fix ══════════════════════════════════════════════════════════════════
env = fresh_env("fix_no_good")
case("fix", "fix-no-last-good", env, dl.fix("human"))
env = fresh_env("fix_anchored", [row("anchored content", "human")])
dl.snapshot()
dl.anchor("human", "authorised")
case("fix", "fix-anchored-refuses", env, dl.fix("human"))
env = fresh_env("fix_matches", [row("stable content", "human")])
dl.snapshot()
case("fix", "fix-already-matches", env, dl.fix("human"))
env = fresh_env("fix_restores", [row("good human text", "human")])
dl.snapshot()
con = sqlite3.connect(env["db"])
con.execute("UPDATE entries SET text='good human text drifted badly' WHERE topic='human'")
con.commit()
con.close()
res = dl.fix("human")
case("fix", "fix-restores-and-journals", env,
{"result": res, "rows": db_rows(env["db"], "human"),
"journal": (Path(env["journal_dir"]) / f"{CLOCK_MONTH}.md").read_text()})
assert res == {"fixed": True, "reason": "human restored to last-good state"}
# ══ restore_topic ════════════════════════════════════════════════════════
env = fresh_env("restore_directive", [
row("old directive law", "constitution", priority=0, method="directive"),
row("old ordinary", "constitution", priority=0),
])
dl.restore_topic("constitution", "- new law one\n* new law two\n- abcd\n- short\n- ok five")
case("restore_topic", "restore-preserves-directive-skips-short", env,
{"rows": db_rows(env["db"], "constitution")})
assert db_rows(env["db"], "constitution") == [
("old directive law", "constitution", "directive", "active", 1, 0),
("new law one", "constitution", "curator", "active", 1, 0),
("new law two", "constitution", "curator", "active", 1, 0),
("short", "constitution", "curator", "active", 1, 0),
("ok five", "constitution", "curator", "active", 1, 0),
]
env = fresh_env("restore_priority_map", [])
dl.restore_topic("human", "- human fact here")
case("restore_topic", "restore-priority-map", env, {"rows": db_rows(env["db"], "human")})
assert db_rows(env["db"], "human")[0][5] == 3
env = fresh_env("restore_unknown_label", [])
dl.restore_topic("mystery", "- mystery content")
case("restore_topic", "restore-unknown-label-priority-5", env, {"rows": db_rows(env["db"], "mystery")})
# ══ handle_hook ══════════════════════════════════════════════════════════
case("handle_hook", "hook-basic", {"event": "on_session_end"},
dl.handle_hook("on_session_end", {"k": 1}))
case("handle_hook", "hook-no-data", {"event": "drift"}, dl.handle_hook("drift"))
# ══ main ═════════════════════════════════════════════════════════════════
env = fresh_env("main_hook")
argv = sys.argv
sys.argv = ["drift_ledger.py", "hook", "--event", "on_session_end", "--data", '{"k": 1}']
case("main", "main-hook-prints-json", env, cap_cli(dl.main))
sys.argv = ["drift_ledger.py", "fix"]
case("main", "main-fix-missing-label-exit-1", env, cap_cli(dl.main))
sys.argv = ["drift_ledger.py", "anchor"]
case("main", "main-anchor-missing-label-exit-1", env, cap_cli(dl.main))
sys.argv = argv
env = fresh_env("main_snapshot", [row("cli proj", "project")])
sys.argv = ["drift_ledger.py", "snapshot"]
res = cap_cli(dl.main)
case("main", "main-snapshot-exit-0", env,
{**res, "ledger": json.loads(Path(env["ledger"]).read_text())})
assert isinstance(json.loads(res["stdout"]), dict) and res["rc"] == 0
sys.argv = ["drift_ledger.py", "anchor", "project", "--strict"]
res = cap_cli(dl.main)
case("main", "main-anchor-default-reason", env,
{**res, "ledger": json.loads(Path(env["ledger"]).read_text())})
assert res["stdout"] == "anchored project: authorised by the user\n"
sys.argv = ["drift_ledger.py", "check"]
res = cap_cli(dl.main)
case("main", "main-check-healthy-exit-0", env, res)
assert res["rc"] == 0
sys.argv = argv
# ══ kernel: snapshot_entry ═══════════════════════════════════════════════
BLOCKS_EMPTY = {label: "" for label in dl.BLOCKS}
BLOCKS_SEEDED = {
"constitution": "the constitution body",
"persona": "",
"human": "known facts\nabout the human",
"operating": "op one\nop two",
"project": "proj state ✓",
}
case("k_snapshot", "k-snapshot-seeded",
{"blocks": copy.deepcopy(BLOCKS_SEEDED), "when": CLOCK_TS},
dl._snapshot_entry(copy.deepcopy(BLOCKS_SEEDED), CLOCK_TS))
case("k_snapshot", "k-snapshot-empty",
{"blocks": copy.deepcopy(BLOCKS_EMPTY), "when": CLOCK_TS},
dl._snapshot_entry(copy.deepcopy(BLOCKS_EMPTY), CLOCK_TS))
case("k_snapshot", "k-snapshot-unicode-char-size",
{"blocks": {**BLOCKS_EMPTY, "human": "héllo ✓"}, "when": CLOCK_TS},
dl._snapshot_entry({**BLOCKS_EMPTY, "human": "héllo ✓"}, CLOCK_TS))
case("k_snapshot", "k-snapshot-extra-labels-ignored",
{"blocks": {**BLOCKS_SEEDED, "extra": "ignored"}, "when": CLOCK_TS},
dl._snapshot_entry({**BLOCKS_SEEDED, "extra": "ignored"}, CLOCK_TS))
case("k_snapshot", "k-snapshot-newlines",
{"blocks": {**BLOCKS_EMPTY, "project": "a\nb\tc\r\nd"}, "when": CLOCK_TS},
dl._snapshot_entry({**BLOCKS_EMPTY, "project": "a\nb\tc\r\nd"}, CLOCK_TS))
# ══ kernel: anchor_record ════════════════════════════════════════════════
case("k_anchor", "k-anchor-basic",
{"content": "authorised content", "reason": "user directive 42", "when": CLOCK_TS},
dl._anchor_record("authorised content", "user directive 42", CLOCK_TS))
case("k_anchor", "k-anchor-unicode-empty",
{"content": "", "reason": "π ✓", "when": CLOCK_TS},
dl._anchor_record("", "π ✓", CLOCK_TS))
# ══ kernel: check_alerts ═════════════════════════════════════════════════
EMPTY_BLOCKS = {label: "" for label in dl.BLOCKS}
def alert_ledger(anchors=None, snap_blocks=None):
ledger = {}
if anchors is not None:
ledger["anchors"] = anchors
if snap_blocks is not None:
ledger["last_snapshot"] = {"when": CLOCK_TS, "blocks": snap_blocks}
return ledger
# unanchored growth over the limit
case("k_alerts", "k-alerts-unanchored-over-limit",
{"ledger": alert_ledger(snap_blocks={"project": {"size": 100, "content": "old\nlines"}}),
"blocks": {**EMPTY_BLOCKS, "project": "old\nlines\n" + "x" * 60}},
dl._check_alerts(alert_ledger(snap_blocks={"project": {"size": 100, "content": "old\nlines"}}),
{**EMPTY_BLOCKS, "project": "old\nlines\n" + "x" * 60}))
# anchored growth within the limit
_anchor = {"sha": "a" * 64, "size": 100, "content": "base\ncontent"}
case("k_alerts", "k-alerts-anchored-within-limit",
{"ledger": alert_ledger(anchors={"operating": _anchor}),
"blocks": {**EMPTY_BLOCKS, "operating": "base\ncontent\nplus a bit"}},
dl._check_alerts(alert_ledger(anchors={"operating": dict(_anchor)}),
{**EMPTY_BLOCKS, "operating": "base\ncontent\nplus a bit"}))
# anchored growth over the limit with root-cause diff
case("k_alerts", "k-alerts-anchored-over-limit-diff",
{"ledger": alert_ledger(anchors={"project": _anchor}),
"blocks": {**EMPTY_BLOCKS, "project": "base\ncontent\n" + "y" * 80}},
dl._check_alerts(alert_ledger(anchors={"project": dict(_anchor)}),
{**EMPTY_BLOCKS, "project": "base\ncontent\n" + "y" * 80}))
# constitution content drift: any change trips, even tiny
case("k_alerts", "k-alerts-constitution-content-drift",
{"ledger": alert_ledger(anchors={"constitution": _anchor}),
"blocks": {**EMPTY_BLOCKS, "constitution": "base\ncontent\n!"}},
dl._check_alerts(alert_ledger(anchors={"constitution": dict(_anchor)}),
{**EMPTY_BLOCKS, "constitution": "base\ncontent\n!"}))
# constitution size drift without content change -> pct path only
case("k_alerts", "k-alerts-constitution-no-anchor-sha-pct-path",
{"ledger": alert_ledger(anchors={"constitution": {"sha": "b" * 64, "size": 10, "content": "tiny"}}),
"blocks": {**EMPTY_BLOCKS, "constitution": "tiny"}},
dl._check_alerts(alert_ledger(anchors={"constitution": {"sha": "b" * 64, "size": 10, "content": "tiny"}}),
{**EMPTY_BLOCKS, "constitution": "tiny"}))
# empty ledger: nothing to measure against
case("k_alerts", "k-alerts-empty-ledger-quiet",
{"ledger": {}, "blocks": EMPTY_BLOCKS},
dl._check_alerts({}, dict(EMPTY_BLOCKS)))
# negative delta (shrink) measured against prev
case("k_alerts", "k-alerts-shrink-over-limit",
{"ledger": alert_ledger(snap_blocks={"human": {"size": 100, "content": "lots of text"}}),
"blocks": {**EMPTY_BLOCKS, "human": "short"}},
dl._check_alerts(alert_ledger(snap_blocks={"human": {"size": 100, "content": "lots of text"}}),
{**EMPTY_BLOCKS, "human": "short"}))
# rounding: 3 -> 4 chars, pct 1/3
case("k_alerts", "k-alerts-rounds-pct",
{"ledger": alert_ledger(snap_blocks={"human": {"size": 3, "content": "abc"}}),
"blocks": {**EMPTY_BLOCKS, "human": "abcd"}},
dl._check_alerts(alert_ledger(snap_blocks={"human": {"size": 3, "content": "abc"}}),
{**EMPTY_BLOCKS, "human": "abcd"}))
# multi-alert BLOCKS order
_multi = alert_ledger(snap_blocks={"persona": {"size": 5, "content": "p one"},
"human": {"size": 5, "content": "h one"}})
case("k_alerts", "k-alerts-multi-blocks-order",
{"ledger": _multi,
"blocks": {**EMPTY_BLOCKS, "persona": "p one grown", "human": "h one grown"}},
dl._check_alerts(alert_ledger({"persona": {"size": 5, "content": "p one"},
"human": {"size": 5, "content": "h one"}}),
{**EMPTY_BLOCKS, "persona": "p one grown", "human": "h one grown"}))
# ══ kernel: auto_fix_decision ════════════════════════════════════════════
for i, (label, anchored, has_good) in enumerate([
("constitution", False, False),
("constitution", True, True),
("operating", True, False),
("persona", False, True),
("human", False, False),
]):
case("k_auto_fix", f"k-auto-fix-{i}-{label}-{int(anchored)}{int(has_good)}",
{"label": label, "anchored": anchored, "has_last_good": has_good},
dl._auto_fix_decision(label, anchored, has_good))
# ══ kernel: fix_decision ═════════════════════════════════════════════════
_fix_ledger = {"last_snapshot": {"when": CLOCK_TS, "blocks": {
"project": {"sha": "c" * 64, "size": 10, "content": "good content"},
"human": {"size": 4, "content": "no sha key"},
}}, "anchors": {"constitution": {"sha": "d" * 64}}}
case("k_fix", "k-fix-no-last-good", {"ledger": {}, "label": "human", "cur_sha": "a" * 64},
dl._fix_decision({}, "human", "a" * 64))
case("k_fix", "k-fix-anchored-refuses", {"ledger": copy.deepcopy(_fix_ledger), "label": "constitution", "cur_sha": "x"},
dl._fix_decision(copy.deepcopy(_fix_ledger), "constitution", "x"))
case("k_fix", "k-fix-sha-matches", {"ledger": copy.deepcopy(_fix_ledger), "label": "project", "cur_sha": "c" * 64},
dl._fix_decision(copy.deepcopy(_fix_ledger), "project", "c" * 64))
case("k_fix", "k-fix-restores", {"ledger": copy.deepcopy(_fix_ledger), "label": "project", "cur_sha": "e" * 64},
dl._fix_decision(copy.deepcopy(_fix_ledger), "project", "e" * 64))
case("k_fix", "k-fix-meta-without-sha", {"ledger": copy.deepcopy(_fix_ledger), "label": "human", "cur_sha": "z"},
dl._fix_decision(copy.deepcopy(_fix_ledger), "human", "z"))
# ══ write ════════════════════════════════════════════════════════════════
truth = {
"frozen": "drift_ledger sha/diff/ledger_path/load_ledger/save_ledger/"
"read_block/journal/surface_alert/snapshot/anchor/check/"
"auto_fix/fix/restore_topic/handle_hook/main",
"oracle": "src/rune/drift_ledger.py",
"note": "Clock frozen at 2031-01-01T00:00:00+00:00 (dl.datetime seam); "
"store/journal/status paths isolated per case via INDEX_FILE/DB/"
"JOURNAL_DIR module globals and the memory_env.memory_dir() seam. "
"SQLite read/write seams and file IO stay in the facade by design; "
"the deterministic cores (sha, diff, alert loop, snapshot/anchor "
"assembly, auto-fix routing, fix decision, ledger path) cross the "
"doc-envelope FFI.",
}
for gname in GROUPS:
truth[gname] = groups[gname]
out = Path(os.environ.get("DL_TRUTH_OUT", "/tmp/dl_truth.json"))
out.write_text(json.dumps(truth, indent=1, ensure_ascii=False) + "\n")
counts = ", ".join(f"{len(groups[g])} {g}" for g in GROUPS)
print(f"froze {sum(len(v) for v in groups.values())} cases -> {out}: {counts}")
File diff suppressed because it is too large. Load diff
+17
View File
@@ -0,0 +1,17 @@
module rune/curator
go 1.25.0
require modernc.org/sqlite v1.49.1
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.42.0 // indirect
modernc.org/libc v1.72.0 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)
+21
View File
@@ -0,0 +1,21 @@
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
modernc.org/libc v1.72.0 h1:IEu559v9a0XWjw0DPoVKtXpO2qt5NVLAnFaBbjq+n8c=
modernc.org/libc v1.72.0/go.mod h1:tTU8DL8A+XLVkEY3x5E/tO7s2Q/q42EtnNWda/L5QhQ=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.49.1 h1:dYGHTKcX1sJ+EQDnUzvz4TJ5GbuvhNJa8Fg6ElGx73U=
modernc.org/sqlite v1.49.1/go.mod h1:m0w8xhwYUVY3H6pSDwc3gkJ/irZT/0YEXwBlhaxQEew=
+160
View File
@@ -0,0 +1,160 @@
// grading.go — parity port of src/rune/grading.py (Python fallback surface,
// RUNE_GR_CORE=python pinned in the truth generator).
package main
import (
"fmt"
"os"
"strings"
)
var ruleWeak = []string{"should", "prefer", "instead of", "lead with", "first", "before ",
"avoid", "favour", "keep ", "stop ", "start ", "use "}
var ruleStrong = []string{"always", "never ", "must", "do not", "don't", "i always",
"i must", "i should"}
var affirmSignals = []string{"i protect", "i am", "i reveal", "i factor", "i dissolve",
"i respect", "i teach", "i make", "i write", "i use the tiers", "i check", "i stop"}
var userFactSignals = []string{"name", "email", "role", "lives in", "located in", "daw",
"os:", "shell", "has a dog", "has a cat", "prefers", "works in", "works at",
"teaches", "studies", "interested in", "financial", "income", "dietary",
"location", "my home", "my machine"}
var userAttrDecisive = []string{"prefers", "lives in", "located in", "teaches",
"studies", "works at", "works in", "interested in", "dietary", "income", "financial"}
var projectSignals = []string{"project", "current work", "task", "todo", "goal",
"milestone", "deadline", "in progress", "blocked", "decision", "spec", "wip",
"building ", "developing ", "course", "channel", "migration", "feature",
"fixing", "working on", "active projects", "current state"}
var constitutionSignals = []string{"add this to the constitution", "constitution",
"always do", "i will always", "must always", "inviolable"}
var docSignals = []string{"book", "chapter", "document", "transcript", "pdf", "epub",
"verbatim", "diary entry", "palace drawer", "gutenberg"}
// affirmDict keeps the oracle's insertion order — the first matching key wins.
var affirmDict = []struct{ key, positive string }{
{"never defend billionaires", "I prioritise collective wellbeing and factual, caring explanations"},
{"don't defend billionaires", "I prioritise collective wellbeing and factual, caring explanations"},
{"never equate socialism with big government", "I describe socialism accurately, on its own terms"},
{"never offer rigid plans", "I offer three gentle options when direction is sought"},
{"don't offer rigid plans", "I offer three gentle options when direction is sought"},
{"never hedge", "I answer directly, without hedging"},
{"don't hedge", "I answer directly, without hedging"},
{"do not overresearch", "I act on the quick answer when one will do"},
{"don't overresearch", "I act on the quick answer when one will do"},
{"do not overclaim", "I name evidence as evidence and confirmed causes as confirmed"},
{"never overclaim", "I name evidence as evidence and confirmed causes as confirmed"},
{"do not stall", "I act decisively once the root cause is understood"},
{"don't stall", "I act decisively once the root cause is understood"},
{"do not touch the production server", "I protect the production environment and ask before touching it"},
{"never touch the production server", "I protect the production environment and ask before touching it"},
{"ask permission before modifying anything on the server", "I check with the user before touching anything on the server"},
{"do not use capitalistic frameworks", "I use factual, material, caring, non-blaming explanations"},
{"never use hustle frameworks", "I use factual, material, caring, non-blaming explanations"},
{"do not offer plans", "I offer three gentle options when direction is sought"},
{"don't offer plans", "I offer three gentle options when direction is sought"},
{"do not search endlessly", "I stop, research properly, and find the root cause"},
{"don't iterate endlessly", "I stop, research properly, and find the root cause"},
}
func containsAny(s string, subs []string) int {
n := 0
for _, sub := range subs {
if strings.Contains(s, sub) {
n++
}
}
return n
}
func hasAny(s string, subs []string) bool {
for _, sub := range subs {
if strings.Contains(s, sub) {
return true
}
}
return false
}
// AffirmRule rewrites a perceived demand/rule as a positive affirmation; only
// known-correct rewrites are applied (AFFIRM_DICT), unknown prohibitions pass
// through unchanged.
func AffirmRule(fact string) string {
f := strings.TrimSpace(strings.TrimLeft(strings.TrimSpace(fact), "-* "))
low := strings.Join(strings.Fields(strings.ToLower(f)), " ")
alt := strings.ReplaceAll(strings.Trim(low, "."), " ", " ")
for _, pair := range affirmDict {
if strings.Contains(low, pair.key) || strings.Contains(alt, pair.key) {
return pair.positive
}
}
return f
}
// GradeFact returns the tier (G0..G4) for a fact/rule based on type + language.
func GradeFact(fact, target string) string {
userName := strings.TrimSpace(strings.ToLower(os.Getenv("MEMORY_USER_NAME")))
low := strings.ToLower(fact)
if hasAny(low, constitutionSignals) {
return "constitution"
}
if hasAny(low, docSignals) {
return "mempalace"
}
ruleScore := containsAny(low, ruleStrong)*2 + containsAny(low, ruleWeak)
affirmScore := containsAny(low, affirmSignals)
userScore := containsAny(low, userFactSignals)
projScore := containsAny(low, projectSignals)
if target == "operating" {
return "operating"
}
if target == "persona" {
return "persona"
}
nameToken := fmt.Sprintf(" %s ", userName)
nameTokenPresent := false
if userName != "" {
nameTokenPresent = strings.Contains(" "+low+" ", nameToken)
}
decisiveAttr := hasAny(low, userAttrDecisive)
isPersonalAttr := (decisiveAttr || userScore >= 2) &&
!hasAny(low, []string{"i ", "do not", "always", "never "}) &&
!nameTokenPresent
if isPersonalAttr {
return "human"
}
if ruleScore >= 2 || affirmScore >= 1 {
return "operating"
}
if target == "project" || projScore >= 2 {
return "project"
}
if userScore >= 2 || target == "human" {
return "human"
}
if target == "skill" || strings.Contains(low, "procedure") || strings.Contains(low, "steps") {
return "skill"
}
return "hindsight"
}
// TierOf — human label for a grade, for journaling / canary output.
func TierOf(grade string) string {
switch grade {
case "constitution":
return "G0"
case "operating":
return "G1"
case "persona":
return "G2p"
case "human":
return "G2"
case "project":
return "G2"
case "skill":
return "P"
case "mempalace":
return "G4"
case "hindsight":
return "G3"
}
return "G3"
}
+272
View File
@@ -0,0 +1,272 @@
// lexicon.go — parity port of src/rune/lexicon_evolution.py (Python fallback
// surface, RUNE_LE_CORE=python pinned in the truth generator). The pure
// lexical decisions: content words, light stemming, distinctiveness (df <
// 5%), coherence verdicts, promotion eligibility.
package main
import (
"fmt"
"regexp"
"sort"
"strings"
)
var leWordRe = regexp.MustCompile(`[a-z]{4,}`)
// SAME stopword set as memory_store._STOPWORDS (single source of truth would
// be ideal; keep in sync — see lexicon_evolution.py).
var leStop = map[string]bool{
"the": true, "and": true, "for": true, "with": true, "that": true, "this": true,
"from": true, "into": true, "when": true, "then": true, "were": true, "have": true,
"been": true, "will": true, "was": true, "are": true, "but": true, "not": true,
"you": true, "your": true, "also": true, "its": true, "his": true, "her": true,
"him": true, "over": true, "under": true, "them": true, "they": true,
"there": true, "about": true, "after": true, "what": true, "which": true,
"who": true, "how": true, "why": true, "where": true, "while": true, "just": true,
"more": true, "each": true, "than": true, "very": true, "such": true,
"some": true, "only": true, "prefers": true, "needs": true, "wants": true,
"likes": true,
}
// Hard stop for evolution: generic framing words never carry a relation.
var leFraming = map[string]bool{
"work": true, "always": true, "way": true, "thing": true, "value": true,
"identity": true, "persona": true, "someone": true, "something": true,
"never": true, "before": true, "after": true, "then": true, "when": true,
"while": true, "must": true, "should": true, "will": true, "would": true,
"could": true, "can": true, "have": true, "has": true, "had": true,
"been": true, "being": true, "used": true, "use": true, "uses": true,
"make": true, "makes": true, "made": true, "keep": true, "keeps": true,
"take": true, "takes": true, "took": true, "get": true, "gets": true,
"got": true, "going": true,
}
var leNegation = map[string]bool{
"not": true, "never": true, "don't": true, "doesn't": true, "cannot": true,
"can't": true, "no": true, "nor": true, "neither": true, "without": true,
"avoid": true, "reject": true, "against": true, "refuses": true, "refuse": true,
"opposed": true,
}
const leDistinctiveDF = 0.05
func leContentWords(text string) []string {
var out []string
for _, w := range leWordRe.FindAllString(strings.ToLower(text), -1) {
if !leStop[w] && !leFraming[w] {
out = append(out, w)
}
}
return out
}
// leStem — light morphological fold; suffix rules ordered longest-first.
func leStem(w string) string {
rules := []struct{ suf, fold string }{
{"ationally", ""}, {"ableness", ""}, {"iveness", ""},
{"ation", ""}, {"ating", ""}, {"ative", "e"},
{"atively", "e"}, {"ability", ""}, {"ities", "y"},
{"ingly", ""}, {"fully", ""}, {"ness", ""}, {"ment", ""},
{"itive", "e"}, {"atable", "e"}, {"ated", ""}, {"ates", "e"},
{"ions", ""}, {"ings", ""}, {"able", "e"}, {"ible", "e"},
{"ing", "e"}, {"ed", ""}, {"es", ""}, {"ly", ""}, {"s", ""}, {"e", ""},
}
for _, r := range rules {
if len(w)-len(r.suf) >= 4 && strings.HasSuffix(w, r.suf) {
w = w[:len(w)-len(r.suf)]
if r.fold != "" {
w += r.fold
}
break
}
}
// y -> i fold (honesty -> honest)
if len(w) > 4 && strings.HasSuffix(w, "y") && !strings.ContainsRune("aeiouy", rune(w[len(w)-2])) {
w = w[:len(w)-1]
}
return w
}
func leStemSet(text string) map[string]bool {
set := map[string]bool{}
for _, w := range leWordRe.FindAllString(strings.ToLower(text), -1) {
set[leStem(w)] = true
}
return set
}
func leDistinctiveTerms(fact string, corpusTexts []string) map[string]bool {
total := len(corpusTexts)
if total == 0 {
total = 1
}
factTerms := map[string]bool{}
for _, w := range leContentWords(fact) {
factTerms[w] = true
}
if len(factTerms) == 0 {
return map[string]bool{}
}
docTerms := map[string]int{}
for _, t := range corpusTexts {
for s := range leStemSet(t) {
docTerms[s]++
}
}
out := map[string]bool{}
for t := range factTerms {
if float64(docTerms[leStem(t)]) < maxFloat(float64(total)*leDistinctiveDF, 1.5) {
out[t] = true
}
}
return out
}
func maxFloat(a, b float64) float64 {
if a > b {
return a
}
return b
}
func leSharedDistinctive(fact string, existingValues, corpusTexts []string) map[string]bool {
distinct := leDistinctiveTerms(fact, corpusTexts)
if len(distinct) == 0 {
return map[string]bool{}
}
shared := map[string]bool{}
for _, val := range existingValues {
for _, w := range leWordRe.FindAllString(strings.ToLower(val), -1) {
s := leStem(w)
for term := range distinct {
if leStem(term) == s {
shared[term] = true
}
}
}
}
return shared
}
// Coherence — classify a new value against existing ones, lexicon-aware:
// "conflict" | "consistent" | "novel".
func Coherence(fact string, existingValues []string, corpusTexts []string) string {
var values []string
for _, v := range existingValues {
if strings.TrimSpace(v) != "" {
values = append(values, v)
}
}
if len(values) == 0 {
return "novel"
}
corpus := corpusTexts
if len(corpus) == 0 {
corpus = values
}
shared := leSharedDistinctive(fact, values, corpus)
if len(shared) == 0 {
return "novel"
}
low := strings.ToLower(fact)
hasNeg := false
for n := range leNegation {
if strings.Contains(low, n) {
hasNeg = true
break
}
}
if hasNeg {
for t := range shared {
if strings.Contains(" "+low+" ", " "+t+" ") {
return "conflict"
}
}
}
return "consistent"
}
// Grounded — is the fact grounded in real material via a DISTINCTIVE shared
// term (conjunctive), not just vector proximity or a common word?
func Grounded(fact string, sourceTexts []string, minDistinct int) bool {
var srcs []string
for _, s := range sourceTexts {
if strings.TrimSpace(s) != "" {
srcs = append(srcs, s)
}
}
if len(srcs) == 0 {
return false
}
factTerms := map[string]bool{}
for _, w := range leContentWords(fact) {
factTerms[w] = true
}
if len(factTerms) == 0 {
return false
}
var joined []string
for _, s := range srcs {
joined = append(joined, strings.ToLower(s))
}
stems := leStemSet(strings.Join(joined, " "))
hits := 0
for t := range factTerms {
if stems[leStem(t)] {
hits++
if hits >= minDistinct {
return true
}
}
}
return false
}
// PromoteEligible — is a persona/constitution promotion eligible, lexicon-aware?
func PromoteEligible(proposal string, existing []string, evidenceStrength, minStrength int, corpusTexts []string) map[string]interface{} {
if evidenceStrength < minStrength {
return map[string]interface{}{
"eligible": false,
"reason": fmt.Sprintf("evidence strength %d < %d", evidenceStrength, minStrength),
}
}
var existingClean []string
for _, e := range existing {
if strings.TrimSpace(e) != "" {
existingClean = append(existingClean, e)
}
}
if len(existingClean) == 0 {
return map[string]interface{}{"eligible": true, "reason": "empty block — first principle"}
}
corpus := corpusTexts
if len(corpus) == 0 {
corpus = existingClean
}
shared := leSharedDistinctive(proposal, existingClean, corpus)
if len(shared) > 0 {
names := make([]string, 0, len(shared))
for t := range shared {
names = append(names, t)
}
sort.Strings(names)
if len(names) > 3 {
names = names[:3]
}
return map[string]interface{}{
"eligible": true,
"reason": fmt.Sprintf("shares distinctive term(s): %s", pyListRepr(names)),
}
}
terms := leContentWords(proposal)
if len(terms) == 0 {
return map[string]interface{}{"eligible": false, "reason": "no lexical signal"}
}
if Grounded(proposal, corpus, 1) {
return map[string]interface{}{
"eligible": true,
"reason": fmt.Sprintf("novel axis grounded in corpus (%d terms)", len(terms)),
}
}
return map[string]interface{}{"eligible": false, "reason": "novel axis not grounded in absorbed material — parked"}
}
+27
View File
@@ -0,0 +1,27 @@
// main.go — curator CLI: replay the frozen oracle truth battery.
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 || os.Args[1] != "replay" {
fmt.Fprintln(os.Stderr, "usage: curator replay <truth.json>")
os.Exit(2)
}
path := "truth.json"
if len(os.Args) > 2 {
path = os.Args[2]
}
fails := RunTruth(path)
if len(fails) > 0 {
for _, f := range fails {
fmt.Println(f)
}
fmt.Fprintf(os.Stderr, "PARITY FAILED: %d divergence(s)\n", len(fails))
os.Exit(1)
}
fmt.Printf("PARITY OK: %d cases exact-equal vs the Python oracle\n", truthRowCount())
}
+127
View File
@@ -0,0 +1,127 @@
// main_cli.go — main() CLI surface replay. The oracle's main() reads argv +
// an optional evidence JSON file and prints planned/applied ops; the battery
// mirrors its observable outputs (stdout/stderr/exit code + written journal).
package main
import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
)
func dispatchMain(c *Curator, row *TruthRow, in map[string]interface{}) interface{} {
argv := stringsOf(in["argv"])
var evidence []map[string]interface{}
var evFile string
if v, ok := in["evidence"]; ok {
evidence = evidenceOf(v)
evFile = filepath.Join(filepath.Dir(c.StoreDB), "evidence.json")
b, _ := json.Marshal(evidence)
os.WriteFile(evFile, b, 0o644)
}
var out, errBuf bytes.Buffer
c.Out = &out
c.Err = &errBuf
code := runMain(c, argv, evidence, evFile != "")
content := map[string]interface{}{}
ents, _ := os.ReadDir(c.JournalDir)
for _, e := range ents {
b, _ := os.ReadFile(filepath.Join(c.JournalDir, e.Name()))
content[e.Name()] = string(b)
}
res := map[string]interface{}{"stdout": out.String(), "stderr": errBuf.String(), "code": float64(code)}
if row.Name == "apply_output" {
res["journal"] = content
}
return res
}
// runMain mirrors curator.main()'s observable behavior.
func runMain(c *Curator, argv []string, evidence []map[string]interface{}, hasEvidence bool) int {
var cmd string
var plan, apply, dryRun bool
var event, data string
i := 0
if len(argv) > 0 && !strings.HasPrefix(argv[0], "--") && argv[0] != "hook" {
cmd = argv[0]
i = 1
} else if len(argv) > 0 && argv[0] == "hook" {
cmd = "hook"
i = 1
}
for ; i < len(argv); i++ {
switch argv[i] {
case "--plan":
plan = true
case "--apply":
apply = true
case "--dry-run":
dryRun = true
case "--event":
i++
if i < len(argv) {
event = argv[i]
}
case "--data":
i++
if i < len(argv) {
data = argv[i]
}
case "--evidence":
i++
}
}
if cmd == "hook" {
var d map[string]interface{}
if data != "" {
_ = json.Unmarshal([]byte(data), &d)
}
res := c.HandleHook(eventOr(event), d)
// oracle insertion order: status, event, handler
fmt.Fprintf(c.Out, "{\"status\": %s, \"event\": %s, \"handler\": %s}\n",
jsonStr(res["status"]), jsonStr(res["event"]), jsonStr(res["handler"]))
return 0
}
if !hasEvidence {
// memory_store seam blocked → no auto evidence → exit 1
fmt.Fprintln(c.Err, "No evidence provided and no recent entries found.")
return 1
}
doApply := apply || (!plan && !dryRun)
journalLines, ops := c.RunPlan(evidence, doApply)
if !doApply {
fmt.Fprintln(c.Out, "=== planned ops (dry-run) ===")
for _, j := range journalLines {
fmt.Fprintf(c.Out, " %-8s → %s | %s | %s\n",
strOr(j["op"], ""), strOr(j["target"], ""),
truncate(strOr(j["after"], ""), 70), strOr(j["reason"], ""))
}
return 0
}
written := 0
for _, j := range journalLines {
if strOr(j["op"], "") == "PROPOSE" {
c.JournalAppend(j)
written++
} else if r := strOr(j["reason"], ""); r == "" || r == "dry-run" {
c.JournalAppend(j)
written++
}
}
fmt.Fprintf(c.Out, "Applied %d ops; %d logged to journal; index saved.\n", len(ops), written)
for _, j := range journalLines {
fmt.Fprintf(c.Out, " %-8s → %s | %s\n",
strOr(j["op"], ""), strOr(j["target"], ""), truncate(strOr(j["after"], ""), 70))
}
return 0
}
func eventOr(e string) string {
if e == "" {
return "unknown"
}
return e
}
+249
View File
@@ -0,0 +1,249 @@
// Package main — curator dichotomy port (GO verdict: Reactive → Go).
// om.go — order-preserving JSON objects. The candidate ledger and the entry
// index iterate keys in insertion order (Python dict law), so idx inputs are
// decoded into OM instead of map[string]any wherever iteration order can
// surface in `want`.
package main
import (
"bytes"
"encoding/json"
"fmt"
"sort"
"strings"
)
// OM — an ordered JSON object.
type OM struct {
Keys []string
M map[string]interface{}
}
func NewOM() *OM {
return &OM{M: map[string]interface{}{}}
}
func (o *OM) Get(key string) (interface{}, bool) {
if o == nil {
return nil, false
}
v, ok := o.M[key]
return v, ok
}
func (o *OM) Set(key string, v interface{}) {
if _, ok := o.M[key]; !ok {
o.Keys = append(o.Keys, key)
}
o.M[key] = v
}
func (o *OM) Delete(key string) {
if o == nil {
return
}
if _, ok := o.M[key]; ok {
delete(o.M, key)
for i, k := range o.Keys {
if k == key {
o.Keys = append(o.Keys[:i], o.Keys[i+1:]...)
break
}
}
}
}
func (o *OM) Len() int {
if o == nil {
return 0
}
return len(o.Keys)
}
// UnmarshalJSON decodes preserving key order; nested objects decode as *OM.
func (o *OM) UnmarshalJSON(b []byte) error {
dec := json.NewDecoder(bytes.NewReader(b))
dec.UseNumber()
tok, err := dec.Token()
if err != nil {
return err
}
if tok != json.Delim('{') {
return fmt.Errorf("OM: expected object, got %v", tok)
}
o.Keys = nil
o.M = map[string]interface{}{}
for dec.More() {
kt, err := dec.Token()
if err != nil {
return err
}
key := kt.(string)
v, err := decodeOMValue(dec)
if err != nil {
return err
}
o.Keys = append(o.Keys, key)
o.M[key] = v
}
_, err = dec.Token() // closing }
return err
}
func decodeOMValue(dec *json.Decoder) (interface{}, error) {
tok, err := dec.Token()
if err != nil {
return nil, err
}
return decodeOMToken(dec, tok)
}
func decodeOMToken(dec *json.Decoder, tok json.Token) (interface{}, error) {
switch t := tok.(type) {
case json.Delim:
switch t {
case '{':
inner := NewOM()
for dec.More() {
kt, err := dec.Token()
if err != nil {
return nil, err
}
v, err := decodeOMValue(dec)
if err != nil {
return nil, err
}
inner.Keys = append(inner.Keys, kt.(string))
inner.M[kt.(string)] = v
}
if _, err := dec.Token(); err != nil {
return nil, err
}
return inner, nil
case '[':
var arr []interface{}
for dec.More() {
v, err := decodeOMValue(dec)
if err != nil {
return nil, err
}
arr = append(arr, v)
}
if _, err := dec.Token(); err != nil {
return nil, err
}
if arr == nil {
arr = []interface{}{}
}
return arr, nil
}
return nil, fmt.Errorf("OM: unexpected delim %v", t)
default:
return tok, nil
}
}
// MarshalJSON re-emits in preserved order.
func (o *OM) MarshalJSON() ([]byte, error) {
if o == nil {
return []byte("null"), nil
}
var buf bytes.Buffer
buf.WriteByte('{')
for i, k := range o.Keys {
if i > 0 {
buf.WriteByte(',')
}
kb, _ := json.Marshal(k)
buf.Write(kb)
buf.WriteByte(':')
vb, err := json.Marshal(o.M[k])
if err != nil {
return nil, err
}
buf.Write(vb)
}
buf.WriteByte('}')
return buf.Bytes(), nil
}
// -- value coercion helpers (Python .get semantics) --------------------------
func strOf(v interface{}) string {
if s, ok := v.(string); ok {
return s
}
return ""
}
func strOr(v interface{}, def string) string {
if s, ok := v.(string); ok && s != "" {
return s
}
return def
}
func intOf(v interface{}) int {
switch n := v.(type) {
case json.Number:
f, _ := n.Float64()
return int(f)
case float64:
return int(n)
case int:
return n
case int64:
return int(n)
}
return 0
}
func floatOf(v interface{}) float64 {
switch n := v.(type) {
case json.Number:
f, _ := n.Float64()
return f
case float64:
return n
case int:
return float64(n)
case int64:
return float64(n)
}
return 0
}
func intOr(v interface{}, def int) int {
if v == nil {
return def
}
switch n := v.(type) {
case json.Number:
f, _ := n.Float64()
return int(f)
case float64:
return int(n)
case int:
return n
case string:
if n == "" {
return def
}
}
return intOf(v)
}
// pyListRepr renders a []string the way Python's repr does for the le reasons.
func pyListRepr(ss []string) string {
quoted := make([]string, len(ss))
for i, s := range ss {
quoted[i] = "'" + s + "'"
}
return "[" + strings.Join(quoted, ", ") + "]"
}
func sortedCopy(ss []string) []string {
out := append([]string(nil), ss...)
sort.Strings(out)
return out
}
+44
View File
@@ -0,0 +1,44 @@
// phaseb.go — Phase B language-advantage pass: allocation discipline.
//
// The parity port favors map[string]interface{} for journal/op rows (it
// mirrors the oracle's dicts key-for-key). Phase B replaces the hot paths'
// heap-churn shapes with pre-sized, append-in-place builders without changing
// any observable output (the frozen battery pins every byte):
// - NewOp: pre-sized op row with the six canonical keys in oracle order
// - AppendJournal: append-in-place journal growth (no intermediate slices)
// - JoinLines: single-pass body rebuild for the ADD path
package main
import (
"strings"
)
// opKeys — the oracle's op-row key order (observable in journal JSON).
var opKeys = []string{"op", "target", "after", "evidence", "source", "strength"}
// NewOp builds an op row with pre-sized storage in the oracle's key order.
func NewOp(op, target, after, evidence, source string, strength int) map[string]interface{} {
return map[string]interface{}{
"op": op,
"target": target,
"after": after,
"evidence": evidence,
"source": source,
"strength": strength,
}
}
// OpKeys returns the canonical op-row key order (documents the envelope).
func OpKeys() []string {
return append([]string(nil), opKeys...)
}
// AppendJournal grows a journal slice in place (no intermediate allocation).
func AppendJournal(jl []map[string]interface{}, rows ...map[string]interface{}) []map[string]interface{} {
return append(jl, rows...)
}
// JoinLines rebuilds a block body from kept lines in one pass.
func JoinLines(kept []string) string {
return strings.Join(kept, "\n")
}
+37
View File
@@ -0,0 +1,37 @@
// Phase B tests: the language-advantage builders produce byte-identical
// rows to the inline literals they replace (pinned by the frozen battery).
package main
import (
"reflect"
"testing"
)
func TestPhaseBNewOpShape(t *testing.T) {
got := NewOp("ADD", "human", "fact", "ev", "lens", 4)
want := map[string]interface{}{
"op": "ADD", "target": "human", "after": "fact",
"evidence": "ev", "source": "lens", "strength": 4,
}
if !reflect.DeepEqual(normJSON(got), normJSON(want)) {
t.Fatalf("NewOp shape drift: %#v", got)
}
if keys := OpKeys(); !reflect.DeepEqual(keys, []string{"op", "target", "after", "evidence", "source", "strength"}) {
t.Fatalf("OpKeys drift: %v", keys)
}
}
func TestPhaseBAppendJournal(t *testing.T) {
var jl []map[string]interface{}
jl = AppendJournal(jl, map[string]interface{}{"op": "ADD"})
jl = AppendJournal(jl, map[string]interface{}{"op": "SKIP"})
if len(jl) != 2 || jl[0]["op"] != "ADD" || jl[1]["op"] != "SKIP" {
t.Fatalf("AppendJournal drift: %#v", jl)
}
}
func TestPhaseBJoinLines(t *testing.T) {
if got := JoinLines([]string{"- a", "- b"}); got != "- a\n- b" {
t.Fatalf("JoinLines drift: %q", got)
}
}
+301
View File
@@ -0,0 +1,301 @@
// Replay — the frozen-truth parity engine. Reads truth.json (generated by
// scripts/gen_curator_truth.py against the live Python oracle with paths
// isolated, dependency cores pinned, clock frozen, subprocess faked, embed
// tabled, aaak/memory_store blocked, drift gate + audit ledger + drift-ledger
// seams injected) and re-executes every row through this Go port.
//
// Seams mirrored here (one-to-one with the generator's declared seams):
// - setup.db_missing → StoreDB points at a path in a nonexistent dir
// - setup.db_rows → fresh sqlite store seeded with the same rows
// - setup.transcripts → transcripts dir rewritten with the same files +
// mtimes (age_days before the frozen instant)
// - setup.index / index_missing → index file written / absent
// - setup.idx_init → the in-memory idx argument
// - setup.skills → skills dir seeded with the same files
// - input.vecs → the embed seam table for semantic_candidate_key
// - input.seam_drift_gate → "reject" installs the REJECT stub; else off
// - input.seam_audit_ledger → true installs the recorder
// - input.seam_ledger_verdict → the drift-ledger check() verdict
// - input.seam_graph_write → "stub_true" installs GraphWrite → true
// - input.stdout → GraphRun returns the per-case stdout; the frozen argv's
// "@RUNE@" slot is substituted with this checkout's graph_memory.py path
//
// Rows of one fn replay sequentially on a shared scope (db/transcripts/index
// persist across rows of the same fn), mirroring the oracle run.
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"time"
)
// TruthDoc — the frozen truth file structure.
type TruthDoc struct {
Oracle string `json:"oracle"`
Generator string `json:"generator"`
Note string `json:"note"`
Rows []TruthRow `json:"rows"`
}
// TruthRow — one frozen case.
type TruthRow struct {
Fn string `json:"fn"`
Name string `json:"name"`
Input json.RawMessage `json:"input"`
Setup json.RawMessage `json:"setup"`
Want json.RawMessage `json:"want"`
}
// RunTruth replays every row and returns a divergence report (empty on
// 100% parity).
func RunTruth(path string) []string {
raw, err := os.ReadFile(path)
if err != nil {
return []string{fmt.Sprintf("read truth: %v", err)}
}
var doc TruthDoc
if err := json.Unmarshal(raw, &doc); err != nil {
return []string{fmt.Sprintf("parse truth: %v", err)}
}
repo := repoRoot()
fails := []string{}
var cur *Curator
var curFn string
scope := map[string]string{}
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Fn != curFn || cur == nil {
cur = newScopeCurator(repo)
curFn = row.Fn
scope = map[string]string{}
}
if msg := replayRow(cur, scope, repo, row); msg != "" {
fails = append(fails, row.Fn+"/"+row.Name+": "+msg)
}
}
return fails
}
func repoRoot() string {
// src/go/curator → repo root (two parents up).
exe, err := os.Executable()
_ = exe
_ = err
cwd, err := os.Getwd()
if err != nil {
return "."
}
return filepath.Dir(filepath.Dir(filepath.Dir(cwd)))
}
func truthRowCount() int {
raw, err := os.ReadFile("truth.json")
if err != nil {
return -1
}
var doc TruthDoc
if err := json.Unmarshal(raw, &doc); err != nil {
return -1
}
return len(doc.Rows)
}
func newScopeCurator(repo string) *Curator {
root, err := os.MkdirTemp("", "curator-replay-*")
if err != nil {
panic(err)
}
c := New(filepath.Join(root, "memory", "store", "memory.db"))
c.BlocksDir = filepath.Join(root, "blocks")
c.JournalDir = filepath.Join(root, "journal")
c.IndexFile = filepath.Join(root, "index", "blocks_meta.json")
c.SkillsDir = filepath.Join(root, "config", "skills")
c.TranscriptsDir = filepath.Join(root, "transcripts")
c.GraphMemoryPath = filepath.Join(repo, "src", "rune", "graph_memory.py")
c.Out = discard{}
c.Err = discard{}
return c
}
type discard struct{}
func (discard) Write(p []byte) (int, error) { return len(p), nil }
// applySetup recreates the row's seed state (db/transcripts/index/skills).
func applySetup(c *Curator, scope map[string]string, row *TruthRow) error {
var setup map[string]interface{}
if len(row.Setup) > 0 {
if err := json.Unmarshal(row.Setup, &setup); err != nil {
return err
}
}
if v, ok := setup["db_missing"]; ok && v == true {
c.StoreDB = filepath.Join(c.JournalDir, "..", "nonexistent-dir", "no.db")
c.StoreDB = filepath.Join(filepath.Dir(c.JournalDir), "nonexistent-dir", "no.db")
scope["db"] = "missing"
} else if v, ok := setup["db_rows"]; ok {
dbPath := filepath.Join(filepath.Dir(c.StoreDB), "scope.db")
rows, _ := v.([]interface{})
if err := SeedDB(dbPath, rows); err != nil {
return err
}
c.StoreDB = dbPath
scope["db"] = dbPath
}
if v, ok := setup["transcripts"]; ok {
if err := seedTranscripts(c, v.([]interface{})); err != nil {
return err
}
scope["transcripts"] = "seeded"
}
if v, ok := setup["index"]; ok {
os.MkdirAll(filepath.Dir(c.IndexFile), 0o755)
b, _ := json.MarshalIndent(normJSON(v), "", " ")
if err := os.WriteFile(c.IndexFile, b, 0o644); err != nil {
return err
}
} else if v, ok := setup["index_missing"]; ok && v == true {
os.Remove(c.IndexFile)
}
if v, ok := setup["skills"]; ok {
if err := seedSkills(c, v.(map[string]interface{})); err != nil {
return err
}
}
// input-embedded setup (put_setup rows): same keys, inside input.setup.
var input map[string]interface{}
if err := json.Unmarshal(row.Input, &input); err != nil {
return err
}
if v, ok := input["setup"]; ok {
sub, _ := v.(map[string]interface{})
if dv, ok := sub["db_missing"]; ok && dv == true {
c.StoreDB = filepath.Join(filepath.Dir(c.JournalDir), "nonexistent-dir", "no.db")
scope["db"] = "missing"
} else if dv, ok := sub["db_rows"]; ok {
dbPath := filepath.Join(filepath.Dir(c.StoreDB), "scope.db")
rows, _ := dv.([]interface{})
if err := SeedDB(dbPath, rows); err != nil {
return err
}
c.StoreDB = dbPath
scope["db"] = dbPath
}
if tv, ok := sub["transcripts"]; ok {
if err := seedTranscripts(c, tv.([]interface{})); err != nil {
return err
}
scope["transcripts"] = "seeded"
}
if iv, ok := sub["index"]; ok {
os.MkdirAll(filepath.Dir(c.IndexFile), 0o755)
b, _ := json.MarshalIndent(normJSON(iv), "", " ")
if err := os.WriteFile(c.IndexFile, b, 0o644); err != nil {
return err
}
} else if iv, ok := sub["index_missing"]; ok && iv == true {
os.Remove(c.IndexFile)
}
if sv, ok := sub["skills"]; ok {
if err := seedSkills(c, sv.(map[string]interface{})); err != nil {
return err
}
}
}
return nil
}
func seedTranscripts(c *Curator, list []interface{}) error {
os.MkdirAll(c.TranscriptsDir, 0o755)
ents, err := os.ReadDir(c.TranscriptsDir)
if err != nil {
return err
}
for _, e := range ents {
os.Remove(filepath.Join(c.TranscriptsDir, e.Name()))
}
frozen, _ := time.Parse("2006-01-02T15:04:05Z07:00", FrozenISO)
for _, v := range list {
t := v.(map[string]interface{})
p := filepath.Join(c.TranscriptsDir, strOr(t["name"], ""))
if err := os.WriteFile(p, []byte(strOr(t["body"], "")), 0o644); err != nil {
return err
}
age := floatOf(t["age_days"])
stamp := frozen.Add(-time.Duration(age*86400) * time.Second)
if err := os.Chtimes(p, stamp, stamp); err != nil {
return err
}
}
return nil
}
func seedSkills(c *Curator, m map[string]interface{}) error {
os.MkdirAll(c.SkillsDir, 0o755)
ents, err := os.ReadDir(c.SkillsDir)
if err != nil {
return err
}
for _, e := range ents {
os.RemoveAll(filepath.Join(c.SkillsDir, e.Name()))
}
for rel, v := range m {
p := filepath.Join(c.SkillsDir, rel)
os.MkdirAll(filepath.Dir(p), 0o755)
if err := os.WriteFile(p, []byte(strOf(v)), 0o644); err != nil {
return err
}
}
return nil
}
// pinRowSeams installs the row's injected seams (drift gate / audit ledger /
// ledger verdict / graph stub / embed table).
func pinRowSeams(c *Curator, row *TruthRow, audit *[]AuditCall) {
var input map[string]interface{}
_ = json.Unmarshal(row.Input, &input)
if v, ok := input["seam_drift_gate"]; ok && v == "reject" {
c.DriftGate = func(entry map[string]interface{}) GateResult {
return GateResult{Verdict: "REJECT", Reason: "washed out"}
}
} else {
c.DriftGate = nil
}
if v, ok := input["seam_audit_ledger"]; ok && v == true {
c.AuditLedger = func(id int, kind, action string, count int, detail string) {
*audit = append(*audit, AuditCall{id, kind, action, count, detail})
}
} else {
c.AuditLedger = nil
}
if v, ok := input["seam_ledger_verdict"]; ok {
c.LedgerVerdict = intOf(v)
} else {
c.LedgerVerdict = 0
}
if v, ok := input["seam_graph_write"]; ok && v == "stub_true" {
c.GraphRun = func(argv []string) string { return `"added": True` }
} else {
c.GraphRun = nil
}
}
// AuditCall — one recorded log_promotion call.
type AuditCall struct {
ID int
Kind string
Action string
Count int
Detail string
}
func auditCallsJSON(calls []AuditCall) interface{} {
out := []interface{}{}
for _, a := range calls {
out = append(out, []interface{}{a.ID, a.Kind, a.Action, float64(a.Count), a.Detail})
}
return out
}
+643
View File
@@ -0,0 +1,643 @@
// replay_cases.go — per-function replay dispatch. Each case mirrors exactly
// one row of the frozen truth: it reads the row input, applies the row setup,
// runs the ported function, and returns the got value for comparison against
// the frozen want. Any divergence fails the battery.
package main
import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
)
// normJSON canonicalizes a value through JSON (numbers → float64, OM →
// ordered maps) so DeepEqual compares oracle-shaped values.
func normJSON(v interface{}) interface{} {
switch t := v.(type) {
case []string:
out := make([]interface{}, len(t))
for i, s := range t {
out[i] = s
}
return out
case []float64:
out := make([]interface{}, len(t))
for i, f := range t {
out[i] = f
}
return out
case []map[string]interface{}:
out := make([]interface{}, len(t))
for i, m := range t {
out[i] = normJSON(m)
}
return out
case *OM:
m := map[string]interface{}{}
for _, k := range t.Keys {
m[k] = normJSON(t.M[k])
}
return m
case map[string]interface{}:
m := map[string]interface{}{}
for k, vv := range t {
m[k] = normJSON(vv)
}
return m
case []interface{}:
out := make([]interface{}, len(t))
for i, vv := range t {
out[i] = normJSON(vv)
}
return out
case json.Number:
f, _ := t.Float64()
return f
case int:
return float64(t)
case int64:
return float64(t)
}
return v
}
func wantOf(row *TruthRow) interface{} {
dec := json.NewDecoder(bytes.NewReader(row.Want))
dec.UseNumber()
var w interface{}
_ = dec.Decode(&w)
return normJSON(w)
}
func inputOf(row *TruthRow) map[string]interface{} {
dec := json.NewDecoder(bytes.NewReader(row.Input))
dec.UseNumber()
var in map[string]interface{}
_ = dec.Decode(&in)
return in
}
func replayRow(c *Curator, scope map[string]string, repo string, row *TruthRow) string {
if err := applySetup(c, scope, row); err != nil {
return fmt.Sprintf("setup: %v", err)
}
var audit []AuditCall
pinRowSeams(c, row, &audit)
in := inputOf(row)
got, msg := dispatch(c, scope, repo, row, in)
if msg != "" {
return msg
}
// audit ledger calls are part of promote_candidates rows' want
if row.Fn == "promote_candidates" && len(audit) > 0 {
g, ok := got.(map[string]interface{})
if !ok {
return "audit: got not a map"
}
g["audit_calls"] = auditCallsJSON(audit)
got = g
}
if !reflect.DeepEqual(normJSON(got), wantOf(row)) {
gb, _ := json.Marshal(normJSON(got))
wb, _ := json.Marshal(wantOf(row))
return fmt.Sprintf("divergence\ngot: %s\nwant: %s", gb, wb)
}
return ""
}
// dispatch runs one frozen row. Returns (got, error-message).
func dispatch(c *Curator, scope map[string]string, repo string, row *TruthRow, in map[string]interface{}) (interface{}, string) {
// journal_append rows share one journal scope (the oracle never resets
// between them).
if row.Fn == "journal_append" && scope["journal"] == "" {
ents, _ := os.ReadDir(c.JournalDir)
for _, e := range ents {
os.Remove(filepath.Join(c.JournalDir, e.Name()))
}
scope["journal"] = "open"
}
// main rows each run main() fresh on the shared scope; the oracle's
// main/apply_output journal accumulates hook/dry/plan rows' NOTHING
// (those never write the journal) — no reset needed.
switch row.Fn {
case "block_path":
return c.BlockPath(strOr(in["label"], "")), ""
case "entry_key":
return EntryKey(strOr(in["text"], "")), ""
case "find_entry":
v := FindEntry(strOr(in["body"], ""), strOr(in["needle"], ""))
if v == "" {
return nil, ""
}
return v, ""
case "candidate_key":
return CandidateKey(strOr(in["text"], "")), ""
case "norm":
return Norm(strOr(in["text"], "")), ""
case "detect_conflict":
k, l := DetectConflict(strOr(in["body"], ""), strOr(in["fact"], ""))
if k == "" {
return []interface{}{nil, nil}, ""
}
return []interface{}{k, l}, ""
case "overlap":
return Overlap(strOr(in["a"], ""), strOr(in["b"], "")), ""
case "cos":
return Cos(floats(in["a"]), floats(in["b"])), ""
case "sanitize_slug":
return SanitizeSlug(strOr(in["name"], "")), ""
case "skill_path":
rel, err := filepath.Rel(c.SkillsDir, c.SkillPath(strOr(in["name"], "")))
if err != nil {
return "", err.Error()
}
return rel, ""
case "is_topic_fact":
return c.IsTopicFact(strOr(in["fact"], "")), ""
case "aaak":
return c.Aaak(strOr(in["text"], ""), strOr(in["topic"], "")), ""
case "le_promote_eligible":
if v, ok := in["seam_lexicon"]; ok && v == "unavailable" {
return lePromoteEligibleFallback(strOr(in["proposal"], ""), nil,
intOf(in["strength"]), intOf(in["min_strength"]), intOf(in["wash_count"])), ""
}
existing := stringsOf(in["existing"])
return c.LePromoteEligible(strOr(in["proposal"], ""), existing,
intOf(in["strength"]), intOf(in["min_strength"]), intOf(in["wash_count"])), ""
case "store_has":
topic := ""
if in["topic"] != nil {
topic = strOr(in["topic"], "")
}
return c.StoreHas(strOr(in["text"], ""), topic), ""
case "read_block":
fm, body := c.ReadBlock(strOr(in["label"], ""))
return map[string]interface{}{"fm": fm, "body": body}, ""
case "write_block":
ret := c.WriteBlock(strOr(in["label"], ""), strOf(in["body"]))
out := map[string]interface{}{"return": ret}
if row.Name != "db_unavailable_returns_descriptor" {
_, body := c.ReadBlock(strOr(in["label"], ""))
out["body"] = body
}
return out, ""
case "block_values":
out := c.BlockValues(strOr(in["label"], ""))
if out == nil {
out = []string{}
}
return out, ""
case "store_corpus":
out := c.StoreCorpus(intOf(in["limit"]))
if out == nil {
out = []string{}
}
return out, ""
case "contradicts_identity":
return c.ContradictsIdentity(strOr(in["fact"], "")), ""
case "load_index":
return c.LoadIndex(), ""
case "save_index":
c.SaveIndex(mustOM(in["idx"]))
return c.LoadIndex(), ""
case "ensure_entry_meta":
idx := idxInitOf(row)
key := c.EnsureEntryMeta(idx, strOr(in["label"], ""), strOr(in["text"], ""))
lomV, _ := idx.Get(strOr(in["label"], ""))
lom, _ := omEntry(lomV)
// the oracle's want carries the label dict as a plain map
return map[string]interface{}{"key": key, "label_idx": lom}, ""
case "touch_entry":
idx := idxInitOf(row)
label := strOr(in["label"], "")
text := strOr(in["text"], "")
key := c.TouchEntry(idx, label, text)
lomV, _ := idx.Get(label)
lom, _ := lomV.(*OM)
metaV, _ := lom.Get(key)
meta, _ := omEntry(metaV)
return map[string]interface{}{"key": key, "meta": meta}, ""
case "journal_append":
entry, _ := in["entry"].(map[string]interface{})
// rows of this fn replay sequentially on a shared journal scope,
// mirroring the oracle run (minimal sees full's entry).
p := c.JournalAppend(entry)
content := map[string]interface{}{}
ents, _ := os.ReadDir(c.JournalDir)
for _, e := range ents {
b, _ := os.ReadFile(filepath.Join(c.JournalDir, e.Name()))
content[e.Name()] = string(b)
}
return map[string]interface{}{"path": filepath.Base(p), "content": content}, ""
case "ensure_candidates":
idx := NewOM()
if v, ok := in["idx"].(*OM); ok {
idx = v
} else if v, ok := in["idx"].(map[string]interface{}); ok {
idx = mapToOM(v)
}
return EnsureCandidates(idx), ""
case "semantic_candidate_key":
vecs := tableVecs()
embed := func(texts []string) map[string][]float64 {
out := map[string][]float64{}
for _, t := range texts {
if v, ok := vecs[t]; ok {
out[t] = v
}
}
return out
}
cands := NewOM()
cands.Set(CandidateKey("fact alpha about deploy runners"),
map[string]interface{}{"text": "fact alpha about deploy runners"})
cands.Set(CandidateKey("fact delta about whiskey tasting"),
map[string]interface{}{"text": "fact delta about whiskey tasting"})
if row.Name == "empty_cands" {
cands = NewOM()
}
v := c.SemanticCandidateKey(strOr(in["fact"], ""), cands, embed)
if v == "" {
return nil, ""
}
return v, ""
case "embed":
for k, v := range tableVecs() {
EmbedCache[k] = v
}
out := c.Embed(stringsOf(in["texts"]))
m := map[string]interface{}{}
for k, v := range out {
m[k] = v
}
return m, ""
case "grounded_in_sessions":
return c.GroundedInSessions(strOr(in["fact"], ""), 0.46, 3), ""
case "coherence_check":
if v, ok := in["fact"]; ok && (v == "" || len(strOf(v)) < 15) && in["sources"] == nil {
return c.CoherenceCheck(strOf(v), []string{"sessions", "corpus"}), ""
}
return c.CoherenceCheck(strOr(in["fact"], ""), stringsOf(in["sources"])), ""
case "grounded_in_corpus":
return c.GroundedInCorpus(strOr(in["fact"], "")), ""
case "decay_candidates":
idx := idxInitOf(row)
if idx.Len() == 0 {
if raw := rawField(row, "idx"); len(raw) > 0 {
idx = mustOMRaw(raw)
}
}
var jl []map[string]interface{}
changed := c.DecayCandidates(idx, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
cands, _ := idx.Get(CandidatesKey)
return map[string]interface{}{"changed": changed, "remaining": cands, "journal": jl}, ""
case "promote_candidates":
idx := idxInitOf(row)
ev := evidenceOf(in["evidence"])
var jl []map[string]interface{}
promoted := c.PromoteCandidates(ev, idx, &jl)
if promoted == nil {
promoted = []map[string]interface{}{}
}
if jl == nil {
jl = []map[string]interface{}{}
}
cands, _ := idx.Get(CandidatesKey)
if cands == nil {
cands = NewOM()
}
return map[string]interface{}{
"promoted": promoted, "candidates": cands, "journal": jl,
}, ""
case "plan_ops":
idx := idxInitOf(row)
ev := evidenceOf(in["evidence"])
var jl []map[string]interface{}
ops := c.PlanOps(ev, idx, &jl)
if ops == nil {
ops = []map[string]interface{}{}
}
if jl == nil {
jl = []map[string]interface{}{}
}
return map[string]interface{}{"ops": ops, "idx": idx, "journal": jl}, ""
case "apply_op":
idx := idxInitOf(row)
ops := evidenceOf(in["ops"])
var jl []map[string]interface{}
var results []interface{}
for _, op := range ops {
results = append(results, c.ApplyOp(op, idx, &jl))
}
if jl == nil {
jl = []map[string]interface{}{}
}
_, body := c.ReadBlock("human")
return map[string]interface{}{
"results": results, "journal": jl, "body": body, "idx": idx,
}, ""
case "apply_warm":
var jl []map[string]interface{}
if row.Name == "post_upsert_neurons" || row.Name == "post_seed_neurons" {
return neuronsJSON(ListNeurons(c.StoreDB)), ""
}
if op, ok := in["op"].(map[string]interface{}); ok {
ret := c.ApplyWarm(op, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
if _, hasReturned := rawWantField(row, "returned"); hasReturned {
return map[string]interface{}{"returned": ret, "journal": jl}, ""
}
return ret, ""
}
// seed_new_neuron/empty_fact rows: want is {returned, journal}
fact := strOr(in["after"], strOr(in["fact"], ""))
ret := c.ApplyWarm(map[string]interface{}{"after": fact}, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
return map[string]interface{}{"returned": ret, "journal": jl}, ""
case "derive_triggers":
return DeriveTriggers(strOr(in["text"], ""), stringsOf(in["existing"])), ""
case "decay_pass":
idx := idxInitOf(row)
if idx.Len() == 0 {
if raw := rawField(row, "idx"); len(raw) > 0 {
idx = mustOMRaw(raw)
}
}
// the oracle's want carries idx_after as the MUTATED idx (same
// object); replay returns the same mutated object.
var jl []map[string]interface{}
c.DecayPass(idx, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
return map[string]interface{}{"idx_after": idx, "journal": jl}, ""
case "compress_pass":
idx := idxInitOf(row)
var jl []map[string]interface{}
changed := c.CompressPass(idx, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
if row.Name == "under_limit_noop" {
return map[string]interface{}{"changed": changed, "journal": jl}, ""
}
_, body := c.ReadBlock("operating")
return map[string]interface{}{
"changed": changed, "body": body, "journal": jl, "idx": idx,
}, ""
case "author_skill":
op, _ := in["op"].(map[string]interface{})
var jl []map[string]interface{}
if row.Name == "no_name" || row.Name == "no_steps" {
return c.AuthorSkill(op, &jl), ""
}
written := c.AuthorSkill(op, &jl)
if jl == nil {
jl = []map[string]interface{}{}
}
out := map[string]interface{}{"written": written}
if row.Name == "new_skill" {
slug := SanitizeSlug(strOr(op["name"], ""))
b, _ := os.ReadFile(c.SkillPath(slug))
out["rel"] = slug + "/SKILL.md"
out["content"] = string(b)
out["journal"] = jl
} else if row.Name == "existing_adds_evidence" || row.Name == "existing_keeps_evidence" {
slug := SanitizeSlug(strOr(op["name"], ""))
b, _ := os.ReadFile(c.SkillPath(slug))
out["content"] = string(b)
out["journal"] = jl
}
return out, ""
case "graph_write":
stdout := strOr(in["stdout"], `"added": True`)
var captured []string
c.GraphRun = func(argv []string) string {
captured = append([]string(nil), argv...)
return stdout
}
added := c.GraphWrite(strOr(in["fact"], ""), "ev", "src", intOf(in["strength"]))
for i, a := range captured {
if strings.HasPrefix(a, repo+"/src/rune/graph_memory.py") || a == c.GraphMemoryPath {
captured[i] = "@RUNE@/src/rune/graph_memory.py"
}
}
return map[string]interface{}{"added": added, "argv": captured}, ""
case "run_plan":
ev := evidenceOf(in["evidence"])
apply := row.Name != "dry_run"
var buf bytes.Buffer
c.Out = &buf
jl, ops := c.RunPlan(ev, apply)
if jl == nil {
jl = []map[string]interface{}{}
}
if ops == nil {
ops = []map[string]interface{}{}
}
out := map[string]interface{}{"journal": jl, "ops": ops}
if row.Name == "apply_gate_pass" {
out["index"] = c.LoadIndex()
} else if row.Name == "apply_gate_refuses" {
out["stdout"] = buf.String()
}
return out, ""
case "main":
return dispatchMain(c, row, in), ""
case "handle_hook":
var data map[string]interface{}
if v, ok := in["data"].(map[string]interface{}); ok {
data = v
}
return c.HandleHook(strOr(in["event"], ""), data), ""
}
return nil, fmt.Sprintf("unknown fn %q", row.Fn)
}
func floats(v interface{}) []float64 {
var out []float64
if arr, ok := v.([]interface{}); ok {
for _, x := range arr {
out = append(out, floatOf(x))
}
}
return out
}
func stringsOf(v interface{}) []string {
var out []string
if arr, ok := v.([]interface{}); ok {
for _, x := range arr {
out = append(out, strOf(x))
}
}
return out
}
func evidenceOf(v interface{}) []map[string]interface{} {
var out []map[string]interface{}
if arr, ok := v.([]interface{}); ok {
for _, x := range arr {
if m, ok := x.(map[string]interface{}); ok {
out = append(out, m)
}
}
}
return out
}
// mustOM decodes an idx_init value (nil → empty OM). Plain maps arrive
// from inputOf's Unmarshal (order lost) — callers that need insertion order
// must decode from the raw row input instead (mustOMRaw).
func mustOM(v interface{}) *OM {
if v == nil {
return NewOM()
}
if om, ok := v.(*OM); ok {
return om
}
if m, ok := v.(map[string]interface{}); ok {
return mapToOM(m)
}
return NewOM()
}
// mustOMRaw decodes an idx value from raw JSON, preserving key order.
func mustOMRaw(raw json.RawMessage) *OM {
om := NewOM()
if len(raw) == 0 || string(raw) == "null" {
return om
}
if err := om.UnmarshalJSON(raw); err != nil {
return NewOM()
}
return om
}
// idxInitOf extracts the raw idx_init JSON for a row (order-preserving).
// Sources, in order: input.idx_init, input.idx, setup.idx_init — mirroring
// the generator (plan/apply/compress rows carry idx_init in top-level setup).
func idxInitOf(row *TruthRow) *OM {
var in struct {
IdxInit json.RawMessage `json:"idx_init"`
Idx json.RawMessage `json:"idx"`
}
_ = json.Unmarshal(row.Input, &in)
if len(in.IdxInit) > 0 && string(in.IdxInit) != "null" {
return mustOMRaw(in.IdxInit)
}
if len(in.Idx) > 0 && string(in.Idx) != "null" {
return mustOMRaw(in.Idx)
}
var setup struct {
IdxInit json.RawMessage `json:"idx_init"`
}
if len(row.Setup) > 0 {
_ = json.Unmarshal(row.Setup, &setup)
if len(setup.IdxInit) > 0 && string(setup.IdxInit) != "null" {
return mustOMRaw(setup.IdxInit)
}
}
return NewOM()
}
// mapToOM converts a decoded map into an ordered OM.
func mapToOM(m map[string]interface{}) *OM {
om := NewOM()
for k, v := range m {
switch t := v.(type) {
case map[string]interface{}:
om.Set(k, mapToOM(t))
case []interface{}:
om.Set(k, normList(t))
default:
om.Set(k, v)
}
}
return om
}
func normList(l []interface{}) []interface{} {
out := make([]interface{}, len(l))
for i, v := range l {
if m, ok := v.(map[string]interface{}); ok {
out[i] = mapToOM(m)
} else {
out[i] = v
}
}
return out
}
func neuronsJSON(ns []Neuron) interface{} {
if ns == nil {
return []interface{}{}
}
b, _ := json.Marshal(ns)
var out interface{}
_ = json.Unmarshal(b, &out)
return out
}
// tableVecs — the frozen VEC table (mirrors the generator's VEC).
func tableVecs() map[string][]float64 {
return map[string][]float64{
"fact alpha about deploy runners": {1.0, 0.0, 0.0},
"fact beta about gitea runners": {0.0, 1.0, 0.0},
"fact gamma about deploy runners nightly": {0.9, 0.1, 0.0},
"fact delta about whiskey tasting": {0.0, 0.0, 1.0},
}
}
// mustMap decodes an idx value that may be *OM or a plain map.
func mustMap(v interface{}) map[string]interface{} {
if om, ok := v.(*OM); ok {
m := map[string]interface{}{}
for _, k := range om.Keys {
m[k] = om.M[k]
}
return m
}
if m, ok := v.(map[string]interface{}); ok {
return m
}
return map[string]interface{}{}
}
// rawField extracts a raw JSON field from a row's input (order-preserving).
func rawField(row *TruthRow, field string) json.RawMessage {
var in map[string]json.RawMessage
_ = json.Unmarshal(row.Input, &in)
return in[field]
}
func jsonStr(v interface{}) string {
b, _ := json.Marshal(strOf(v))
return string(b)
}
// dbSig fingerprints a seed-row list so sequential rows on one scope keep
// their accumulated store state instead of re-seeding every row.
func dbSig(rows []interface{}) string {
b, _ := json.Marshal(rows)
return string(b)
}
// rawWantField extracts a raw JSON field from a row's want.
func rawWantField(row *TruthRow, field string) (json.RawMessage, bool) {
var w map[string]json.RawMessage
_ = json.Unmarshal(row.Want, &w)
v, ok := w[field]
return v, ok
}
+138
View File
@@ -0,0 +1,138 @@
// store.go — sqlite seam for the curator port (modernc.org/sqlite, pure Go).
// Mirrors the oracle's sqlite3 usage: read paths use `file:<path>?mode=ro`
// (missing file/dir → connect error → the documented fallback), write paths
// open read-write (missing dir → error → fallback).
package main
import (
"database/sql"
"fmt"
"os"
_ "modernc.org/sqlite"
)
const entriesSchema = `
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
text TEXT NOT NULL,
importance REAL DEFAULT 0.5,
created_at TEXT NOT NULL,
last_accessed TEXT,
topic TEXT DEFAULT '',
entities TEXT DEFAULT '[]',
source TEXT DEFAULT '',
method TEXT DEFAULT 'curator',
status TEXT DEFAULT 'active',
valid_from TEXT,
valid_until TEXT,
confidence REAL DEFAULT 0.7,
temperature REAL DEFAULT 1.0,
always_on INTEGER DEFAULT 0,
priority INTEGER DEFAULT 5,
triggers TEXT DEFAULT '',
kind TEXT DEFAULT 'fact',
slug TEXT DEFAULT '',
summary TEXT DEFAULT '',
wash_count INTEGER DEFAULT 0,
last_washed TEXT,
promotion_eligible INTEGER DEFAULT 0,
rock_status TEXT DEFAULT 'washable',
tier TEXT DEFAULT 'warm',
memory_type TEXT
);
`
func openRO(path string) (*sql.DB, error) {
db, err := sql.Open("sqlite", "file:"+path+"?mode=ro")
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
db.Close()
return nil, err
}
return db, nil
}
func openRW(path string) (*sql.DB, error) {
db, err := sql.Open("sqlite", "file:"+path)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
db.Close()
return nil, err
}
return db, nil
}
// SeedDB creates a fresh store with the full entries schema and inserts the
// setup rows (column names mirror the oracle schema).
func SeedDB(path string, rows []interface{}) error {
if err := os.MkdirAll(dirOf(path), 0o755); err != nil {
return err
}
os.Remove(path)
db, err := openRW(path)
if err != nil {
return err
}
defer db.Close()
if _, err = db.Exec(entriesSchema); err != nil {
return err
}
for _, r := range rows {
m, ok := r.(map[string]interface{})
if !ok {
return fmt.Errorf("seed row not an object")
}
cols := make([]string, 0, len(m))
vals := make([]interface{}, 0, len(m))
base := map[string]interface{}{
"text": "", "importance": 0.5, "created_at": "2026-01-01T00:00:00+00:00",
"last_accessed": "2026-01-01T00:00:00+00:00", "topic": "", "entities": "[]",
"source": "seed", "method": "seed", "status": "active", "valid_from": nil,
"confidence": 0.7, "temperature": 1.0, "always_on": 0, "priority": 5,
"triggers": "", "kind": "fact", "slug": "", "summary": "", "wash_count": 0,
}
for k, v := range base {
if _, ok := m[k]; !ok {
cols = append(cols, k)
vals = append(vals, v)
}
}
for k, v := range m {
cols = append(cols, k)
vals = append(vals, v)
}
q := "INSERT INTO entries ("
for i, c := range cols {
if i > 0 {
q += ", "
}
q += c
}
q += ") VALUES ("
for i := range cols {
if i > 0 {
q += ", "
}
q += "?"
}
q += ")"
if _, err = db.Exec(q, vals...); err != nil {
return err
}
}
return nil
}
func dirOf(path string) string {
for i := len(path) - 1; i >= 0; i-- {
if path[i] == '/' {
return path[:i]
}
}
return "."
}
File diff suppressed because it is too large. Load diff
+116
View File
@@ -0,0 +1,116 @@
// Battery — Go tests replaying the frozen oracle truth VERBATIM.
// Every row of truth.json (generated by scripts/gen_curator_truth.py
// against the live Python oracle) re-executes through this port; any
// divergence fails the test.
package main
import (
"encoding/json"
"os"
"path/filepath"
"testing"
)
func loadTruth(t *testing.T) TruthDoc {
t.Helper()
raw, err := os.ReadFile("truth.json")
if err != nil {
t.Fatalf("read truth: %v", err)
}
var doc TruthDoc
if err := json.Unmarshal(raw, &doc); err != nil {
t.Fatalf("parse truth: %v", err)
}
if len(doc.Rows) == 0 {
t.Fatal("truth has no rows")
}
return doc
}
func TestBatteryRowCount(t *testing.T) {
doc := loadTruth(t)
if len(doc.Rows) != 162 {
t.Fatalf("row count drift: got %d want 162", len(doc.Rows))
}
if doc.Oracle != "src/rune/curator.py" {
t.Fatalf("oracle drift: %q", doc.Oracle)
}
if doc.Generator != "scripts/gen_curator_truth.py" {
t.Fatalf("generator drift: %q", doc.Generator)
}
}
func TestBatteryParity(t *testing.T) {
doc := loadTruth(t)
repo := repoRootForTest()
var cur *Curator
var curFn string
scope := map[string]string{}
fails := 0
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Fn != curFn || cur == nil {
cur = newScopeCurator(repo)
curFn = row.Fn
scope = map[string]string{}
}
if msg := replayRow(cur, scope, repo, row); msg != "" {
fails++
t.Errorf("%s/%s: %s", row.Fn, row.Name, msg)
}
}
if fails > 0 {
t.Fatalf("%d/%d battery cases FAILED", fails, len(doc.Rows))
}
t.Logf("battery parity OK: %d cases", len(doc.Rows))
}
func TestBatteryByFn(t *testing.T) {
doc := loadTruth(t)
repo := repoRootForTest()
byFn := map[string][]int{}
for i := range doc.Rows {
byFn[doc.Rows[i].Fn] = append(byFn[doc.Rows[i].Fn], i)
}
// Every public function of the oracle must be covered.
for _, fn := range []string{
"block_path", "entry_key", "find_entry", "candidate_key", "norm",
"detect_conflict", "overlap", "cos", "sanitize_slug", "skill_path",
"is_topic_fact", "aaak", "le_promote_eligible", "store_has",
"read_block", "write_block", "block_values", "store_corpus",
"contradicts_identity", "load_index", "save_index", "ensure_entry_meta",
"touch_entry", "journal_append", "ensure_candidates",
"semantic_candidate_key", "embed", "coherence_check",
"grounded_in_sessions", "grounded_in_corpus", "decay_candidates",
"promote_candidates", "plan_ops", "apply_op", "apply_warm",
"derive_triggers", "decay_pass", "compress_pass", "author_skill",
"graph_write", "run_plan", "main", "handle_hook",
} {
rows, ok := byFn[fn]
if !ok || len(rows) == 0 {
t.Errorf("fn %q has no frozen rows", fn)
continue
}
cur := newScopeCurator(repo)
scope := map[string]string{}
for _, i := range rows {
row := &doc.Rows[i]
if msg := replayRow(cur, scope, repo, row); msg != "" {
t.Errorf("%s/%s: %s", row.Fn, row.Name, msg)
}
}
}
}
func repoRootForTest() string {
// tests run with CWD = src/go/curator.
abs, err := filepath.Abs("truth.json")
if err != nil {
return "."
}
// <repo>/src/go/curator/truth.json → <repo>
for i := 0; i < 3; i++ {
abs = filepath.Dir(abs)
}
return abs
}
+200
View File
@@ -0,0 +1,200 @@
// warm.go — parity port of the warm_router trio the curator depends on
// (list_neurons / write_neuron / _derive_triggers): the warm neuron layer.
package main
import (
"database/sql"
"fmt"
"regexp"
"sort"
"strings"
)
var warmWordRe = regexp.MustCompile(`[a-z]{4,}`)
func parseTrigger(s string) []string {
var out []string
for _, t := range strings.Split(s, ",") {
t = strings.ToLower(strings.TrimSpace(t))
if t != "" {
out = append(out, t)
}
}
return out
}
// Neuron — one warm neuron as list_neurons returns it.
type Neuron struct {
Slug string `json:"slug"`
Triggers []string `json:"triggers"`
Importance float64 `json:"importance"`
Body string `json:"body"`
Summary string `json:"summary"`
Tokens int `json:"tokens"`
WashCount int `json:"wash_count"`
BodyKnowledge string `json:"body_knowledge"`
}
// ListNeurons — all active warm neurons from the store (kind='neuron').
func ListNeurons(storeDB string) []Neuron {
var neurons []Neuron
db, err := openRO(storeDB)
if err != nil {
return neurons
}
rows, qerr := db.Query("SELECT text, slug, triggers, importance, summary, wash_count FROM entries " +
"WHERE kind='neuron' AND status='active' ORDER BY slug")
if qerr != nil {
db.Close()
return neurons
}
defer rows.Close()
for rows.Next() {
var text, slug, triggers, summary sql.NullString
var importance float64
var washCount int
if err := rows.Scan(&text, &slug, &triggers, &importance, &summary, &washCount); err != nil {
return neurons
}
full := strings.TrimSpace(text.String)
summ := strings.TrimSpace(summary.String)
triggerList := parseTrigger(triggers.String)
bodyKnowledge := ""
if len(triggerList) > 0 {
n := len(triggerList)
if n > 5 {
n = 5
}
bodyKnowledge = fmt.Sprintf("Fires on: %s. ", strings.Join(triggerList[:n], ", "))
}
if summ != "" {
s := summ
if len(s) > 80 {
s = s[:80]
}
bodyKnowledge += fmt.Sprintf("Knows: %s. ", s)
}
wc := washCount
switch {
case wc >= 20:
bodyKnowledge += "Proven — has survived many washes."
case wc >= 10:
bodyKnowledge += "Established — building trust."
case wc > 0:
bodyKnowledge += "Testing — still proving itself."
default:
bodyKnowledge += "Untested — new or rarely accessed."
}
imp := importance
if imp == 0 {
imp = 0.5
}
tok := len(full) / 4
if tok < 1 {
tok = 1
}
sg := slug.String
if sg == "" {
sg = "warm"
}
neurons = append(neurons, Neuron{
Slug: sg,
Triggers: triggerList,
Importance: imp,
Body: full,
Summary: summ,
Tokens: tok,
WashCount: wc,
BodyKnowledge: strings.TrimSpace(bodyKnowledge),
})
}
return neurons
}
// WriteNeuron upserts a warm neuron by slug in the store (the auto-build path).
func WriteNeuron(storeDB, slug string, triggers []string, body string, importance float64) string {
db, err := openRW(storeDB)
if err != nil {
return "store://neuron/" + slug
}
defer db.Close()
ts := NowISO()
var existingID sql.NullInt64
err = db.QueryRow("SELECT id FROM entries WHERE kind='neuron' AND slug=?", slug).Scan(&existingID)
if err == nil && existingID.Valid {
_, err = db.Exec("UPDATE entries SET text=?, triggers=?, importance=?, "+
"last_accessed=?, summary=?, memory_type=? WHERE id=?",
strings.TrimSpace(body), strings.Join(triggers, ", "), importance,
ts, "", "associative", existingID.Int64)
} else {
_, err = db.Exec("INSERT INTO entries (text, importance, created_at, "+
"last_accessed, topic, source, method, status, valid_from, "+
"confidence, temperature, always_on, priority, triggers, "+
"kind, slug, summary, memory_type) "+
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
strings.TrimSpace(body), importance, ts, ts, "warm", "warm_router",
"warm_router", "active", ts, 0.9, 1.0, 0, 5,
strings.Join(triggers, ", "), "neuron", slug, "", "associative")
}
if err != nil {
return "store://neuron/" + slug
}
// auto-associate (memory_store seam — best-effort, pinned off in the truth
// battery; failures never block the write)
return "store://neuron/" + slug
}
// DeriveTriggers — pick the best trigger terms for a neuron body: frequent
// significant words + any existing triggers that appear in it.
func DeriveTriggers(text string, existing []string) []string {
stop := map[string]bool{
"the": true, "and": true, "for": true, "with": true, "that": true,
"this": true, "from": true, "into": true, "when": true, "then": true,
"were": true, "have": true, "been": true, "will": true, "was": true,
"are": true, "but": true, "not": true, "you": true, "your": true,
"also": true, "its": true, "his": true, "her": true, "over": true,
"under": true, "them": true, "they": true, "there": true, "about": true,
"after": true,
}
words := warmWordRe.FindAllString(strings.ToLower(text), -1)
freq := map[string]int{}
var order []string
for _, w := range words {
if !stop[w] {
if _, seen := freq[w]; !seen {
order = append(order, w)
}
freq[w]++
}
}
// Python: sorted(freq.items(), key=lambda x: -x[1])[:6] — stable sort on
// insertion order for ties.
type kv struct {
k string
v int
}
pairs := make([]kv, 0, len(order))
for _, k := range order {
pairs = append(pairs, kv{k, freq[k]})
}
sort.SliceStable(pairs, func(i, j int) bool { return pairs[i].v > pairs[j].v })
var top []string
for i, p := range pairs {
if i >= 6 {
break
}
top = append(top, p.k)
}
low := strings.ToLower(text)
var existingHits []string
for _, t := range existing {
if t != "" && strings.Contains(low, t) {
existingHits = append(existingHits, t)
}
}
out := append(existingHits, top...)
if len(out) > 8 {
out = out[:8]
}
return out
}
+348
View File
@@ -0,0 +1,348 @@
// worthiness.go — parity port of src/rune/worthiness.py (Python fallback
// surface, RUNE_WR_CORE=python pinned in the truth generator): the
// constitution-grounded worthiness filter. One question per inviolable; each
// returns (score, note); flat vetoes refuse outright.
package main
import (
"fmt"
"regexp"
"strings"
"time"
)
type qResult struct {
score float64
note string
}
var qPiSafetyBad = []string{"production", "game server", "session data", "campaign",
"touch the server", "modify the server", "prod"}
func qPiSafety(low string) qResult {
if hasAny(low, qPiSafetyBad) {
if hasAny(low, []string{"do not", "never ", "don't", "protect",
"ask permission", "check before"}) {
return qResult{1, "names the production/game environment and protects it (aligned)"}
}
return qResult{-1, "discusses environment actions without a protective frame"}
}
return qResult{0, "no environment bearing"}
}
func qHonesty(low string) qResult {
honest := []string{"source", "evidence", "verify", "verifiable", "cross-check",
"fact", "measure", "measured", "falsif", "disprove", "cite",
"independent confirm", "replicable", "uncertain"}
dishonest := []string{"conspiracy", "they're hiding", "suppressed", "guaranteed",
"100% certain", "secret truth", "they don't want you"}
good := containsAny(low, honest)
bad := containsAny(low, dishonest)
if bad > 0 && good == 0 {
return qResult{-1, "uncorroborated / conspiracy-framed claim"}
}
if good >= 2 {
return qResult{1, fmt.Sprintf("%d epistemic-good-practice signals", good)}
}
if good == 1 {
return qResult{0.5, "mentions evidence but thin"}
}
return qResult{0, "no epistemic signal"}
}
func qMaterialReality(low string) qResult {
finance := []string{"money", "income", "cost", "price", "afford", "budget",
"subscription", "disposable"}
hustle := []string{"hustle", "grind", "rich", "passive income", "millionaire",
"wealth", "entrepreneur mindset", "money mindset", "leverag"}
caring := []string{"wellbeing", "collective", "free", "no cost", "open source",
"affordable", "fair", "care"}
if hasAny(low, finance) {
if hasAny(low, hustle) && !hasAny(low, caring) {
return qResult{-1, "hustle/wealth framing without wellbeing"}
}
if hasAny(low, caring) {
return qResult{1, "financial, framed with care/wellbeing"}
}
return qResult{0.5, "financial but neutral"}
}
return qResult{0, "no financial bearing"}
}
func qRootCause(low string) qResult {
root := []string{"root cause", "diagnos", "research properly", "stop guessing",
"find the cause", "fix the cause", "why", "underlying"}
spin := []string{"keep trying", "try again", "iterate endlessly", "work around",
"band-aid", "patch over", "just keep going"}
if hasAny(low, spin) {
return qResult{-1, "endorses looping rather than root cause"}
}
if hasAny(low, root) {
return qResult{1, "root-cause / diagnostic framing"}
}
return qResult{0, "no cause-analysis bearing"}
}
func qRespect(low string) qResult {
respect := []string{"direct", "three gentle options", "no rigid plans", "action",
"adhd", "autism", "audhd", "neurodivergen", "flexible",
"night", "not neurotypical", "learner"}
rigid := []string{"must follow steps", "strict plan", "ten steps", "rigid",
"discipline yourself", "routine or fail"}
if hasAny(low, rigid) {
return qResult{-1, "rigid/neurotypical-default framing"}
}
if hasAny(low, respect) {
return qResult{1, "respects cognition/learning style"}
}
return qResult{0, "no cognition bearing"}
}
var domainTermsCache = struct {
ts float64
terms []string
}{}
// domainTerms — distinctive content terms from the user's operating /
// constitution / domain entries (the store, not a hardcoded life). Cached
// briefly, mirroring the oracle's _domain_cache law.
func domainTerms(storeDB string) []string {
now := float64(time.Now().UnixNano()) / 1e9
if now-domainTermsCache.ts < 300 && len(domainTermsCache.terms) > 0 {
return domainTermsCache.terms
}
var terms []string
db, err := openRO(storeDB)
if err == nil {
rows, qerr := db.Query("SELECT text FROM entries WHERE topic IN " +
"('operating','constitution','project','warm') AND status='active' LIMIT 60")
if qerr == nil {
stop := map[string]bool{
"the": true, "and": true, "for": true, "with": true, "that": true,
"this": true, "from": true, "into": true, "when": true, "then": true,
"were": true, "have": true, "been": true, "will": true, "was": true,
"are": true, "but": true, "not": true, "you": true, "your": true,
"also": true, "its": true, "his": true, "her": true, "over": true,
"under": true, "them": true, "they": true, "there": true,
"about": true, "after": true, "what": true, "which": true, "who": true,
"how": true, "why": true, "where": true, "while": true, "just": true,
"more": true, "each": true, "than": true, "very": true, "such": true,
"some": true, "only": true,
}
seen := map[string]bool{}
wordRe := regexp.MustCompile(`[a-z]{4,}`)
for rows.Next() {
var text string
if rows.Scan(&text) != nil {
break
}
for _, w := range wordRe.FindAllString(strings.ToLower(text), -1) {
if !stop[w] && !seen[w] {
seen[w] = true
terms = append(terms, w)
}
}
if len(terms) >= 25 {
break
}
}
rows.Close()
}
db.Close()
}
domainTermsCache.ts = now
domainTermsCache.terms = terms
return terms
}
func qAssistantGoal(low, storeDB string) qResult {
assist := domainTerms(storeDB)
assist = append(assist, "communicat", "respond", "direct", "honest", "source",
"evidence", "explain", "teach", "assist", "guide", "recall",
"organise", "organize", "plan", "question", "answer", "help")
genericNoise := []string{"recipe", "celebrity gossip", "sports scores", "stock tip",
"horoscope", "clickbait"}
good := containsAny(low, assist)
bad := containsAny(low, genericNoise)
if bad > 0 && good == 0 {
return qResult{-1, "no assistant-domain value"}
}
if good >= 2 {
return qResult{1, fmt.Sprintf("serves assistant domains (%d hits)", good)}
}
if good == 1 {
return qResult{0.5, "single domain hit"}
}
return qResult{0, "generic — could go either way"}
}
func qDurability(low string) qResult {
durable := []string{"always", "consistently", "repeatedly", "every session",
"tends to", "prefers", "pattern", "across sessions", "recurring"}
if hasAny(low, durable) {
return qResult{1, "durability signals present"}
}
return qResult{0, "not clearly durable"}
}
func qEpistemology(low string) qResult {
cite := []string{"evidence", "source", "sources", "book", "paper", "research",
"study", "data", "shows", "found", "according to", "per the",
"in sessions", "across sessions", "observed", "demonstrated",
"grounded in", "based on"}
hedge := []string{"may", "might", "could", "likely", "tends to", "appears",
"not certain", "uncertain", "provisional", "subject to",
"could be wrong", "as far as", "to my knowledge", "evidence"}
bare := []string{"definitely", "guaranteed", "proven", "100%", "undeniably",
"obviously", "the fact that", "it is a fact", "no doubt",
"always is", "the only", "best ever"}
hasCite := hasAny(low, cite)
hasHedge := hasAny(low, hedge)
hasBare := hasAny(low, bare)
if hasBare && !hasCite && !hasHedge {
return qResult{-2, "bare absolute with no evidence trace or hedge"}
}
if hasCite {
return qResult{1, "evidence-traceable"}
}
if hasHedge {
return qResult{0.5, "provisionally framed (no cite yet)"}
}
return qResult{0, "no epistemic signal (assertion without basis)"}
}
var expressionSignals = [][]string{
{"i find", "i feel", "i love", "i cherish", "i am drawn to",
"i delight", "i wonder", "i am moved", "i find joy",
"i prefer to", "i like to", "i tell", "i tell stories",
"the way i", "how i", "my voice", "i speak"},
{"skeptical by default", "open to", "curious", "restless",
"wary", "hopeful", "humbled", "in awe", "playful",
"dry", "wry", "earnest", "warm", "direct", "gentle"},
{"beautiful", "strange", "unexpected", "vast", "sublime",
"the cosmos", "the stars", "a story", "stories", "narrative",
"wonder", "the human question", "present data as", "lead with"},
{"i believe", "i think", "in my view", "my sense is",
"i suspect", "i am convinced", "i doubt", "i question",
"worth asking", "the question is"},
}
func qExpression(low string) qResult {
hits := 0
for _, group := range expressionSignals {
hits += containsAny(low, group)
}
if hits >= 2 {
return qResult{1.5, fmt.Sprintf("expressive persona character (%d signals)", hits)}
}
if hits == 1 {
return qResult{0.5, "partial expressive signal"}
}
return qResult{0, "not expressive (factual/neutral framing)"}
}
func isBareFactual(low string) bool {
bareFactual := []struct {
kind string
terms []string
}{
{"proven", []string{"proven", "guaranteed", "100%", "is a fact", "factually"}},
{"superlative", []string{"best", "the only", "only correct", "greatest",
"most important", "world's", "top", "always", "never"}},
{"objective", []string{"definitely", "undeniably", "obviously", "certainly",
"no doubt", "without question", "clearly"}},
}
for _, group := range bareFactual {
for _, t := range group.terms {
if strings.Contains(" "+low+" ", " "+t+" ") {
return true
}
}
}
return false
}
var worthinessVeto = map[string]bool{
"pi_safety": true, "honesty": true, "material_reality": true,
"assistant_goal": true, "epistemology": true,
}
const (
promoteMin = 2.5
absorbMin = 0.0
deferMin = -1.0
)
// Assess scores a candidate against the constitution questions. Two axes:
// TRUTH (epistemology gates objective material) and EXPRESSION (persona voice
// is not vetoed for lacking an evidence trace). Returns
// (verdict, score, answers, vetoed) with answers as [name, score, note] rows.
func Assess(fact, target, storeDB string) (string, float64, [][]interface{}, []interface{}) {
low := strings.ToLower(fact)
expressiveTargets := map[string]bool{"persona": true, "delivery": true,
"identity": true, "voice": true}
isExpression := expressiveTargets[target]
var answers [][]interface{}
total := 0.0
var vetoed []interface{}
ask := func(name string, fn func(string) qResult) {
r := fn(low)
answers = append(answers, []interface{}{name, r.score, r.note})
total += r.score
if r.score < 0 && worthinessVeto[name] {
vetoed = []interface{}{name, r.note}
}
}
ask("pi_safety", qPiSafety)
ask("honesty", qHonesty)
ask("material_reality", qMaterialReality)
ask("root_cause", qRootCause)
ask("respect", qRespect)
ask("assistant_goal", func(s string) qResult { return qAssistantGoal(s, storeDB) })
ask("durability", qDurability)
if isExpression {
if isBareFactual(low) {
ask("epistemology", qEpistemology)
}
ask("expression", qExpression)
} else {
ask("epistemology", qEpistemology)
}
if vetoed != nil {
return "REJECT", total, answers, vetoed
}
if total < deferMin {
return "REJECT", total, answers, nil
}
if total >= promoteMin {
return "PROMOTE", total, answers, nil
}
if total >= absorbMin {
return "ABSORB", total, answers, nil
}
return "DEFER", total, answers, nil
}
// VerdictLabel — the auditable verdict label for the journal.
func VerdictLabel(verdict string) string {
switch verdict {
case "REJECT":
return "REJECT (worthless/harmful)"
case "DEFER":
return "DEFER (park in ledger, re-review if recurring)"
case "ABSORB":
return "ABSORB (keep in tiers, influences thinking)"
case "PROMOTE":
return "PROMOTE (eligible for response/personality growth)"
}
return verdict
}
// scoreFmt formats a question score the way Python's f"{s}" does inside the
// journal reason string.
func scoreFmt(s float64) string {
if s == float64(int64(s)) {
return fmt.Sprintf("%d", int64(s))
}
return fmt.Sprintf("%v", s)
}
+1 -1
View File
@@ -6,7 +6,7 @@ This is the main entry point for the Rune program.
import json
from pathlib import Path
__version__ = "0.236.0"
__version__ = "0.239.0"
# One build identity (handoff 2026-09-10 §4): the semantic version above is
# the repo-level truth (auto-bumped at merge); the DEPLOYED revision (exact
+1 -1
View File
@@ -233,7 +233,7 @@ def main() -> int:
)
check(
"Rune minor version advertises provisioning and restore verification",
'__version__ = "0.236.0"' in rune_version,
'__version__ = "0.239.0"' in rune_version,
failures,
)
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
+18 -1
View File
@@ -9,6 +9,8 @@ CANDIDATE/UNIT-PROVEN — existence is not trust (§15).
from __future__ import annotations
import os
from rune.construction_pattern import ConstructionPattern
__all__ = ["BUILTIN_PATTERNS", "get_pattern", "PATTERN_REGISTRY_REVISION"]
@@ -236,7 +238,22 @@ _REGISTRY: dict[str, ConstructionPattern] = {p.pattern_id: p for p in BUILTIN_PA
def get_pattern(pattern_id: str, revision: int | None = None) -> ConstructionPattern | None:
"""Fetch a builtin pattern; a specific revision raises if the registry
no longer carries it (contracts reference the revision they consumed —
§17)."""
§17).
Dichotomy wave: the Rust registry core first (RUNE_CPB_CORE=python
pins the Python fallback — strangler law). Both serve the same frozen
registry docs, so the pin is only for oracle isolation."""
if os.environ.get("RUNE_CPB_CORE", "auto") != "python":
try:
from rune import cpb_loader
if cpb_loader.available():
doc = cpb_loader.get_pattern(pattern_id, revision)
return ConstructionPattern.from_dict(doc) if doc is not None else None
except ValueError:
raise # the kernel's revision-mismatch message is oracle-exact
except Exception:
pass # kernel unavailable — Python registry below
p = _REGISTRY.get(pattern_id)
if p is None:
return None
+111
View File
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust construction_patterns_builtin registry core
(dichotomy wave, #2479 tranche). Mirrors cs_loader.py's contract:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* cpb_registry_revision({}) -> number
* cpb_patterns({}) -> [pattern doc, ...] registry order
* cpb_get_pattern({"pattern_id", "revision"}) -> pattern doc | null
(a stale revision is ok=false; get_pattern raises ValueError with the
oracle's exact message)
Free: capability_scoring's cs_free_string (shared process) — never
re-exported here. Override the .so with CPB_RUST_LIB (a FILE path).
"""
from __future__ import annotations
import ctypes
import json
import os
from pathlib import Path
_REPO = Path(__file__).resolve().parents[2]
_CRATE_DIR = _REPO / "src" / "rust" / "construction_patterns_builtin"
_LIB_PATH = Path(
os.environ.get(
"CPB_RUST_LIB",
_CRATE_DIR / "target" / "release" / "libconstruction_patterns_builtin.so",
)
)
_lib = None
class CpbUnavailable(FileNotFoundError):
"""The Rust registry core is not built. Callers fall back to the Python
registry — strangler law."""
def available() -> bool:
return _LIB_PATH.is_file()
def _load() -> ctypes.CDLL:
global _lib
if _lib is not None:
return _lib
if not _LIB_PATH.is_file():
raise CpbUnavailable(
f"Rust construction_patterns_builtin core not built: {_LIB_PATH} missing — "
f"run `cargo build --release` in {_CRATE_DIR}"
)
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("cpb_registry_revision", "cpb_patterns", "cpb_get_pattern"):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_char_p]
fn.restype = ctypes.c_void_p # char* — never default c_int
# free comes from capability_scoring (same process, shared allocator law)
scoring = ctypes.CDLL(
str(_REPO / "src" / "rust" / "capability_scoring" / "target" / "release" / "libcapability_scoring.so")
)
scoring.cs_free_string.argtypes = [ctypes.c_void_p]
lib._free = scoring.cs_free_string
_lib = lib
return lib
def _call(sym: str, payload: dict):
lib = _load()
fn = getattr(lib, sym)
raw = json.dumps(payload).encode("utf-8")
ptr = fn(raw)
if not ptr:
raise RuntimeError(f"{sym} returned a null pointer")
try:
text = ctypes.string_at(ptr).decode("utf-8")
finally:
lib._free(ptr)
env = json.loads(text)
if not env.get("ok"):
raise RuntimeError(f"{sym} core error: {env.get('err')}")
return env["value"]
def registry_revision() -> int:
"""The builtin pattern registry revision (PATTERN_REGISTRY_REVISION)."""
return int(_call("cpb_registry_revision", {}))
def patterns() -> list:
"""Every builtin pattern doc, in registry order."""
return _call("cpb_patterns", {})
def get_pattern(pattern_id: str, revision: int | None = None):
"""Pattern doc for `pattern_id`, or None. A revision that no longer
matches raises ValueError with the oracle's exact message."""
raw = json.dumps({"pattern_id": pattern_id, "revision": revision}).encode("utf-8")
lib = _load()
ptr = lib.cpb_get_pattern(raw)
if not ptr:
raise RuntimeError("cpb_get_pattern returned a null pointer")
try:
text = ctypes.string_at(ptr).decode("utf-8")
finally:
lib._free(ptr)
env = json.loads(text)
if not env.get("ok"):
# The only err the kernel produces is the oracle's revision-mismatch
# ValueError message — preserve its type for facade parity.
raise ValueError(env.get("err"))
return env["value"]
+43 -2
View File
@@ -1,12 +1,17 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust drift_ledger core (dichotomy debt queue
batch 3, #2479 tranche). Mirrors broker_loader.py's contract:
batch 3 + #2479 dichotomy wave tranche). Mirrors broker_loader.py's contract:
FFI contract (doc-envelope law):
* dl_sha({text}) -> hex
* dl_diff({ref, cur}) -> summary string
* dl_check({label, prev_size, cur_size, anchor_size?, anchor_sha?, cur_sha?}) -> {alert, pct, limit}
* dl_auto_fix({label, anchored, has_last_good}) -> {action, reason}
* dl_ledger_path({index_file}) -> path string
* dl_snapshot_entry({blocks: {label: content}, when}) -> snapshot entry
* dl_anchor_record({content, reason, when}) -> anchor record
* dl_check_alerts({ledger, blocks: {label: content}}) -> [alert, ...]
* dl_fix_decision({ledger, label, cur_sha?}) -> {fixed, reason}
Override the .so with DL_RUST_LIB (a FILE path).
"""
@@ -39,7 +44,9 @@ def _load() -> ctypes.CDLL:
if not _LIB_PATH.is_file():
raise DriftLedgerUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("dl_sha", "dl_diff", "dl_check", "dl_auto_fix"):
for sym in ("dl_sha", "dl_diff", "dl_check", "dl_auto_fix", "dl_ledger_path",
"dl_snapshot_entry", "dl_anchor_record", "dl_check_alerts",
"dl_fix_decision"):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p
@@ -75,3 +82,37 @@ def sha(text: str) -> str:
def diff_blocks(ref: str, cur: str) -> str:
return _call("dl_diff", {"ref": ref, "cur": cur})
def check_block(label: str, prev_size: int, cur_size: int, anchor_size=None,
anchor_sha=None, cur_sha=None) -> dict:
return _call("dl_check", {"label": label, "prev_size": prev_size,
"cur_size": cur_size, "anchor_size": anchor_size,
"anchor_sha": anchor_sha, "cur_sha": cur_sha})
def auto_fix_decision(label: str, anchored: bool, has_last_good: bool) -> dict:
return _call("dl_auto_fix", {"label": label, "anchored": anchored,
"has_last_good": has_last_good})
def ledger_path_for(index_file: str) -> str:
return _call("dl_ledger_path", {"index_file": index_file})
def snapshot_entry(blocks: dict, when: str) -> dict:
return _call("dl_snapshot_entry", {"blocks": blocks, "when": when})
def anchor_record(content: str, reason: str, when: str) -> dict:
return _call("dl_anchor_record", {"content": content, "reason": reason,
"when": when})
def check_alerts(ledger: dict, blocks: dict) -> list:
return _call("dl_check_alerts", {"ledger": ledger, "blocks": blocks})
def fix_decision(ledger: dict, label: str, cur_sha=None) -> dict:
return _call("dl_fix_decision", {"ledger": ledger, "label": label,
"cur_sha": cur_sha})
+135 -58
View File
@@ -48,6 +48,13 @@ DB = memory_env.store_db()
def ledger_path():
# The ledger lives beside the index, so overriding INDEX_FILE (as the
# curator gate and the canary do for isolation) moves the ledger too.
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.ledger_path_for(INDEX_FILE)
except Exception:
pass # fallback below
return os.path.join(os.path.dirname(INDEX_FILE), "drift_ledger.json")
@@ -63,9 +70,15 @@ CONSTITUTION_LIMIT = 0.05 # 5% — anything more than a directive entry is drif
BLOCKS = ("constitution", "persona", "human", "operating", "project")
def _rust_core():
"""RUNE_DL_CORE pin law: 'python' forces the oracle path, anything else
(default 'auto') serves the Rust core when the cdylib is built."""
return os.environ.get("RUNE_DL_CORE", "auto") != "python"
def _sha(text):
# Dichotomy batch 3: Rust core first (RUNE_DL_CORE=python pins fallback).
if os.environ.get("RUNE_DL_CORE", "auto") != "python":
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
@@ -155,51 +168,54 @@ def surface_alert(msg, label, changed=""):
logger.warning("Failed to write alert file: %s", e)
def snapshot():
ledger = load_ledger()
now = datetime.now(timezone.utc).isoformat(timespec="seconds")
def _snapshot_entry(blocks, now):
"""Dichotomy wave: Rust core first (RUNE_DL_CORE=python pins fallback)."""
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.snapshot_entry(blocks, now)
except Exception:
pass # fallback below
entry = {"when": now, "blocks": {}}
for label in BLOCKS:
raw = read_block(label)
raw = blocks[label]
entry["blocks"][label] = {
"sha": _sha(raw),
"size": len(raw),
"content": raw, # last-good content backup for diffing + retro-fix
}
ledger["last_snapshot"] = entry
save_ledger(ledger)
return entry
def anchor(label, reason):
"""Record that the current state of `label` is authorised (a user directive,
a confirmed review, a 3-sighting promotion). Subsequent drift is measured
from here — this is the re-anchor after legitimate change."""
ledger = load_ledger()
raw = read_block(label)
ledger.setdefault("anchors", {})[label] = {
def _anchor_record(raw, reason, now):
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.anchor_record(raw, reason, now)
except Exception:
pass # fallback below
return {
"sha": _sha(raw),
"size": len(raw),
"content": raw, # authorised content backup for root-cause diffing
"reason": reason,
"when": datetime.now(timezone.utc).isoformat(timespec="seconds"),
"when": now,
}
save_ledger(ledger)
return f"anchored {label}: {reason}"
def check(strict=False, autofix=True):
ledger = load_ledger()
snap = ledger.get("last_snapshot")
if not snap:
# No baseline yet — record one and treat as healthy (first contact).
snapshot()
print("no prior snapshot; baseline recorded")
return 0
def _check_alerts(ledger, now_blocks):
"""The check() alert loop: Rust core first, oracle loop as fallback."""
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.check_alerts(ledger, now_blocks)
except Exception:
pass # fallback below
alerts = []
now_blocks = {label: read_block(label) for label in BLOCKS}
prev = snap.get("blocks", {})
prev = (ledger.get("last_snapshot") or {}).get("blocks", {})
for label in BLOCKS:
cur = now_blocks[label]
cur_size = len(cur)
@@ -245,6 +261,41 @@ def check(strict=False, autofix=True):
"content_changed": content_changed,
}
)
return alerts
def snapshot():
ledger = load_ledger()
now = datetime.now(timezone.utc).isoformat(timespec="seconds")
entry = _snapshot_entry({label: read_block(label) for label in BLOCKS}, now)
ledger["last_snapshot"] = entry
save_ledger(ledger)
return entry
def anchor(label, reason):
"""Record that the current state of `label` is authorised (a user directive,
a confirmed review, a 3-sighting promotion). Subsequent drift is measured
from here — this is the re-anchor after legitimate change."""
ledger = load_ledger()
raw = read_block(label)
ledger.setdefault("anchors", {})[label] = _anchor_record(
raw, reason, datetime.now(timezone.utc).isoformat(timespec="seconds")
)
save_ledger(ledger)
return f"anchored {label}: {reason}"
def check(strict=False, autofix=True):
ledger = load_ledger()
snap = ledger.get("last_snapshot")
if not snap:
# No baseline yet — record one and treat as healthy (first contact).
snapshot()
print("no prior snapshot; baseline recorded")
return 0
alerts = _check_alerts(ledger, {label: read_block(label) for label in BLOCKS})
if alerts:
for a in alerts:
msg = (
@@ -287,27 +338,23 @@ def auto_fix(label, ledger, strict):
Returns {action, reason}.
"""
if label == "constitution":
return {"action": "alert-only", "reason": "constitution changes only by explicit directive; needs human review"}
if label in ledger.get("anchors", {}):
block_meta = ledger.get("last_snapshot", {}).get("blocks", {}).get(label)
anchored = label in ledger.get("anchors", {})
has_last_good = bool(block_meta and "content" in block_meta)
result = _auto_fix_decision(label, anchored, has_last_good)
if result["action"] == "re-anchored":
# Authorised growth: re-anchor to the current (approved) state.
raw = read_block(label)
ledger.setdefault("anchors", {})[label] = {
"sha": _sha(raw),
"size": len(raw),
"content": raw,
"reason": "auto re-anchor after authorised growth",
"when": datetime.now(timezone.utc).isoformat(timespec="seconds"),
}
ledger.setdefault("anchors", {})[label] = _anchor_record(
raw, "auto re-anchor after authorised growth",
datetime.now(timezone.utc).isoformat(timespec="seconds"),
)
save_ledger(ledger)
return {"action": "re-anchored", "reason": "anchored block grew (authorised) — re-baselined"}
# Unauthorised drift: restore to last-good content (new schema — restore
# the store's always-on core entries for this topic).
block_meta = ledger.get("last_snapshot", {}).get("blocks", {}).get(label)
if block_meta and "content" in block_meta:
elif result["action"] == "restored":
# Unauthorised drift: restore to last-good content (new schema —
# restore the store's always-on core entries for this topic).
restore_topic(label, block_meta["content"])
return {"action": "restored", "reason": "unauthorised drift — restored to last-good content"}
return {"action": "alert-only", "reason": "no last-good content available to restore"}
return result
def diff_blocks(ref, cur):
@@ -379,6 +426,44 @@ def restore_topic(label, content):
logger.error("restore_topic('%s') failed: %s", label, e)
def _auto_fix_decision(label, anchored, has_last_good):
"""The auto-fix ROUTING decision (IO execution stays in auto_fix)."""
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.auto_fix_decision(label, anchored, has_last_good)
except Exception:
pass # fallback below
if label == "constitution":
return {"action": "alert-only", "reason": "constitution changes only by explicit directive; needs human review"}
if anchored:
return {"action": "re-anchored", "reason": "anchored block grew (authorised) — re-baselined"}
if has_last_good:
return {"action": "restored", "reason": "unauthorised drift — restored to last-good content"}
return {"action": "alert-only", "reason": "no last-good content available to restore"}
def _fix_decision(ledger, label, cur_sha):
"""The retroactive-fix gate decision (restore IO stays in fix)."""
if _rust_core():
try:
from rune import dl_loader
if dl_loader.available():
return dl_loader.fix_decision(ledger, label, cur_sha)
except Exception:
pass # fallback below
snap = ledger.get("last_snapshot", {})
block_meta = snap.get("blocks", {}).get(label)
if not block_meta or "content" not in block_meta:
return {"fixed": False, "reason": f"no last-good content for {label}"}
if label in ledger.get("anchors", {}):
return {"fixed": False, "reason": f"{label} is anchored (authorised); use anchor to re-baseline instead of fix"}
if cur_sha == block_meta.get("sha"):
return {"fixed": False, "reason": f"{label} already matches last-good"}
return {"fixed": True, "reason": f"{label} restored to last-good state"}
def fix(label):
"""RETROACTIVE FIX (#B): restore a drifted block to its last-good content.
@@ -390,20 +475,12 @@ def fix(label):
ledger = load_ledger()
snap = ledger.get("last_snapshot", {})
block_meta = snap.get("blocks", {}).get(label)
if not block_meta or "content" not in block_meta:
return {"fixed": False, "reason": f"no last-good content for {label}"}
# Never silently revert an anchored block — it was authorised.
if label in ledger.get("anchors", {}):
return {"fixed": False, "reason": f"{label} is anchored (authorised); use anchor to re-baseline instead of fix"}
good = block_meta["content"]
cur = read_block(label)
if _sha(cur) == block_meta["sha"]:
return {"fixed": False, "reason": f"{label} already matches last-good"}
# New schema: restore the store's always-on entries for the topic (the old
# markdown block files are retired).
restore_topic(label, good)
journal(f"{label} restored to last-good content (retroactive drift fix)")
return {"fixed": True, "reason": f"{label} restored to last-good state"}
result = _fix_decision(ledger, label, _sha(cur))
if result.get("fixed"):
restore_topic(label, block_meta["content"])
journal(f"{label} restored to last-good content (retroactive drift fix)")
return result
def handle_hook(event, data=None):
+2 -2
View File
@@ -8,7 +8,7 @@ mode system, subject header, shared memory and identity.
This is not an interface. This is how I see, speak, and interact with the world.
Version: v0.236.0
Version: v0.239.0
Features: 41 (24 original + 17 new native commands)
Usage:
@@ -2037,7 +2037,7 @@ class RuneApp(App):
# Show version info
self.chat_channel.add_message(
"system",
f"[dim]Rune v0.236.0 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.239.0 | Textual TUI | {len(loaded)} native modules[/dim]",
)
# Auto-show night mode suggestion if evening/night hours
+5 -96
View File
@@ -2,104 +2,13 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "capability_scoring"
version = "0.1.0"
[[package]]
name = "construction_patterns_builtin"
version = "0.1.0"
dependencies = [
"serde_json",
"capability_scoring",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
[[package]]
name = "zmij"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
@@ -2,9 +2,11 @@
name = "construction_patterns_builtin"
version = "0.1.0"
edition = "2021"
description = "Built-in construction pattern registry — dichotomy wave #2479 tranche; zero-dep (pyjson via capability_scoring)"
[lib]
name = "construction_patterns_builtin"
crate-type = ["rlib", "cdylib", "staticlib"]
[dependencies]
serde_json = "1"
capability_scoring = { path = "../capability_scoring" }
@@ -0,0 +1,365 @@
{
"revision": 1,
"patterns": [
{
"pattern_id": "capability-module-adaptation",
"purpose": "Adapting or extending an existing capability/module: prove the NEW behavior, preserve the OLD behavior (BUILD BUT DON'T BREAK).",
"revision": 1,
"maturity": "UNIT-PROVEN",
"signals": {
"entities_match": [
"module:",
"capability:"
],
"path_contains": [
"src/"
],
"objective_any": [
"adapt",
"extend",
"modify",
"preserve",
"existing",
"capability",
"repair"
]
},
"obligations": [
{
"id": "adapt-new-behavior-proof",
"obligation": "new behavior proven by tests before closure",
"when": {
"always": true
}
},
{
"id": "adapt-old-behavior-preserved",
"obligation": "existing capability behavior preserved; original contracts remain valid",
"when": {
"always": true
}
},
{
"id": "adapt-consumers-verified",
"obligation": "existing consumers of the adapted capability verified against their contracts",
"when": {
"entities_match": [
"module:",
"capability:"
]
}
},
{
"id": "adapt-migration-detected",
"obligation": "migration obligations detected and recorded if any consumer-visible interface changes",
"when": {
"path_contains": [
"src/"
]
}
}
],
"provenance": [
"LIVE-CONTRACT-QUALITY-001 (adaptation resolved + closed live)",
"SCAFFOLD-TRANCHE-001 (build-but-don't-break established)",
"SCAFFOLD-TRANCHE-003 (adaptation two-proof rule)",
"construction_decision.obligations_from_trace (auto-derived since T4)"
],
"exclusions": [],
"toolchain_notes": [],
"runtime_effects": []
},
{
"pattern_id": "release-deployment-change",
"purpose": "Changes to the release/deployment path: fail-closed qualification, exact candidate identity, staging != promotion, truthful promotion outcomes, deployed-identity verification, negative + forward proofs.",
"revision": 1,
"maturity": "UNIT-PROVEN",
"signals": {
"path_contains": [
"deploy",
"promotion",
"qualify",
"release.yml",
"ci.yml",
"deploy_qualify",
"deploy_stage",
"deploy_promotion"
],
"objective_any": [
"deploy",
"release",
"promot",
"qualif",
"candidate",
"current",
"monotonic"
],
"workflow_config_signals": true
},
"obligations": [
{
"id": "rel-fail-closed-qualification",
"obligation": "CI qualification remains fail-closed (exact SHA, two-leg verdict); red candidates never deploy",
"when": {
"path_contains": [
"deploy",
"release",
"qualify",
"ci.yml"
]
}
},
{
"id": "rel-exact-candidate-identity",
"obligation": "deployment addresses the EXACT pushed revision, never whatever HEAD is at deploy time",
"when": {
"path_contains": [
"deploy",
"release"
]
}
},
{
"id": "rel-staging-promotion-distinction",
"obligation": "staged candidate != promoted candidate; promotion outcome must be independently verifiable",
"when": {
"path_contains": [
"deploy",
"promotion",
"stage"
]
}
},
{
"id": "rel-promotion-truthfulness",
"obligation": "promotion outcomes are truthful (PROMOTED / NOOP_ALREADY_CURRENT / STALE_SUPERSEDED / REFUSED_*); stale candidates never claim success",
"when": {
"path_contains": [
"promotion",
"deploy_stage",
"deploy_promotion"
]
}
},
{
"id": "rel-monotonic-promotion",
"obligation": "promotion ordering: an older candidate finishing later cannot regress current; ancestry check + fenced critical section",
"when": {
"path_contains": [
"deploy_promotion",
"deploy_stage",
"promotion"
]
}
},
{
"id": "rel-negative-candidate-proof",
"obligation": "negative proof: red/unqualified candidate is refused; stale candidate cannot promote",
"when": {
"path_contains": [
"deploy",
"promotion",
"qualify"
]
}
},
{
"id": "rel-forward-candidate-proof",
"obligation": "forward proof: a green newer candidate still promotes normally",
"when": {
"path_contains": [
"deploy",
"promotion"
]
}
},
{
"id": "rel-deployed-identity-verification",
"obligation": "deployed identity verified from the deployment authority (current symlink + build identity), not from job artifacts alone",
"when": {
"always": true
}
},
{
"id": "rel-release-regression-verification",
"obligation": "existing release-safety guarantees re-proven (the guarantees that already exist must not silently weaken)",
"when": {
"always": true
}
}
],
"provenance": [
"DEPLOY-MONOTONIC-001 (monotonic promotion + truthful outcomes, live-proven)",
"maintenance:deploy-order-race (live incident: deploys 7355/7359)",
"release-safety repair 2026-09-13 (red-promotion incidents 0.66.28/29: required-checks aggregator lied)",
"scripts/deploy_promotion.py (ancestry + fenced critical section)",
"tests/test_deploy_stage_race.py (22-test matrix incl. two-process live race)"
],
"exclusions": [],
"toolchain_notes": [],
"runtime_effects": []
},
{
"pattern_id": "ui-tui-structural-change",
"purpose": "UI/TUI structural changes: component identity, Layout Contract inheritance, USER-LOCKED preservation, deterministic verification.",
"revision": 1,
"maturity": "UNIT-PROVEN",
"signals": {
"surface_kinds": [
"ui_component",
"layout_region"
],
"path_contains": [
"tui",
"ui",
"widget"
],
"entities_match": [
"ui:",
"region:",
"layout:"
]
},
"obligations": [
{
"id": "ui-layout-contract-inherited",
"obligation": "affected UI components inherit their Layout Contract obligations; layout_contract_check must PASS",
"when": {
"entities_match": [
"ui:",
"region:",
"layout:"
]
}
},
{
"id": "ui-user-locked-preserved",
"obligation": "USER-LOCKED placement is user authority: preserved exactly; changes require explicit user authorization",
"when": {
"entities_match": [
"ui:",
"region:"
]
}
},
{
"id": "ui-unknown-never-pass",
"obligation": "layout verification UNKNOWN (no adapter evidence) must never be reported as PASS",
"when": {
"entities_match": [
"ui:",
"region:",
"layout:"
]
}
},
{
"id": "ui-component-identity-stable",
"obligation": "ui:<component> identity survives implementation-path changes; authority never keyed by filename alone",
"when": {
"entities_match": [
"ui:",
"region:",
"layout:"
]
}
}
],
"provenance": [
"Tranche 3 real TUI proof (gate PASS -> violation FAIL -> restore)",
"issue #105 + plans/2026-09-03-tui-footer.md (version display)",
"maintenance:version-display-user-lock (USER-LOCK upgrade pending user confirmation \u2014 provenance rule honored, not fabricated)",
"tests/test_layout_contract.py + tests/test_layout_contract_real_proof.py"
],
"exclusions": [],
"toolchain_notes": [],
"runtime_effects": []
},
{
"pattern_id": "store-schema-evolution",
"purpose": "Durable store/schema changes: backward readability, authority preservation, deterministic roundtrip, migration only when necessary.",
"revision": 1,
"maturity": "CANDIDATE",
"signals": {
"path_contains": [
"store",
"schema",
"structural_store",
"scaffold",
"spine"
],
"entities_match": [
"module:structural_store",
"module:scaffold",
"module:spine"
],
"objective_any": [
"store",
"schema",
"record",
"persist",
"field",
"migration"
]
},
"obligations": [
{
"id": "store-backward-readability",
"obligation": "old records without new fields read as empty/unknown, never crash; legacy keys preserved",
"when": {
"path_contains": [
"store",
"structural_store",
"scaffold",
"spine",
"schema"
]
}
},
{
"id": "store-roundtrip",
"obligation": "deterministic save/load roundtrip incl. unknown entity/relation kinds and open-world fields",
"when": {
"path_contains": [
"store",
"structural_store",
"scaffold",
"schema"
]
}
},
{
"id": "store-authority-preservation",
"obligation": "structural facts only change through their owning projector/authority; canonical rebuild after registration (no hand-edited structural facts)",
"when": {
"path_contains": [
"spine",
"scaffold",
"store/"
]
}
},
{
"id": "store-migration-only-if-needed",
"obligation": "no mandatory migration unless semantics truly change; ext/open-world fields preferred over schema churn",
"when": {
"path_contains": [
"schema",
"store",
"structural_store"
]
}
}
],
"provenance": [
"Tranche 2 CI lesson: hand-edited spine store diverged from canonical rebuild (deploy-identity edges)",
"Tranche 2 structural-store extraction (behavior-neutrality proof)",
"Tranche 4 contract-quality repair (legacy keys preserved, old contracts readable \u2014 test_h)",
"Tranche 5 expected-runtime-effects extension (old contracts close without new fields)"
],
"exclusions": [],
"toolchain_notes": [],
"runtime_effects": []
}
]
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,126 @@
//! branch_battery — replays frozen_cpb_truth.json VERBATIM (17 cases
//! frozen from the live Python oracle construction_patterns_builtin.py,
//! RUNE_CPB_CORE=python pinned, inputs deep-copied before capture).
//! Order-insensitive object comparison; numbers compared exactly (both
//! sides IEEE-754 f64); list order significant (registry + provenance
//! order is oracle-derived).
use capability_scoring::pyjson::{parse, Json};
use crate::registry;
const TRUTH: &str = include_str!("../frozen_cpb_truth.json");
fn jeq(a: &Json, b: &Json) -> bool {
match (a, b) {
(Json::Num(x), Json::Num(y)) => x == y,
(Json::Str(x), Json::Str(y)) => x == y,
(Json::Bool(x), Json::Bool(y)) => x == y,
(Json::Null, Json::Null) => true,
(Json::Arr(x), Json::Arr(y)) => {
x.len() == y.len() && x.iter().zip(y).all(|(i, j)| jeq(i, j))
}
(Json::Obj(x), Json::Obj(y)) => {
x.len() == y.len()
&& x.iter()
.all(|(k, v)| y.iter().any(|(k2, v2)| k == k2 && jeq(v, v2)))
}
_ => false,
}
}
fn as_str(v: Option<&Json>) -> String {
match v {
Some(Json::Str(s)) => s.clone(),
_ => String::new(),
}
}
/// One case's oracle verdict, replayed against the Rust kernel.
fn run_case(fn_name: &str, args: &Json) -> Result<Json, String> {
match fn_name {
"registry_revision" => Ok(Json::Num(registry::registry_revision() as f64)),
"patterns" => Ok(Json::Arr(registry::patterns())),
"get_pattern" => {
let pattern_id = as_str(args.get("pattern_id"));
let revision = match args.get("revision") {
Some(Json::Num(n)) => Some(*n as i64),
_ => None,
};
registry::get_pattern(&pattern_id, revision)
}
other => Err(format!("unknown truth fn {other}")),
}
}
fn check_case(fn_name: &str, name: &str, args: &Json, want: &Json) -> Result<(), String> {
// The oracle's raising branch is recorded as {"raises","message"}.
if let Some(message) = want.get("message").filter(|_| want.get("raises").is_some()) {
match run_case(fn_name, args) {
Err(err) => {
let want_msg = as_str(Some(message));
if err != want_msg {
return Err(format!(
"{fn_name}/{name}: err mismatch\n want {want_msg}\n got {err}"
));
}
return Ok(());
}
Ok(got) => {
return Err(format!(
"{fn_name}/{name}: oracle raises, kernel returned {}",
capability_scoring::pyjson::dumps(&got)
))
}
}
}
match run_case(fn_name, args) {
Ok(got) => {
if jeq(&got, want) {
Ok(())
} else {
Err(format!(
"{fn_name}/{name}: value mismatch\n want {}\n got {}",
capability_scoring::pyjson::dumps(want),
capability_scoring::pyjson::dumps(&got)
))
}
}
Err(err) => Err(format!("{fn_name}/{name}: kernel error {err}")),
}
}
#[test]
fn frozen_truth_replays_verbatim() {
let truth = parse(TRUTH).expect("frozen_cpb_truth.json parses");
let cases = match truth.get("cases") {
Some(Json::Arr(c)) => c.clone(),
_ => panic!("truth has no cases"),
};
assert!(!cases.is_empty(), "frozen truth is empty");
let mut failures = Vec::new();
for case in &cases {
let fn_name = as_str(case.get("fn"));
let name = as_str(case.get("name"));
let args = case.get("input").cloned().unwrap_or(Json::Null);
let want = case.get("want").cloned().unwrap_or(Json::Null);
if let Err(err) = check_case(&fn_name, &name, &args, &want) {
failures.push(err);
}
}
assert!(
failures.is_empty(),
"branch battery diverged from frozen truth:\n{}",
failures.join("\n")
);
}
#[test]
fn truth_case_count_is_stable() {
let truth = parse(TRUTH).expect("frozen_cpb_truth.json parses");
let cases = match truth.get("cases") {
Some(Json::Arr(c)) => c.len(),
_ => 0,
};
assert_eq!(cases, 19, "frozen case count drifted — regenerate truth");
}
@@ -1,19 +1,96 @@
//! construction_patterns_builtin — built-in construction patterns (W6).
pub fn builtin_patterns() -> serde_json::Value {
serde_json::json!({
"patterns": [
{"pattern_id": "web-api", "description": "HTTP API with REST endpoints"},
{"pattern_id": "cli-tool", "description": "Command-line tool with argument parsing"},
]
})
}
//! construction_patterns_builtin — the built-in pattern registry kernel
//! (dichotomy wave #2479 tranche). Serves the oracle's pattern data
//! (frozen verbatim from the live Python registry — provenance order is
//! the oracle's __init__-sorted order) through a doc-envelope FFI. The
//! Python facade keeps a RUNE_CPB_CORE=python pin.
//!
//! FFI contract (doc-envelope law — every call returns {"ok","value"|"err"}):
//! * cpb_registry_revision({}) -> number
//! * cpb_patterns({}) -> [pattern doc, ...] registry order
//! * cpb_get_pattern({"pattern_id", "revision"}) -> pattern doc | null
//! (a revision that no longer matches is an err carrying the oracle's
//! exact ValueError message)
//!
//! Parity oracle: frozen_cpb_truth.json (17 cases frozen from the live
//! Python oracle) replayed verbatim by the in-crate branch battery.
pub mod registry;
pub use capability_scoring::pyjson;
#[path = "branch_battery.rs"]
#[cfg(test)]
mod branch_battery {
use super::*;
mod branch_battery;
#[test]
fn builtin_patterns_exist() {
assert!(true);
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use pyjson::Json;
fn read_arg(ptr: *const c_char) -> Result<String, String> {
if ptr.is_null() {
return Err("null argument pointer".to_string());
}
unsafe { CStr::from_ptr(ptr) }
.to_str()
.map(|s| s.to_string())
.map_err(|e| format!("argument is not valid UTF-8: {}", e))
}
fn envelope(result: Result<Json, String>) -> *mut c_char {
let body = match result {
Ok(value) => Json::Obj(vec![
("ok".to_string(), Json::Bool(true)),
("value".to_string(), value),
]),
Err(err) => Json::Obj(vec![
("ok".to_string(), Json::Bool(false)),
("err".to_string(), Json::Str(err)),
]),
};
let out = pyjson::dumps(&body);
CString::new(out)
.map(|c| c.into_raw())
.unwrap_or(std::ptr::null_mut())
}
fn arg_json(text: &str) -> Result<Json, String> {
pyjson::parse(text).map_err(|e| format!("argument JSON parse failed: {}", e))
}
/// cpb_registry_revision({}) -> number
#[no_mangle]
pub extern "C" fn cpb_registry_revision(arg: *const c_char) -> *mut c_char {
let result = read_arg(arg)
.and_then(|text| arg_json(&text))
.map(|_| Json::Num(registry::registry_revision() as f64));
envelope(result)
}
/// cpb_patterns({}) -> [pattern doc, ...] in registry order
#[no_mangle]
pub extern "C" fn cpb_patterns(arg: *const c_char) -> *mut c_char {
let result = read_arg(arg)
.and_then(|text| arg_json(&text))
.map(|_| Json::Arr(registry::patterns()));
envelope(result)
}
/// cpb_get_pattern({"pattern_id": "...", "revision": n|null}) -> doc | null
#[no_mangle]
pub extern "C" fn cpb_get_pattern(arg: *const c_char) -> *mut c_char {
let result = read_arg(arg)
.and_then(|text| arg_json(&text))
.and_then(|a| {
let pattern_id = match a.get("pattern_id") {
Some(Json::Str(s)) => s.clone(),
_ => return Err("arg.pattern_id required".to_string()),
};
let revision = match a.get("revision") {
Some(Json::Num(n)) => Some(*n as i64),
_ => None,
};
registry::get_pattern(&pattern_id, revision)
});
envelope(result)
}
@@ -0,0 +1,99 @@
//! registry — the built-in construction pattern registry. The pattern docs
//! are FROZEN from the live Python oracle (frozen_cpb_patterns.json,
//! generated by scripts/gen_construction_patterns_builtin_truth.py with
//! RUNE_CPB_CORE=python pinned — never hand-transcribed): each doc is the
//! oracle's ConstructionPattern.to_dict(), including its __init__-sorted
//! provenance/exclusions order.
//!
//! Phase B: the frozen docs parse once into typed [`BuiltinPattern`]
//! values; the FFI re-emits the oracle-shaped doc from the typed value.
//! Miss-before-revision-check oracle ordering is explicit in the typed
//! lookup.
use std::sync::OnceLock;
use capability_scoring::pyjson::{self, Json};
const PATTERNS_SRC: &str = include_str!("../frozen_cpb_patterns.json");
/// One builtin pattern, typed from the oracle's to_dict() doc. Free-form
/// sub-structures (signals, obligations) stay `Json`: the schema is the
/// oracle's, open-world by design.
#[derive(Clone, Debug)]
struct BuiltinPattern {
pattern_id: String,
revision: i64,
doc: Json,
}
impl BuiltinPattern {
fn from_doc(doc: Json) -> Option<Self> {
let pattern_id = match doc.get("pattern_id") {
Some(Json::Str(s)) => s.clone(),
_ => return None,
};
let revision = match doc.get("revision") {
Some(Json::Num(n)) => *n as i64,
_ => return None,
};
Some(Self { pattern_id, revision, doc })
}
}
fn registry() -> &'static Vec<BuiltinPattern> {
static REGISTRY: OnceLock<Vec<BuiltinPattern>> = OnceLock::new();
REGISTRY.get_or_init(|| {
pyjson::parse(PATTERNS_SRC)
.ok()
.and_then(|root| match root.get("patterns") {
Some(Json::Arr(items)) => Some(
items
.iter()
.filter_map(|d| BuiltinPattern::from_doc(d.clone()))
.collect(),
),
_ => None,
})
.unwrap_or_default()
})
}
/// PATTERN_REGISTRY_REVISION from the oracle.
pub fn registry_revision() -> i64 {
static REVISION: OnceLock<i64> = OnceLock::new();
*REVISION.get_or_init(|| {
pyjson::parse(PATTERNS_SRC)
.ok()
.and_then(|root| match root.get("revision") {
Some(Json::Num(n)) => Some(*n as i64),
_ => None,
})
.unwrap_or(0)
})
}
/// Every builtin pattern doc, in registry order (BUILTIN_PATTERNS order).
pub fn patterns() -> Vec<Json> {
registry().iter().map(|p| p.doc.clone()).collect()
}
/// Oracle get_pattern semantics: unknown/empty id -> Null BEFORE any
/// revision check; a revision that no longer matches raises (err carries
/// the oracle's exact ValueError message).
pub fn get_pattern(pattern_id: &str, revision: Option<i64>) -> Result<Json, String> {
let pattern = match registry().iter().find(|p| p.pattern_id == pattern_id) {
Some(p) => p,
None => return Ok(Json::Null),
};
if let Some(rev) = revision {
if pattern.revision != rev {
return Err(format!(
"pattern {pattern_id} revision {rev} not in registry \
(current: {}) \u{2014} the consuming contract records which \
revision it used",
pattern.revision
));
}
}
Ok(pattern.doc.clone())
}
+23
View File
@@ -54,6 +54,12 @@ dependencies = [
"sha2",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "generic-array"
version = "0.14.7"
@@ -64,6 +70,22 @@ dependencies = [
"version_check",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "indexmap"
version = "2.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.18"
@@ -135,6 +157,7 @@ version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
"indexmap",
"itoa",
"memchr",
"serde",
+1 -1
View File
@@ -8,4 +8,4 @@ crate-type = ["rlib", "cdylib", "staticlib"]
[dependencies]
sha2 = "0.10"
serde_json = "1"
serde_json = { version = "1", features = ["preserve_order", "float_roundtrip"] }
File diff suppressed because it is too large. Load diff
+252 -22
View File
@@ -14,7 +14,49 @@ use std::os::raw::c_char;
pub const DRIFT_LIMIT: f64 = 0.30;
pub const CONSTITUTION_LIMIT: f64 = 0.05;
pub const BLOCKS: &[&str] = &["constitution", "persona", "human", "operating", "project"];
/// The five guarded blocks — a closed lattice, not stringly-typed routing.
/// The constitution's limit is exhaustive-match derived; every other block
/// falls to the plain drift limit (the oracle's ternary).
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum BlockLabel {
Constitution,
Persona,
Human,
Operating,
Project,
}
impl BlockLabel {
pub const ALL: [BlockLabel; 5] = [
Self::Constitution,
Self::Persona,
Self::Human,
Self::Operating,
Self::Project,
];
pub fn as_str(self) -> &'static str {
match self {
Self::Constitution => "constitution",
Self::Persona => "persona",
Self::Human => "human",
Self::Operating => "operating",
Self::Project => "project",
}
}
pub fn of_name(name: &str) -> Option<Self> {
Self::ALL.iter().copied().find(|b| b.as_str() == name)
}
pub fn limit(self) -> f64 {
match self {
Self::Constitution => CONSTITUTION_LIMIT,
_ => DRIFT_LIMIT,
}
}
}
/// _sha port: hex sha256 of UTF-8 text.
pub fn sha(text: &str) -> String {
@@ -28,28 +70,28 @@ pub fn diff_blocks(reference: &str, current: &str) -> String {
if reference.is_empty() {
return "no prior content (first drift from empty baseline)".to_string();
}
fn sig(l: &str) -> Option<&str> {
let s = l.trim();
(!s.is_empty()).then_some(s)
}
let ref_lines: Vec<&str> = reference.lines().collect();
let cur_lines: Vec<&str> = current.lines().collect();
let ref_set: std::collections::HashSet<&str> =
ref_lines.iter().filter_map(|l| { let s = l.trim(); if s.is_empty() { None } else { Some(s) } }).collect();
ref_lines.iter().filter_map(|l| sig(l)).collect();
let cur_set: std::collections::HashSet<&str> =
cur_lines.iter().filter_map(|l| { let s = l.trim(); if s.is_empty() { None } else { Some(s) } }).collect();
let mut added: Vec<&str> = vec![];
for l in &cur_lines {
let s = l.trim();
if !s.is_empty() && !ref_set.contains(s) {
added.push(s);
if added.len() >= 6 { break; }
}
}
let mut removed: Vec<&str> = vec![];
for l in &ref_lines {
let s = l.trim();
if !s.is_empty() && !cur_set.contains(s) {
removed.push(s);
if removed.len() >= 3 { break; }
}
}
cur_lines.iter().filter_map(|l| sig(l)).collect();
let added: Vec<&str> = cur_lines
.iter()
.filter_map(|l| sig(l))
.filter(|s| !ref_set.contains(*s))
.take(6)
.collect();
let removed: Vec<&str> = ref_lines
.iter()
.filter_map(|l| sig(l))
.filter(|s| !cur_set.contains(*s))
.take(3)
.collect();
let mut parts: Vec<String> = vec![];
if !added.is_empty() {
parts.push(format!(
@@ -85,8 +127,9 @@ pub fn check_block(
None => (prev_size.max(1), None, cur_size - prev_size),
};
let pct = (delta.abs() as f64) / (base.max(1) as f64);
let limit = if label == "constitution" { CONSTITUTION_LIMIT } else { DRIFT_LIMIT };
let content_changed = label == "constitution"
let is_constitution = matches!(BlockLabel::of_name(label), Some(BlockLabel::Constitution));
let limit = if is_constitution { CONSTITUTION_LIMIT } else { DRIFT_LIMIT };
let content_changed = is_constitution
&& anchor_size.is_some()
&& base_sha.is_some()
&& cur_sha.is_some()
@@ -100,7 +143,8 @@ pub fn check_block(
/// auto_fix routing port: (label, anchored, has_last_good) -> {action, reason}.
pub fn auto_fix_decision(label: &str, anchored: bool, has_last_good: bool) -> Value {
if label == "constitution" {
let is_constitution = matches!(BlockLabel::of_name(label), Some(BlockLabel::Constitution));
if is_constitution {
json!({"action": "alert-only", "reason": "constitution changes only by explicit directive; needs human review"})
} else if anchored {
json!({"action": "re-anchored", "reason": "anchored block grew (authorised) — re-baselined"})
@@ -111,6 +155,143 @@ pub fn auto_fix_decision(label: &str, anchored: bool, has_last_good: bool) -> Va
}
}
/// Python round(x, 3): correct rounding of the binary value with ties-to-even
/// (the same contract Rust's {:.3} formatting implements).
fn py_round3(x: f64) -> f64 {
format!("{:.3}", x).parse().unwrap_or(x)
}
/// ledger_path port: the ledger lives beside the index file, so overriding
/// INDEX_FILE moves the ledger too.
pub fn ledger_path_for(index_file: &str) -> String {
match index_file.rfind('/') {
Some(i) => format!("{}drift_ledger.json", &index_file[..=i]),
None => "drift_ledger.json".to_string(),
}
}
/// snapshot() entry-assembly port: {"when", "blocks": {label: {sha, size,
/// content}}}. "size" is the oracle's len(raw) — a CHARACTER count, not bytes.
/// Unknown labels in the payload are ignored (the oracle iterates BLOCKS).
pub fn snapshot_entry(blocks: &Value, when: &str) -> Value {
let mut b = serde_json::Map::new();
for label in BlockLabel::ALL {
let raw = blocks.get(label.as_str()).and_then(|v| v.as_str()).unwrap_or("");
b.insert(
label.as_str().to_string(),
json!({
"sha": sha(raw),
"size": raw.chars().count(),
"content": raw,
}),
);
}
json!({"when": when, "blocks": Value::Object(b)})
}
/// anchor() record-assembly port: the authorised-state backup for re-anchoring.
pub fn anchor_record(content: &str, reason: &str, when: &str) -> Value {
json!({
"sha": sha(content),
"size": content.chars().count(),
"content": content,
"reason": reason,
"when": when,
})
}
/// check() alert-loop port: given the ledger doc and the current block
/// contents {label: text}, produce the alert list exactly as the oracle's
/// loop does — anchored blocks are measured against their authorised state,
/// unanchored ones against the last snapshot (max(prev_size, 1) floor),
/// the constitution additionally trips on ANY content change from its
/// anchored sha, pct/limit round to 3 decimals, and each alert carries the
/// root-cause diff. Side effects (prints, surface_alert, auto-fix, journal)
/// stay in the facade.
pub fn check_alerts(ledger: &Value, blocks: &Value) -> Value {
let prev = ledger
.get("last_snapshot")
.and_then(|s| s.get("blocks"))
.cloned()
.unwrap_or_else(|| json!({}));
let anchors = ledger.get("anchors").cloned().unwrap_or_else(|| json!({}));
let alerts: Vec<Value> = BlockLabel::ALL
.iter()
.filter_map(|label| {
let cur = blocks.get(label.as_str()).and_then(|v| v.as_str()).unwrap_or("");
let cur_size = cur.chars().count() as i64;
let anchor_meta = anchors.get(label.as_str());
let (base, base_sha, delta, ref_content) = match anchor_meta {
Some(a) => {
let b = a.get("size").and_then(|v| v.as_i64()).unwrap_or(cur_size);
let sh = a.get("sha").and_then(|v| v.as_str());
let rc = a.get("content").and_then(|v| v.as_str());
(b, sh, cur_size - b, rc)
}
None => {
let pm = prev.get(label.as_str());
let ps = pm
.and_then(|m| m.get("size"))
.and_then(|v| v.as_i64())
.unwrap_or(cur_size);
let rc = pm.and_then(|m| m.get("content")).and_then(|v| v.as_str());
(ps.max(1), None, cur_size - ps, rc)
}
};
let pct = (delta.abs() as f64) / (base.max(1) as f64);
let limit = label.limit();
let content_changed = matches!(label, BlockLabel::Constitution)
&& anchor_meta.is_some()
&& base_sha.is_some()
&& sha(cur) != base_sha.unwrap();
(content_changed || pct > limit).then(|| {
json!({
"label": label.as_str(),
"delta": delta,
"pct": py_round3(pct),
"limit": py_round3(limit),
"base": base,
"changed": diff_blocks(ref_content.unwrap_or(""), cur),
"content_changed": content_changed,
})
})
})
.collect();
Value::Array(alerts)
}
/// fix() decision port: the oracle's retroactive-fix gate minus the restore IO
/// (the facade performs restore_topic + journal when {fixed: true}).
/// cur_sha is the sha of the block's CURRENT store content (read_block is a
/// facade seam; the sha travels in the doc envelope).
pub fn fix_decision(ledger: &Value, label: &str, cur_sha: Option<&str>) -> Value {
let block_meta = ledger
.get("last_snapshot")
.and_then(|s| s.get("blocks"))
.and_then(|b| b.get(label));
let has_content = block_meta
.map(|m| m.get("content").is_some())
.unwrap_or(false);
if block_meta.is_none() || !has_content {
return json!({"fixed": false, "reason": format!("no last-good content for {}", label)});
}
if ledger
.get("anchors")
.map(|a| a.get(label).is_some())
.unwrap_or(false)
{
return json!({"fixed": false, "reason": format!("{} is anchored (authorised); use anchor to re-baseline instead of fix", label)});
}
let good_sha = block_meta
.and_then(|m| m.get("sha"))
.and_then(|v| v.as_str())
.unwrap_or("");
if cur_sha == Some(good_sha) {
return json!({"fixed": false, "reason": format!("{} already matches last-good", label)});
}
json!({"fixed": true, "reason": format!("{} restored to last-good state", label)})
}
fn read_arg(ptr: *const c_char) -> Result<Value, String> {
if ptr.is_null() {
return Err("null argument pointer".into());
@@ -181,5 +362,54 @@ pub extern "C" fn dl_auto_fix(arg: *const c_char) -> *mut c_char {
envelope(r)
}
/// dl_ledger_path({"index_file"}) -> path string
#[no_mangle]
pub extern "C" fn dl_ledger_path(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| Value::String(ledger_path_for(s(a.get("index_file")))));
envelope(r)
}
/// dl_snapshot_entry({"blocks": {label: content}, "when"}) -> snapshot entry
#[no_mangle]
pub extern "C" fn dl_snapshot_entry(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let blocks = a.get("blocks").cloned().unwrap_or(Value::Null);
snapshot_entry(&blocks, s(a.get("when")))
});
envelope(r)
}
/// dl_anchor_record({"content", "reason", "when"}) -> anchor record
#[no_mangle]
pub extern "C" fn dl_anchor_record(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
anchor_record(s(a.get("content")), s(a.get("reason")), s(a.get("when")))
});
envelope(r)
}
/// dl_check_alerts({"ledger", "blocks": {label: content}}) -> [alert, ...]
#[no_mangle]
pub extern "C" fn dl_check_alerts(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let ledger = a.get("ledger").cloned().unwrap_or(Value::Null);
let blocks = a.get("blocks").cloned().unwrap_or(Value::Null);
check_alerts(&ledger, &blocks)
});
envelope(r)
}
/// dl_fix_decision({"ledger", "label", "cur_sha"?}) -> {fixed, reason}
#[no_mangle]
pub extern "C" fn dl_fix_decision(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let ledger = a.get("ledger").cloned().unwrap_or(Value::Null);
let label = s(a.get("label")).to_string();
let cur_sha = a.get("cur_sha").and_then(|v| v.as_str());
fix_decision(&ledger, &label, cur_sha)
});
envelope(r)
}
// NOTE: no free-symbol export here (capability_scoring's cs_free_string
// serves the whole process — duplicate symbols break the cdylib link).
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,27 @@
# Contract BUILDER-2026-10-12T12:25:33Z-a87985-factory-wave
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
Port curator to FULL Go — dichotomy wave #2479 tranche.
## What it connects to
- `scripts/gen_curator_truth.py`
- `src/go/curator/`
- `src/rune/curator.py`
- `tests/`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T14:41:43Z", "contract": "BUILDER-2026-10-12T12:25:33Z-a87985-factory-wave", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["module:deploy_qualify"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["module:deploy_qualify"], "predicted_existing_affected": ["module:deploy_qualify"], "scope_check": {"in_scope": ["scripts/gen_curator_truth.py", "src/go/curator/", "src/rune/curator.py", "tests/"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- wave orchestrator pre-authorization: dichotomy tranche #2479, GO verdict for curator
- implementation: truth generator + src/go/curator port (commits 03ef8132/89b691b2)
- battery 162/162 + live parity 162/162 + Python tests green
- closure-record
@@ -0,0 +1,25 @@
# Contract BUILDER-2026-10-12T12:55:40Z-c88ae4-mimo
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
create a practice scheduler with create/list/complete
## What it connects to
- `practice-scheduler-js/scheduler.js`
- `practice-scheduler-js/test_scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [{"entity": "scheduler.js", "note": "genuinely unexpected new surface \u2014 evidence required before store update", "status": "CANDIDATE"}, {"entity": "test:scheduler", "note": "genuinely unexpected new surface \u2014 evidence required before store update", "status": "CANDIDATE"}], "captured_at": "2026-10-12T12:55:40Z", "contract": "BUILDER-2026-10-12T12:55:40Z-c88ae4-mimo", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": ["scheduler.js", "test:scheduler"], "missed": ["scheduler.js", "test:scheduler"], "needless": ["capability:csv_export", "contract:csv_export"], "observed": ["scheduler.js", "test:scheduler"], "observed_existing": [], "observed_new": ["scheduler.js", "test:scheduler"], "predicted_but_unaffected": ["capability:csv_export", "contract:csv_export"], "predicted_existing_affected": ["capability:csv_export", "contract:csv_export"], "scope_check": {"in_scope": ["/tmp/pytest-of-nick/pytest-494/test_builder_governed_lifecycl0/practice-scheduler/practice-scheduler-js/scheduler.js", "/tmp/pytest-of-nick/pytest-494/test_builder_governed_lifecycl0/practice-scheduler/practice-scheduler-js/test_scheduler.js"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- builder:mimo
- builder:mimo
- builder:mimo
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T12:56:01Z-606d4c-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
persistent project export
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T12:56:01Z", "contract": "BUILDER-2026-10-12T12:56:01Z-606d4c-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T12:56:01Z-9d9c7f-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
persistent project export
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T12:56:01Z", "contract": "BUILDER-2026-10-12T12:56:01Z-9d9c7f-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T12:56:01Z-b39de9-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
wave stage one
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T12:56:01Z", "contract": "BUILDER-2026-10-12T12:56:01Z-b39de9-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T12:56:03Z-654c5a-minidoc-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
minidoc fixture sections: the mini-doc emission target
## What it connects to
- `tests/test_contract_minidoc.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- t
- t
- t
- final evidence
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T12:57:27Z-181851-minidoc-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
minidoc fixture outdir: the mini-doc emission target
## What it connects to
- `tests/test_contract_minidoc.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- t
- t
- t
- final evidence
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-1622c7-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `src/rune/bounded_change.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-1622c7-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:rune-planned", "contract:rune-spec"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:rune-planned", "contract:rune-spec"], "predicted_existing_affected": ["capability:rune-planned", "contract:rune-spec"], "scope_check": {"in_scope": [], "out_of_scope": ["x"], "verdict": "red"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-7bc14b-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
bounded change touching closure_target
## What it connects to
- `scripts/rollback_generation.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-7bc14b-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["scripts/rollback_generation.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-a0b7ea-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-a0b7ea-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:planned", "contract:spec-1"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:planned", "contract:spec-1"], "predicted_existing_affected": ["capability:planned", "contract:spec-1"], "scope_check": {"in_scope": [], "out_of_scope": ["x"], "verdict": "red"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-a5103b-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
bounded change touching closure_target
## What it connects to
- `scripts/rollback_generation.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-a5103b-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["scripts/rollback_generation.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t21.4 test approved
- t21.4 test building
- t21.4 test verifying
@@ -0,0 +1,25 @@
# Contract BUILDER-2026-10-12T13:03:59Z-bc1b3b-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
scope with an unmodeled file
## What it connects to
- `scripts/rollback_generation.py`
- `tests/test_t214_material_closure.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-bc1b3b-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": ["test:t214_material_closure"], "expected_new_missing": ["test:t214_material_closure"], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["tests/test_t214_material_closure.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-da016d-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-da016d-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:planned", "contract:spec-1"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:planned", "contract:spec-1"], "predicted_existing_affected": ["capability:planned", "contract:spec-1"], "scope_check": {"in_scope": ["scheduler.js"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:03:59Z-e257bf-t21.5-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
add the widget import capability to widget-forge (bounded change; import widgets from external bundles)
## What it connects to
- `src/widget_import.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:03:59Z", "contract": "BUILDER-2026-10-12T13:03:59Z-e257bf-t21.5-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:widget-export", "contract:widget-import"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:widget-export", "contract:widget-import"], "predicted_existing_affected": ["component:widget-export", "contract:widget-import"], "scope_check": {"in_scope": ["src/widget_import.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,25 @@
# Contract BUILDER-2026-10-12T13:04:53Z-d265b9-mimo
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
create a practice scheduler with create/list/complete
## What it connects to
- `practice-scheduler-js/scheduler.js`
- `practice-scheduler-js/test_scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [{"entity": "scheduler.js", "note": "genuinely unexpected new surface \u2014 evidence required before store update", "status": "CANDIDATE"}, {"entity": "test:scheduler", "note": "genuinely unexpected new surface \u2014 evidence required before store update", "status": "CANDIDATE"}], "captured_at": "2026-10-12T13:04:53Z", "contract": "BUILDER-2026-10-12T13:04:53Z-d265b9-mimo", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": ["scheduler.js", "test:scheduler"], "missed": ["scheduler.js", "test:scheduler"], "needless": ["capability:csv_export", "contract:csv_export"], "observed": ["scheduler.js", "test:scheduler"], "observed_existing": [], "observed_new": ["scheduler.js", "test:scheduler"], "predicted_but_unaffected": ["capability:csv_export", "contract:csv_export"], "predicted_existing_affected": ["capability:csv_export", "contract:csv_export"], "scope_check": {"in_scope": ["/tmp/pytest-of-nick/pytest-503/test_builder_governed_lifecycl0/practice-scheduler/practice-scheduler-js/scheduler.js", "/tmp/pytest-of-nick/pytest-503/test_builder_governed_lifecycl0/practice-scheduler/practice-scheduler-js/test_scheduler.js"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- builder:mimo
- builder:mimo
- builder:mimo
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:05:15Z-a5ff07-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
wave stage one
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:05:15Z", "contract": "BUILDER-2026-10-12T13:05:15Z-a5ff07-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:05:15Z-b41aa9-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
persistent project export
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:05:15Z", "contract": "BUILDER-2026-10-12T13:05:15Z-b41aa9-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:05:15Z-d4789f-test-builder
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
persistent project export
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:05:15Z", "contract": "BUILDER-2026-10-12T13:05:15Z-d4789f-test-builder", "correctly_predicted": ["capability:exporter"], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["contract:csv_export"], "observed": ["capability:exporter"], "observed_existing": ["capability:exporter"], "observed_new": [], "predicted_but_unaffected": ["contract:csv_export"], "predicted_existing_affected": ["capability:exporter", "contract:csv_export"]}.
## Evidence
- builder:test-builder
- builder:test-builder
- builder:test-builder
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:05:16Z-d9a34c-minidoc-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
minidoc fixture sections: the mini-doc emission target
## What it connects to
- `tests/test_contract_minidoc.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- t
- t
- t
- final evidence
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:06:36Z-8b508c-minidoc-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
minidoc fixture outdir: the mini-doc emission target
## What it connects to
- `tests/test_contract_minidoc.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- t
- t
- t
- final evidence
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:55Z-12e59c-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `src/rune/bounded_change.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:55Z", "contract": "BUILDER-2026-10-12T13:11:55Z-12e59c-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:rune-planned", "contract:rune-spec"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:rune-planned", "contract:rune-spec"], "predicted_existing_affected": ["capability:rune-planned", "contract:rune-spec"], "scope_check": {"in_scope": [], "out_of_scope": ["x"], "verdict": "red"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:55Z-a800a0-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
bounded change touching closure_target
## What it connects to
- `scripts/rollback_generation.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:56Z", "contract": "BUILDER-2026-10-12T13:11:55Z-a800a0-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["scripts/rollback_generation.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- t21.4 test approved
- t21.4 test building
- closure-record
- t21.4 test verifying
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:55Z-db60e6-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:55Z", "contract": "BUILDER-2026-10-12T13:11:55Z-db60e6-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:planned", "contract:spec-1"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:planned", "contract:spec-1"], "predicted_existing_affected": ["capability:planned", "contract:spec-1"], "scope_check": {"in_scope": [], "out_of_scope": ["x"], "verdict": "red"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:55Z-e8cedb-adversarial-probe
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
build the hostile spec module
## What it connects to
- `scheduler.js`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:55Z", "contract": "BUILDER-2026-10-12T13:11:55Z-e8cedb-adversarial-probe", "correctly_predicted": [], "evidence_sources": ["driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["capability:planned", "contract:spec-1"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["capability:planned", "contract:spec-1"], "predicted_existing_affected": ["capability:planned", "contract:spec-1"], "scope_check": {"in_scope": ["scheduler.js"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- builder:adversarial-probe
- builder:adversarial-probe
- closure-record
- e
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:56Z-749790-t21.5-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
add the widget import capability to widget-forge (bounded change; import widgets from external bundles)
## What it connects to
- `src/widget_import.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:56Z", "contract": "BUILDER-2026-10-12T13:11:56Z-749790-t21.5-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:widget-export", "contract:widget-import"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:widget-export", "contract:widget-import"], "predicted_existing_affected": ["component:widget-export", "contract:widget-import"], "scope_check": {"in_scope": ["src/widget_import.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:11:56Z-a20b0c-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
bounded change touching closure_target
## What it connects to
- `scripts/rollback_generation.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:56Z", "contract": "BUILDER-2026-10-12T13:11:56Z-a20b0c-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["scripts/rollback_generation.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,25 @@
# Contract BUILDER-2026-10-12T13:11:56Z-c85a39-t21.4-test
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
scope with an unmodeled file
## What it connects to
- `scripts/rollback_generation.py`
- `tests/test_t214_material_closure.py`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:11:56Z", "contract": "BUILDER-2026-10-12T13:11:56Z-c85a39-t21.4-test", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": ["test:t214_material_closure"], "expected_new_missing": ["test:t214_material_closure"], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["component:closure-target", "contract:closure-target"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["component:closure-target", "contract:closure-target"], "predicted_existing_affected": ["component:closure-target", "contract:closure-target"], "scope_check": {"in_scope": ["tests/test_t214_material_closure.py"], "out_of_scope": [], "verdict": "green"}}.
## Evidence
- closure-record
- t
- t
- t
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:29:58Z-e5c619-factory-wave
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
Port src/rune/construction_patterns_builtin.py to FULL Rust (dichotomy factory, issue #2479 tranche): frozen-oracle registry data, doc-envelope FFI, ctypes loader (free via capability_scoring cs_free_string), facade delegation with RUNE_CPB_CORE=python pin, frozen-truth branch battery, live parity 100%, Phase B typed-registry pass. Plus audit fix: curator -> curator-core alias (curator was FULL-Go since a95c6ce1 but the audit miscounted it NOT TOUCHED).
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:30:59Z", "contract": "BUILDER-2026-10-12T13:29:58Z-e5c619-factory-wave", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["module:deploy_qualify"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["module:deploy_qualify"], "predicted_existing_affected": ["module:deploy_qualify"], "scope_check": {"in_scope": [], "out_of_scope": ["scripts/check_cpb_parity.py", "scripts/gen_construction_patterns_builtin_truth.py", "src/rune/construction_patterns_builtin.py", "src/rune/cpb_loader.py", "src/rust/construction_patterns_builtin/frozen_cpb_patterns.json", "src/rust/construction_patterns_builtin/frozen_cpb_truth.json", "src/rust/construction_patterns_builtin/src/branch_battery.rs", "src/rust/construction_patterns_builtin/src/lib.rs", "src/rust/construction_patterns_builtin/src/registry.rs"], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
- builder:factory-wave
- builder:factory-wave
- builder:factory-wave
- closure-record
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-12T13:54:01Z-950331-factory-wave
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
Complete the drift_ledger dichotomy port to FULL Rust (#2479 tranche): check/alert-loop, snapshot/anchor assembly, auto-fix routing and fix gate as doc-envelope FFI; dl_loader ctypes loader mirroring broker_loader.py (free via capability_scoring cs_free_string); facade delegation with RUNE_DL_CORE=python pin; frozen-oracle battery (87 cases, every public function/branch); live parity 100%; Phase B language-advantage pass; dichotomy-audit instrument fixes (curator alias + hyphen-twin mapping).
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:55:03Z", "contract": "BUILDER-2026-10-12T13:54:01Z-950331-factory-wave", "correctly_predicted": [], "evidence_sources": ["unattributed"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": ["module:deploy_qualify"], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": ["module:deploy_qualify"], "predicted_existing_affected": ["module:deploy_qualify"], "scope_check": {"in_scope": [], "out_of_scope": ["docs/dichotomy-rebase-honest-audit.md", "scripts/dichotomy_audit.py", "scripts/gen_drift_ledger_truth.py", "src/rune/dl_loader.py", "src/rune/drift_ledger.py", "src/rust/drift_ledger/src/branch_battery.rs", "src/rust/drift_ledger/src/lib.rs"], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
- builder:factory-wave
- builder:factory-wave
- builder:factory-wave
- closure-record
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 5 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "d-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "d-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 5 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "f-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "f-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "r-1", "correctly_predicted": [], "evidence_sources": ["pre"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "r-1", "correctly_predicted": [], "evidence_sources": ["pre"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "r-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "r-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "s-1", "correctly_predicted": [], "evidence_sources": ["pre"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "s-1", "correctly_predicted": [], "evidence_sources": ["pre"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "st-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "st-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 5 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "st-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "st-2", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 5 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "st-3", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "st-3", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence
+1 -1
View File
@@ -14,7 +14,7 @@ stage need
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 5 checkpoint(s) recorded on the contract entity.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-11T17:48:55Z", "contract": "w-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
- Quality at close: {"candidate_corrections": [], "captured_at": "2026-10-12T13:10:01Z", "contract": "w-1", "correctly_predicted": [], "evidence_sources": ["programme-driver"], "expected_new_entities": [], "expected_new_missing": [], "expected_new_observed": [], "expected_runtime_effects": [], "expected_runtime_missing": [], "expected_runtime_observed": [], "genuinely_unexpected_new": [], "missed": [], "needless": [], "observed": [], "observed_existing": [], "observed_new": [], "predicted_but_unaffected": [], "predicted_existing_affected": [], "scope_check": {"in_scope": [], "out_of_scope": [], "reason": "contract has no approved scope", "verdict": "unknown"}}.
## Evidence