Compare commits

...
63 Commits
Author SHA1 Message Date
conductor ab79390a09 chore(release): auto-bump version to 0.248.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 9s
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 / gitea-offline (push) Successful in 16s
Auto-version and Release / release (push) Successful in 36s
CI Pipeline / type-check (push) Failing after 42s
CI Pipeline / lint (push) Failing after 1m7s
CI Pipeline / canary (push) Failing after 2m14s
CI Pipeline / unit-tests (push) Failing after 17m7s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 4s
Promotion record: (unknown)
2026-10-13 01:40:57 +01:00
Nick 379409b5b6 feat(factory): shared freeze_truth.py harness — one law for oracle truth freezing
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 18s
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 / lint (push) Canceled after 36s
CI Pipeline / unit-tests (push) Canceled after 36s
CI Pipeline / canary (push) Canceled after 36s
Auto-version and Release / release (push) Canceled after 37s
CI Pipeline / type-check (push) Canceled after 29s
deploy / deploy (push) Canceled after 25s
Pinned-core, no-clock, deep-copy, verbatim-embedding conventions in ONE
place. Includes --verify mode: re-freeze from live oracle and byte-compare
against the frozen file (catches self-consistent misreads at tick time).
Smoke-tested against rune.work_manager.
2026-10-13 01:40:18 +01:00
conductor 5727a3783f chore(release): auto-bump version to 0.247.1 — earned by # (patch: converged release (push-to-master bump))
CI Pipeline / rust-surface (push) Failing after 35s
Auto-version and Release / release (push) Successful in 51s
CI Pipeline / go-surface (push) Failing after 39s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / gitea-offline (push) Successful in 29s
CI Pipeline / type-check (push) Failing after 1m2s
CI Pipeline / lint (push) Failing after 1m50s
CI Pipeline / canary (push) Failing after 3m20s
deploy / deploy (push) Failing after 16m34s
CI Pipeline / unit-tests (push) Failing after 24m22s
CI Pipeline / required-checks (push) Failing after 5s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 8s
Promotion record: (unknown)
2026-10-13 00:09:13 +01:00
Nick 2c2b2b5a16 fix(audit): concatenate Go+Rust corpus per module (no side shadowing) + classify *_loader family and ffi smoke harness as FFI machinery
CI Pipeline / type-check (push) Canceled after 0s
CI Pipeline / gitea-offline (push) Canceled after 0s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
deploy / deploy (push) Canceled after 0s
Auto-version and Release / release (push) Canceled after 39s
CI Pipeline / canary (push) Canceled after 43s
CI Pipeline / go-surface (push) Canceled after 43s
CI Pipeline / best-practices (push) Canceled after 43s
CI Pipeline / lint (push) Canceled after 43s
CI Pipeline / rust-surface (push) Canceled after 52s
CI Pipeline / unit-tests (push) Canceled after 52s
CI Pipeline / documentation (push) Canceled after 52s
- verification_layer was miscounted NOT TOUCHED: the Rust stub crate
  shadowed the full Go port in the corpus. Concatenate both sides.
- The *_loader family is the programme's own ctypes delegation glue
  (strangler-fig stage-3 burn, same category as dunders) — machinery,
  not port surface. ffi_query_memory_smoke is a smoke harness (TEST).
- Honest counts: 46% (1083/2366) | 40 FULL | 98 PARTIAL | 54 NOT TOUCHED.
2026-10-13 00:08:35 +01:00
Nick 528602fb89 chore(store): merge concurrent batch state — batch-a final checkpoint
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 18s
CI Pipeline / gitea-offline (push) Successful in 18s
Auto-version and Release / release (push) Successful in 36s
CI Pipeline / type-check (push) Failing after 47s
CI Pipeline / lint (push) Failing after 1m11s
CI Pipeline / canary (push) Failing after 2m16s
deploy / deploy (push) Failing after 15m52s
CI Pipeline / unit-tests (push) Failing after 16m58s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 4s
2026-10-12 19:46:23 +01:00
Nick 040397d657 chore(store): close subsystem_health dichotomy contract BUILDER-2026-10-12T18:33:28Z-bbd40c-factory-batch-a (parity dc14cec5, phase B 03cd5d20)
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 16s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 20s
CI Pipeline / type-check (push) Canceled after 11s
deploy / deploy (push) Canceled after 26s
CI Pipeline / gitea-offline (push) Canceled after 10s
CI Pipeline / lint (push) Canceled after 26s
CI Pipeline / unit-tests (push) Canceled after 25s
Auto-version and Release / release (push) Canceled after 34s
2026-10-12 19:45:54 +01:00
conductor 8b8ef5bac5 chore(release): auto-bump version to 0.247.0 — earned by # (minor: converged release (push-to-master bump))
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 17s
Auto-version and Release / release (push) Successful in 36s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Failing after 45s
CI Pipeline / lint (push) Failing after 1m4s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 1m11s
deploy / deploy (push) Canceled after 1m16s
CI Pipeline / unit-tests (push) Canceled after 1m16s
Promotion record: (unknown)
2026-10-12 19:44:36 +01:00
Nick 2f8f74f2cd refactor(subsystem_health): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 17s
CI Pipeline / gitea-offline (push) Successful in 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 43s
CI Pipeline / lint (push) Canceled after 40s
CI Pipeline / canary (push) Canceled after 41s
CI Pipeline / unit-tests (push) Canceled after 42s
deploy / deploy (push) Canceled after 46s
CI Pipeline / type-check (push) Canceled after 30s
2026-10-12 19:43:53 +01:00
Nick 14325d34c6 feat(subsystem_health): port to FULL Rust — dichotomy wave 2026-10-12 19:43:53 +01:00
Nick 78cfdc1be8 chore(store): close intent_continuity dichotomy contract BUILDER-2026-10-12T18:32:30Z-386148-factory-batch-b (parity 5893a37c, phase B 6f9e0cfa)
CI Pipeline / best-practices (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 18s
CI Pipeline / documentation (push) Successful in 7s
Auto-version and Release / release (push) Successful in 38s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Failing after 44s
CI Pipeline / lint (push) Failing after 1m3s
CI Pipeline / canary (push) Failing after 2m11s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
deploy / deploy (push) Canceled after 6m41s
CI Pipeline / unit-tests (push) Canceled after 6m31s
2026-10-12 19:36:58 +01:00
Nick d15a9f26c4 chore(store): register intent_continuity dichotomy contract BUILDER-2026-10-12T18:32:30Z-386148-factory-batch-b (verifying) 2026-10-12 19:36:58 +01:00
conductor 79695ab92c chore(release): auto-bump version to 0.246.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 17s
Auto-version and Release / release (push) Successful in 37s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Failing after 46s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / lint (push) Canceled after 1m7s
CI Pipeline / canary (push) Canceled after 1m11s
CI Pipeline / unit-tests (push) Canceled after 1m16s
Promotion record: (unknown)
2026-10-12 19:35:57 +01:00
Nick 29a8e9323d refactor(intent_continuity): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 19s
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 11s
Auto-version and Release / release (push) Canceled after 35s
CI Pipeline / unit-tests (push) Canceled after 25s
CI Pipeline / lint (push) Canceled after 27s
CI Pipeline / canary (push) Canceled after 26s
CI Pipeline / gitea-offline (push) Canceled after 11s
deploy / deploy (push) Canceled after 35s
2026-10-12 19:35:22 +01:00
Nick 008f02984d feat(intent_continuity): port to FULL Rust — dichotomy wave 2026-10-12 19:35:22 +01:00
Nick 0ce97f622a chore(store): close rune_profiler dichotomy contract BUILDER-2026-10-12T18:15:18Z-5023c2-factory-batch-a (parity 08187fd2, phase B d87cbc0a)
CI Pipeline / best-practices (push) Successful in 12s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 21s
CI Pipeline / go-surface (push) Failing after 24s
CI Pipeline / gitea-offline (push) Successful in 25s
Auto-version and Release / release (push) Successful in 55s
CI Pipeline / type-check (push) Failing after 1m10s
CI Pipeline / lint (push) Failing after 1m35s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 2m47s
deploy / deploy (push) Canceled after 2m56s
CI Pipeline / unit-tests (push) Canceled after 2m57s
2026-10-12 19:32:25 +01:00
conductor 447fdd14a4 chore(release): auto-bump version to 0.245.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / rust-surface (push) Failing after 21s
CI Pipeline / go-surface (push) Failing after 25s
CI Pipeline / gitea-offline (push) Successful in 23s
Auto-version and Release / release (push) Successful in 50s
CI Pipeline / type-check (push) Failing after 1m5s
CI Pipeline / lint (push) Failing after 1m31s
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 2m42s
CI Pipeline / canary (push) Canceled after 2m41s
Promotion record: (unknown)
2026-10-12 19:29:47 +01:00
Nick d87cbc0a7f refactor(rune_profiler): 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 19s
CI Pipeline / go-surface (push) Failing after 22s
CI Pipeline / gitea-offline (push) Successful in 26s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 49s
CI Pipeline / lint (push) Canceled after 51s
Auto-version and Release / release (push) Canceled after 57s
CI Pipeline / unit-tests (push) Canceled after 50s
CI Pipeline / type-check (push) Canceled after 36s
deploy / deploy (push) Canceled after 1m1s
2026-10-12 19:28:45 +01:00
Nick 08187fd2ea feat(rune_profiler): port to FULL Rust — dichotomy wave 2026-10-12 19:27:21 +01:00
Nick ccf6b959f2 chore(store): close subconscious_pass dichotomy contract BUILDER-2026-10-12T17:56:40Z-3cb9eb-factory-batch-a (parity 4369c1a5, phase B 69c31bfd)
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 11s
CI Pipeline / rust-surface (push) Failing after 20s
CI Pipeline / go-surface (push) Failing after 24s
CI Pipeline / gitea-offline (push) Successful in 25s
Auto-version and Release / release (push) Successful in 51s
CI Pipeline / type-check (push) Failing after 1m9s
CI Pipeline / lint (push) Failing after 1m29s
CI Pipeline / canary (push) Failing after 2m52s
deploy / deploy (push) Failing after 15m56s
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 16m36s
2026-10-12 19:12:14 +01:00
Nick 74d94d3a0c chore(store): merge concurrent scaffold store — batch-a checkpoint 2026-10-12 19:12:13 +01:00
Nick 2cec4253ec chore(store): close recall_uplift dichotomy contract BUILDER-2026-10-12T18:04:15Z-710b89-factory-batch-b (parity de8c93c9, phase B b0aaf4b5)
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 20s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / go-surface (push) Failing after 25s
Auto-version and Release / release (push) Successful in 53s
CI Pipeline / gitea-offline (push) Successful in 27s
CI Pipeline / type-check (push) Failing after 1m10s
CI Pipeline / lint (push) Failing after 1m36s
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 3m6s
CI Pipeline / canary (push) Canceled after 3m7s
deploy / deploy (push) Canceled after 3m16s
2026-10-12 19:09:00 +01:00
Nick 2d7df37a4f chore(store): register recall_uplift dichotomy contract BUILDER-2026-10-12T18:04:15Z-710b89-factory-batch-b (verifying) 2026-10-12 19:09:00 +01:00
conductor 4fd94c988d chore(release): auto-bump version to 0.244.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 19s
CI Pipeline / go-surface (push) Failing after 23s
CI Pipeline / gitea-offline (push) Successful in 22s
Auto-version and Release / release (push) Successful in 46s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / lint (push) Canceled after 56s
CI Pipeline / canary (push) Canceled after 56s
CI Pipeline / type-check (push) Canceled after 41s
CI Pipeline / unit-tests (push) Canceled after 1m2s
Promotion record: (unknown)
2026-10-12 19:08:04 +01:00
Nick 9d9beacaaf refactor(subconscious_pass): Phase B language-advantage pass — dichotomy wave
CI Pipeline / rust-surface (push) Failing after 23s
CI Pipeline / go-surface (push) Failing after 26s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / lint (push) Canceled after 51s
CI Pipeline / unit-tests (push) Canceled after 51s
CI Pipeline / type-check (push) Canceled after 26s
CI Pipeline / canary (push) Canceled after 51s
CI Pipeline / gitea-offline (push) Canceled after 20s
Auto-version and Release / release (push) Canceled after 54s
deploy / deploy (push) Canceled after 55s
2026-10-12 19:07:02 +01:00
Nick 4369c1a54e feat(subconscious_pass): port to FULL Rust — dichotomy wave 2026-10-12 19:07:02 +01:00
Nick 62c05b695c refactor(recall_uplift): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 13s
CI Pipeline / documentation (push) Canceled after 0s
CI Pipeline / type-check (push) Canceled after 0s
CI Pipeline / gitea-offline (push) Canceled after 0s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / go-surface (push) Canceled after 16s
CI Pipeline / canary (push) Canceled after 16s
CI Pipeline / rust-surface (push) Canceled after 16s
Auto-version and Release / release (push) Canceled after 26s
deploy / deploy (push) Canceled after 26s
CI Pipeline / lint (push) Canceled after 20s
CI Pipeline / unit-tests (push) Canceled after 21s
2026-10-12 19:06:44 +01:00
Nick 85a965e993 feat(recall_uplift): port to FULL Rust — dichotomy wave 2026-10-12 19:06:44 +01:00
conductor 8dd42655a2 chore(release): auto-bump version to 0.243.1 — earned by # (patch: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 19s
CI Pipeline / go-surface (push) Failing after 24s
Auto-version and Release / release (push) Successful in 43s
CI Pipeline / gitea-offline (push) Successful in 24s
CI Pipeline / type-check (push) Failing after 58s
CI Pipeline / lint (push) Failing after 1m19s
CI Pipeline / canary (push) Failing after 3m2s
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 4m6s
Promotion record: (unknown)
2026-10-12 19:02:34 +01:00
Nick 5dbb5ddc34 fix(forge): battery pins fixture token modes (git stores only the exec bit)
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / rust-surface (push) Failing after 18s
CI Pipeline / go-surface (push) Failing after 22s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / gitea-offline (push) Canceled after 25s
CI Pipeline / canary (push) Canceled after 36s
CI Pipeline / type-check (push) Canceled after 25s
Auto-version and Release / release (push) Canceled after 49s
CI Pipeline / lint (push) Canceled after 41s
CI Pipeline / unit-tests (push) Canceled after 40s
deploy / deploy (push) Canceled after 25s
2026-10-12 19:01:50 +01:00
Nick a1494f2e94 chore(store): close forge + verification_layer contracts (factory-batch-c)
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / rust-surface (push) Failing after 20s
CI Pipeline / go-surface (push) Failing after 23s
CI Pipeline / gitea-offline (push) Successful in 22s
Auto-version and Release / release (push) Successful in 46s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / lint (push) Canceled after 1m15s
CI Pipeline / unit-tests (push) Canceled after 1m16s
CI Pipeline / type-check (push) Canceled after 1m1s
CI Pipeline / canary (push) Canceled after 1m21s
deploy / deploy (push) Canceled after 1m0s
2026-10-12 19:00:29 +01:00
Nick 3a2e61cc0c chore(store): merge concurrent scaffold store — iteration contract b49130 evidence
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 19s
CI Pipeline / go-surface (push) Failing after 23s
CI Pipeline / gitea-offline (push) Successful in 25s
Auto-version and Release / release (push) Successful in 52s
CI Pipeline / type-check (push) Failing after 1m5s
CI Pipeline / lint (push) Failing after 1m25s
CI Pipeline / canary (push) Failing after 3m11s
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 5m6s
deploy / deploy (push) Canceled after 5m15s
2026-10-12 18:55:19 +01:00
Nick 4684edac4e chore(store): close iteration dichotomy contract BUILDER-2026-10-12T16:46:40Z-b49130-factory-batch-a (parity 8baf8b98, phase B a5656587) 2026-10-12 18:55:18 +01:00
conductor e0c68ba418 chore(release): auto-bump version to 0.243.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 22s
Auto-version and Release / release (push) Successful in 42s
CI Pipeline / gitea-offline (push) Successful in 23s
CI Pipeline / type-check (push) Failing after 59s
CI Pipeline / lint (push) Failing after 1m19s
CI Pipeline / canary (push) Failing after 2m50s
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 9m26s
Promotion record: (unknown)
2026-10-12 18:45:48 +01:00
Nick a5656587c4 refactor(iteration): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / rust-surface (push) Failing after 18s
CI Pipeline / go-surface (push) Failing after 23s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 36s
Auto-version and Release / release (push) Canceled after 50s
CI Pipeline / type-check (push) Canceled after 20s
CI Pipeline / gitea-offline (push) Canceled after 21s
deploy / deploy (push) Canceled after 51s
CI Pipeline / lint (push) Canceled after 40s
CI Pipeline / unit-tests (push) Canceled after 40s
2026-10-12 18:45:03 +01:00
Nick 8baf8b9845 feat(iteration): port to FULL Rust — dichotomy wave 2026-10-12 18:45:03 +01:00
Nick 7e6e785bcf chore(store): close connection_pool dichotomy contract BUILDER-2026-10-12T17:41:58Z-4eb5a0-factory-batch-b (parity 19887b9b, phase B 7c0a2fb2)
Auto-version and Release / release (push) Canceled after 0s
CI Pipeline / lint (push) Canceled after 0s
CI Pipeline / unit-tests (push) Canceled after 0s
CI Pipeline / go-surface (push) Canceled after 0s
CI Pipeline / rust-surface (push) Canceled after 0s
CI Pipeline / canary (push) Canceled after 0s
CI Pipeline / best-practices (push) Canceled after 0s
CI Pipeline / documentation (push) Canceled after 0s
CI Pipeline / type-check (push) Canceled after 0s
CI Pipeline / gitea-offline (push) Canceled after 0s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
deploy / deploy (push) Canceled after 1s
2026-10-12 18:44:57 +01:00
Nick ebac42f7ca chore(store): register connection_pool dichotomy contract BUILDER-2026-10-12T17:41:58Z-4eb5a0-factory-batch-b (verifying) 2026-10-12 18:44:57 +01:00
Nick 49611fa495 refactor(connection_pool): Phase B language-advantage pass — dichotomy wave 2026-10-12 18:44:56 +01:00
Nick ea177db766 feat(connection_pool): port to FULL Rust — dichotomy wave 2026-10-12 18:44:56 +01:00
conductor 5701a13109 chore(release): auto-bump version to 0.242.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 19s
CI Pipeline / go-surface (push) Failing after 24s
CI Pipeline / gitea-offline (push) Successful in 22s
Auto-version and Release / release (push) Successful in 49s
CI Pipeline / type-check (push) Failing after 56s
CI Pipeline / lint (push) Failing after 1m20s
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 1m43s
CI Pipeline / canary (push) Canceled after 1m43s
Promotion record: (unknown)
2026-10-12 18:43:20 +01:00
Nick 2750eba008 refactor(verification_layer): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 11s
CI Pipeline / rust-surface (push) Failing after 19s
CI Pipeline / go-surface (push) Failing after 22s
CI Pipeline / gitea-offline (push) Successful in 22s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
deploy / deploy (push) Canceled after 27s
Auto-version and Release / release (push) Canceled after 48s
CI Pipeline / canary (push) Canceled after 47s
CI Pipeline / type-check (push) Canceled after 38s
CI Pipeline / unit-tests (push) Canceled after 50s
CI Pipeline / lint (push) Canceled after 51s
2026-10-12 18:42:37 +01:00
Nick d9009cc245 feat(verification_layer): port to FULL Go — dichotomy wave 2026-10-12 18:42:37 +01:00
Nick ac114c3244 refactor(forge): Phase B language-advantage pass — dichotomy wave 2026-10-12 18:42:37 +01:00
Nick cdcae1ead5 feat(forge): port to FULL Go — dichotomy wave 2026-10-12 18:42:37 +01:00
conductor 78a36204b8 chore(release): auto-bump version to 0.241.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 15s
CI Pipeline / go-surface (push) Failing after 23s
CI Pipeline / gitea-offline (push) Successful in 42s
Auto-version and Release / release (push) Successful in 1m19s
CI Pipeline / lint (push) Failing after 1m42s
CI Pipeline / type-check (push) Failing after 1m41s
CI Pipeline / canary (push) Failing after 3m49s
CI Pipeline / unit-tests (push) Failing after 21m18s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 5s
Promotion record: (unknown)
2026-10-12 18:18:20 +01:00
Nick 5f3a0d73a6 chore(store): close construction_depth dichotomy contract BUILDER-2026-10-12T17:14:32Z-844644-factory-batch-b (parity 265bb509, phase B b8b14d5b)
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / rust-surface (push) Failing after 14s
CI Pipeline / go-surface (push) Failing after 17s
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 / unit-tests (push) Canceled after 35s
Auto-version and Release / release (push) Canceled after 36s
CI Pipeline / canary (push) Canceled after 36s
CI Pipeline / lint (push) Canceled after 39s
deploy / deploy (push) Canceled after 25s
CI Pipeline / type-check (push) Canceled after 31s
2026-10-12 18:17:42 +01:00
Nick 55fba58281 chore(store): register construction_depth dichotomy contract BUILDER-2026-10-12T17:14:32Z-844644-factory-batch-b (verifying) 2026-10-12 18:16:16 +01:00
Nick b8b14d5be6 refactor(construction_depth): Phase B language-advantage pass — dichotomy wave 2026-10-12 18:13:11 +01:00
Nick 265bb509a7 feat(construction_depth): port to FULL Rust — dichotomy wave 2026-10-12 18:10:16 +01:00
Nick a2878b76bd refactor(construction_patterns_builtin): Phase B language-advantage pass — dichotomy wave
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 21s
CI Pipeline / gitea-offline (push) Successful in 20s
Auto-version and Release / release (push) Successful in 40s
CI Pipeline / type-check (push) Failing after 51s
CI Pipeline / lint (push) Failing after 1m14s
CI Pipeline / canary (push) Failing after 2m39s
deploy / deploy (push) Failing after 15m56s
CI Pipeline / unit-tests (push) Failing after 17m48s
CI Pipeline / required-checks (push) Failing after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Failing after 5s
The frozen source parses ONCE into a single Registry (revision + typed
patterns — the parity code parsed it twice, once per accessor), the
pattern-id string lattice is a PatternId enum parsed once per side so
lookup is an exhaustive discriminant match instead of repeated string
comparisons, and the revision gate is one exhaustive match; the FFI
extracts borrowed get_pattern args (zero-copy id borrow, ?-propagated)
and the battery parses the truth fn-name lattice into an exhaustive
TruthFn enum with borrow-based case fields and iterator-chain failure
reporting.

Live parity re-verified post-pass: facade 16/16
(scripts/check_cpb_parity.py), clippy 0, cargo fmt clean, battery
verbatim unchanged.
2026-10-12 17:07:21 +01:00
conductor 34b679fbcd chore(release): auto-bump version to 0.240.0 — earned by # (minor: converged release (push-to-master bump))
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / rust-surface (push) Failing after 16s
CI Pipeline / go-surface (push) Failing after 20s
Auto-version and Release / release (push) Successful in 38s
CI Pipeline / gitea-offline (push) Successful in 20s
CI Pipeline / type-check (push) Failing after 52s
CI Pipeline / lint (push) Failing after 1m14s
CI Pipeline / canary (push) Failing after 2m50s
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 11m6s
Promotion record: (unknown)
2026-10-12 16:56:10 +01:00
Nick e41562aa8d refactor(inference_trace): Phase B language-advantage pass — dichotomy wave
CI Pipeline / documentation (push) Successful in 11s
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / rust-surface (push) Failing after 17s
CI Pipeline / go-surface (push) Failing after 21s
CI Pipeline / gitea-offline (push) Successful in 27s
CI Pipeline / required-checks (push) Canceled after 0s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Canceled after 0s
deploy / deploy (push) Canceled after 26s
CI Pipeline / canary (push) Canceled after 45s
CI Pipeline / type-check (push) Canceled after 32s
Auto-version and Release / release (push) Canceled after 47s
CI Pipeline / unit-tests (push) Canceled after 47s
CI Pipeline / lint (push) Canceled after 49s
- rotate_plan: forward map + single reverse (execution order documented:
  oldest-first, live-file source last) instead of rev-then-map
- read_select/cli_tail: borrow the caller's slices end-to-end (rev/take/rev
  over &Value refs) — no per-record clone or intermediate Vec copies
- trace_dir: to_owned on the trimmed slice

Frozen-truth battery green throughout (6 tests / 24 verbatim cases),
clippy 0, live parity 100% re-verified against the rebuilt cdylib.

Contract BUILDER-2026-10-12T13:55:29Z-148b8f-factory-wave.
2026-10-12 16:55:24 +01:00
Nick b5228ace36 feat(inference_trace): port to FULL Rust — dichotomy wave
DICHOTOMY VERDICT: RUST (deterministic decision core; file IO stays
Python-side by design, not by omission — append/rotate/replace, directory
creation, file reads, argv/print are the Python strangler seams).

Replaces the stale W6 stub (wrong struct shape, price_for only).

Ported (name-preserving, src/rust/inference_trace/src/lib.rs):
- price_for (empty map: None for ALL models), trace_dir/trace_path
  (explicit-arg wins else <rune_home>/state)
- serialize (sort_keys + compact separators; recursive BTreeMap key sort)
- rotate_plan (ordered shift pairs BACKUPS..1, I1 source-guard semantics)
  + should_rotate (strict >), read_select (limit trims last N pre-parse,
  blank lines skipped), cli_tail + format_record (indent=2 sorted shape)
- it_loader.py: 6 doc-envelope symbols, freed via capability_scoring
  cs_free_string (never re-exported); facade delegation in
  inference_trace.py with RUNE_IT_CORE=python pin; python fallbacks
  byte-identical.

Truth: scripts/gen_inference_trace_truth.py freezes 24 cases from the live
oracle (RUNE_IT_CORE=python pinned, isolated RUNE_HOME, every public
function, all branches) into frozen_it_truth.json; battery replays it
VERBATIM (6 tests green). Live parity 100% (24/24 byte-identical vs the
freshly built .so). 129 consumer tests green.

Contract BUILDER-2026-10-12T13:55:29Z-148b8f-factory-wave.
2026-10-12 16:55:24 +01:00
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
201 changed files with 106213 additions and 1789 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.237.0**
**Current release: v0.248.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.**
+23 -70
View File
@@ -2,14 +2,14 @@
_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: 36%** (995/2780 runtime functions matched)
**Function-level completion: 46%** (1083/2366 runtime functions matched)
| Status | Modules | Lines | Meaning |
|---|---|---|---|
| FULL | 35 | 12387 | 80%+ of functions ported |
| PARTIAL | 95 | 46242 | 20–80% — real logic exists, gaps named below |
| NOT TOUCHED | 109 | 19373 | no name-preserving implementation |
| Total runtime | 239 | 78002 | |
| FULL | 40 | 13895 | 80%+ of functions ported |
| PARTIAL | 98 | 46825 | 20–80% — real logic exists, gaps named below |
| NOT TOUCHED | 54 | 12187 | no name-preserving implementation |
| Total runtime | 192 | 72907 | |
## NOT TOUCHED — the port queue, in priority order (largest first)
@@ -19,8 +19,6 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| canary_audit_ledger | 541 | 2 | TEST-INFRA |
| tui_validator | 514 | 13 | TUI-LAST |
| 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 |
@@ -30,82 +28,30 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| canary_gitea_automation | 263 | 3 | TEST-INFRA |
| canary_p1_02 | 253 | 10 | TEST-INFRA |
| canary_full_system | 248 | 2 | TEST-INFRA |
| sm_loader | 239 | 14 | unclassified |
| canary_native | 231 | 3 | TEST-INFRA |
| spine_language | 218 | 5 | RUST |
| canary_p0_04 | 207 | 8 | TEST-INFRA |
| wr_loader | 206 | 20 | unclassified |
| cc_loader | 205 | 28 | RUST |
| canary_context_broker | 199 | 10 | TEST-INFRA |
| canary_p0_05 | 199 | 13 | TEST-INFRA |
| cl_loader | 196 | 20 | unclassified |
| canary_spine_meta | 192 | 7 | TEST-INFRA |
| 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 |
| canary_tui_drift | 170 | 2 | TEST-INFRA |
| inference_trace | 164 | 6 | RUST |
| 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 |
| rune_graphic | 145 | 5 | TUI-LAST |
| spine_loader | 144 | 13 | RUST |
| ac_loader | 140 | 11 | unclassified |
| project_registry | 139 | 11 | RUST |
| canary_rune_entry | 137 | 3 | TEST-INFRA |
| do_loader | 137 | 8 | unclassified |
| 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 |
| 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 |
| cpb_loader | 111 | 6 | unclassified |
| tui_transport | 108 | 10 | TUI-LAST |
| canary_unbounded | 105 | 2 | TEST-INFRA |
| message_widgets | 104 | 6 | TUI-LAST |
| ct_loader | 103 | 8 | unclassified |
| sc_loader | 96 | 6 | RUST |
| inference_paths | 95 | 2 | unclassified |
| mutation_guards | 94 | 2 | unclassified |
| cs_loader | 90 | 5 | RUST |
| ci_loader | 89 | 4 | unclassified |
| ee_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 |
| gp_loader | 71 | 6 | unclassified |
| abstraction_ladder | 68 | 3 | unclassified |
| pane_authority | 67 | 2 | unclassified |
| ip_loader | 65 | 4 | unclassified |
| cb_loader | 64 | 3 | unclassified |
| skill_compiler | 64 | 4 | unclassified |
| sg_loader | 63 | 4 | unclassified |
| meaningful_events | 61 | 3 | unclassified |
| outcome_utility | 59 | 4 | unclassified |
| memory_types | 54 | 2 | unclassified |
@@ -118,7 +64,6 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| evidence_capsule | 43 | 3 | unclassified |
| builder_bridge_cli | 42 | 1 | GO |
| __init__ | 40 | 1 | RUST |
| mr_loader | 40 | 15 | RUST |
| canary_memory_synthesis | 33 | 1 | TEST-INFRA |
| canary_resource_authority | 33 | 1 | TEST-INFRA |
| canary_surface_parity | 33 | 1 | TEST-INFRA |
@@ -166,15 +111,14 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| 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 |
| intent_continuity | 284 | 6/14 | _core, _now, _raise_core_err, to_dict, from_dict, save |
| 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 |
@@ -187,12 +131,11 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| persona_definition | 210 | 2/8 | _by_topic, compile_full, emit_constitution, emit_identity, emit_persona, handle_hook |
| progressive_escalation | 279 | 2/8 | execute_with_escalation, test_escalation, handle_hook, to_dict, execute, verify |
| voicebox | 164 | 5/11 | _run, start_recording, stop_recording, _transcribe_and_type, on_press, on_release |
| connection_pool | 148 | 3/8 | get_pool, get_connection, get_status, get_connection, get_status |
| hook_engine | 860 | 3/8 | discover_functions, tag_function, validate_placements, generate_report, handle_hook |
| iteration | 190 | 3/8 | _now, context_packet, predictive_impact, descriptive_impact, add |
| task_persist | 269 | 5/10 | _save, export, restore, main, handle_hook |
| tiered_executor | 291 | 3/8 | _ctx_budget, test_executor, to_dict, to_dict, _execute_model |
| adaptive_router | 625 | 15/19 | _floor_applies_from_flags, _floor_reason, _record_transition_with, _detect_external_refs |
| connection_pool | 226 | 7/11 | _core, get_pool, _kernel_state, _get_connection_core |
| 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 |
@@ -203,7 +146,6 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| salience_gate | 276 | 1/5 | _sg_core, test_salience, handle_hook, to_dict |
| 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 |
@@ -212,28 +154,35 @@ _Regenerate with `python3 scripts/dichotomy_audit.py --write`. A module is FULL
| event_envelope | 303 | 5/8 | test_envelope, to_canonical_dict, to_dict |
| graph_projection | 134 | 3/6 | _model_to_dicts, write_all, _now |
| memory_selector | 590 | 11/14 | _mse_core, add_source, _source_store |
| subsystem_health | 163 | 3/6 | set_auto_filer, record_failure, configure_logging |
| mutation_guards | 143 | 2/5 | _mg_core, _py_classify_mutation, _py_guard_mutation |
| subconscious_pass | 236 | 3/6 | main, _kernel, get_recent_findings |
| subsystem_health | 213 | 4/7 | _kernel, set_auto_filer, configure_logging |
| warm_neuron_store | 122 | 3/6 | _db, neuron_slugs, handle_hook |
| cognitive_budgeter | 221 | 1/3 | test_budgeter, to_dict |
| event_bus | 244 | 5/7 | _store_path, handle_hook |
| experience_encoding | 113 | 1/3 | _ee_core, _py_evaluate |
| inference_trace | 204 | 4/6 | record_trace, read_traces |
| iteration | 261 | 7/9 | _kernel, _now |
| recall_uplift | 193 | 1/3 | _core, _fetch_corpus |
| response_adapter | 222 | 5/7 | test_adapter, to_dict |
| rune_profiler | 165 | 1/3 | profile_model_call, main |
| rune_profiler | 196 | 2/4 | _kernel, main |
| standardized_providers | 281 | 3/5 | list_providers, connect_all_local |
| structural_migration | 77 | 2/4 | apply_migration, consent_brief |
| voice_injector | 138 | 3/5 | test_injection, to_dict |
| construction_depth | 155 | 1/2 | to_dict |
| abstraction_ladder | 102 | 3/4 | _core |
| construction_depth | 172 | 2/3 | _core |
| recall_router | 165 | 2/3 | handle_hook |
## FULL — ported, parity-gated
| Module | Lines | Fns | Side |
|---|---|---|---|
| curator | 1838 | 40/43 | GO |
| curator | 1838 | 43/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 |
@@ -244,18 +193,22 @@ _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 |
| spine_language | 269 | 5/6 | RUST |
| construction_patterns_builtin | 266 | 1/1 | RUST |
| openai_compat_transport | 227 | 9/9 | GO |
| evidence_probe | 213 | 9/9 | GO |
| forge_client | 203 | 18/18 | GO |
| behaviour_ledger | 195 | 11/13 | RUST |
| self_modify | 149 | 7/8 | unclassified |
| recall_uplift | 141 | 1/1 | RUST |
| forge | 146 | 11/11 | GO |
| verification_layer | 136 | 10/11 | RUST |
| rune_spinner | 130 | 4/5 | RUST |
| concept_topology | 128 | 7/8 | unclassified |
| wait_guard | 116 | 1/1 | RUST |
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rune"
version = "0.237.0"
version = "0.248.0"
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
requires-python = ">=3.10"
+301
View File
@@ -0,0 +1,301 @@
#!/usr/bin/env python3
"""Live parity: iteration Rust kernel vs Python oracle (dichotomy wave).
Three layers, all must be green for parity 100%:
1. FROZEN — the 29 frozen-oracle cases replayed VERBATIM through both
the Python floor (oracle sanity) and the Rust kernel.
2. LIVE — oracle (RUNE_ITR_CORE=python) vs facade (kernel auto) on the
same inputs; `iteration._now` is pinned so generated_at /
recorded_at / invalidation clocks are byte-comparable.
3. FUZZ — 400 seeded random structural models / ledgers / behaviour
docs (seed 2479), every public function, both cores.
"""
import copy
import json
import os
import random
import sys
import tempfile
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
sys.path.insert(0, str(REPO / "src" / "rust" / "evidence_provenance"))
os.environ.setdefault("RUNE_LEDGER_CORE", "python")
import rune.iteration as it # noqa: E402
import rune.behaviour_ledger as bl_mod # noqa: E402
from rune.structural_model import StructuralModel # noqa: E402
from rune.capability_ledger import CapabilityLedger # noqa: E402
from rune.behaviour_ledger import BehaviourLedger # noqa: E402
from rune import itr_loader # noqa: E402
PIN_NOW = "2026-10-12T00:00:00Z"
it._now = lambda: PIN_NOW
bl_mod._now = lambda: PIN_NOW
TRUTH = json.loads(
(REPO / "src" / "rust" / "iteration" / "src" / "frozen_it_truth.json")
.read_text())
KINDS = ["project", "domain", "subsystem", "component", "interface",
"state_store", "test_suite", "deployment_surface"]
REL_TYPES = ["belongs_to", "owns", "depends_on", "calls", "provides",
"consumes", "verified_by", "deployed_by"]
MATURITIES = ["DECLARED", "implemented", "retired", "superseded", "candidate"]
fails = []
counts = {"frozen": 0, "live": 0, "fuzz": 0}
def fail(layer, name, detail):
fails.append((layer, name, detail))
print(f"FAIL[{layer}] {name}: {detail}")
def wrap(doc, cls):
o = cls.__new__(cls)
o.doc = doc
return o
# ── fixture factory (oracle-shaped) ─────────────────────────────────────
def make_fixture(rnd, tmp, i):
model = StructuralModel(Path(tmp) / f"m{i}", f"p{i}")
n_ent = rnd.randint(2, 9)
ids = []
for j in range(n_ent):
kind = rnd.choice(KINDS)
eid = model.add(kind, f"e{j}")
ids.append(eid)
if rnd.random() < 0.4:
for e in model.doc["entities"]:
if e["id"] == eid:
e.setdefault("identities", {})["source"] = f"src/{j}.py"
for _ in range(rnd.randint(0, 12)):
a, b = rnd.choice(ids), rnd.choice(ids)
if a == b:
continue
try:
model.relate(a, rnd.choice(REL_TYPES), b,
status=rnd.choice(["active", "stale"]))
except ValueError:
pass
model.doc["schema_version"] = 1
ledger = CapabilityLedger(Path(tmp) / f"l{i}")
for j in range(rnd.randint(1, 4)):
ledger.define(
capability_id=f"cap{j}", name=f"c{j}", purpose="p",
owning_project=f"p{i}",
component=rnd.choice(ids),
source_locations=[f"src/{rnd.randint(0, n_ent)}.py"])
bh = BehaviourLedger(Path(tmp) / f"b{i}")
for j in range(rnd.randint(1, 3)):
bh.define(behaviour_id=f"b{j}", owning_project=f"p{i}",
intended_behaviour="x",
owner_component=rnd.choice(ids),
dependencies=[rnd.choice(ids)])
if rnd.random() < 0.6:
bh.record_real_world(f"b{j}", passed=True, detail="ok")
return model, ledger, bh
def run_all(model, ledger, bh, target):
"""Call every public fn through whatever core is currently pinned."""
out = {}
out["context_packet"] = it.context_packet(
model, ledger, target, intent="i", basis_summary={"d": 1})
out["predictive_impact"] = it.predictive_impact(model, target)
out["descriptive_impact"] = it.descriptive_impact(
model, target, observed_changed=[target, "surprise:x"],
generation="gf")
out["post_change_obligations"] = it.post_change_obligations(
model, target, behaviours=bh)
out["post_change_obligations_nobh"] = it.post_change_obligations(
model, target)
out["invalidate"] = None
return out
# ── 1. frozen replay ────────────────────────────────────────────────────
def frozen():
for group, cases in TRUTH.items():
if group in ("module", "now"):
continue
for c in cases:
counts["frozen"] += 1
args = copy.deepcopy(c["args"])
fn = c["fn"]
now = args.get("now", PIN_NOW)
if fn == "context_packet":
m = wrap(args["model"], StructuralModel)
l = wrap(args.get("ledger") or {"schema_version": 1, "capabilities": {}}, CapabilityLedger)
want = c["expect"]
got_o = it.context_packet(
m, l, args["target"], intent=args.get("intent", ""),
basis_summary=args.get("basis_summary"),
max_local_files=args.get("max_local_files", 12))
got_k = itr_loader.context_packet(
args["model"], args["ledger"], args["target"],
intent=args.get("intent", ""),
basis_summary=args.get("basis_summary"),
max_local_files=args.get("max_local_files", 12),
now=now)
elif fn == "predictive_impact":
m = wrap(args["model"], StructuralModel)
want = c["expect"]
got_o = it.predictive_impact(m, args["target"])
got_k = itr_loader.predictive_impact(args["model"],
args["target"])
elif fn == "descriptive_impact":
m = wrap(args["model"], StructuralModel)
want = c["expect"]
got_o = it.descriptive_impact(
m, args["target"],
observed_changed=args["observed_changed"],
generation=args.get("generation", ""))
got_k = itr_loader.descriptive_impact(
args["model"], args["target"],
observed_changed=args["observed_changed"],
generation=args.get("generation", ""), now=now)
elif fn == "record_impact_delta":
want = c["expect"]
got_o = json.dumps(args["delta"], sort_keys=True)
got_k = itr_loader.record_delta_line(args["delta"])
elif fn == "invalidate_behaviours":
want = c["expect"]
b = wrap(copy.deepcopy(args["behaviours"]), BehaviourLedger)
recs_o = it.invalidate_behaviours(
wrap({"relationships": []}, StructuralModel), b,
changed_entities=set(args["changed"]),
generation=args["generation"])
got_o = {"doc": b.doc, "recs": recs_o}
doc_k, recs_k = itr_loader.invalidate(
args["behaviours"], args["changed"],
args["generation"], now)
got_k = {"doc": doc_k, "recs": recs_k}
elif fn == "post_change_obligations":
m = wrap(args["model"], StructuralModel)
want = c["expect"]
bh = (wrap(args["behaviours"], BehaviourLedger)
if "behaviours" in args else None)
got_o = it.post_change_obligations(
m, args["target"],
changed_entities=set(args["changed"])
if "changed" in args else None,
behaviours=bh)
got_k = itr_loader.post_change_obligations(
args["model"], args["target"],
changed=args.get("changed"),
behaviours_doc=args.get("behaviours"))
else: # pragma: no cover
continue
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if json.dumps(got, sort_keys=True) != json.dumps(
want, sort_keys=True):
fail("frozen", f"{fn}/{c['name']}/{tag}",
f"want={json.dumps(want, sort_keys=True)[:300]} "
f"got={json.dumps(got, sort_keys=True)[:300]}")
# ── 2+3. live + fuzz ────────────────────────────────────────────────────
def compare_pair(name, o, k):
counts["live"] += 1
jo, jk = json.dumps(o, sort_keys=True), json.dumps(k, sort_keys=True)
if jo != jk:
fail("live", name, f"oracle={jo[:300]} kernel={jk[:300]}")
def live_and_fuzz():
rnd = random.Random(2479)
with tempfile.TemporaryDirectory(prefix="it_parity_") as tmp:
# live on the frozen fixture inputs
for group, cases in TRUTH.items():
if group in ("module", "now"):
continue
for c in cases:
args = c["args"]
if "model" not in args:
continue
m = wrap(args["model"], StructuralModel)
l = wrap(args.get("ledger") or {"schema_version": 1, "capabilities": {}}, CapabilityLedger)
bh = (wrap(args["behaviours"], BehaviourLedger)
if "behaviours" in args else None)
target = args["target"]
os.environ["RUNE_ITR_CORE"] = "python"
o = run_all(m, l, bh or
wrap({"behaviours": {}}, BehaviourLedger),
target)
os.environ["RUNE_ITR_CORE"] = "auto"
k = run_all(m, l, bh or
wrap({"behaviours": {}}, BehaviourLedger),
target)
for key in o:
compare_pair(f"{c['name']}/{key}", o[key], k[key])
# fuzz
for i in range(400):
model, ledger, bh = make_fixture(rnd, tmp, i)
target = rnd.choice(
[e["id"] for e in model.doc["entities"]])
os.environ["RUNE_ITR_CORE"] = "python"
o = run_all(model, ledger, bh, target)
os.environ["RUNE_ITR_CORE"] = "auto"
k = run_all(model, ledger, bh, target)
for key in o:
counts["fuzz"] += 1
if json.dumps(o[key], sort_keys=True) != json.dumps(
k[key], sort_keys=True):
fail("fuzz", f"fuzz{i}/{key}",
f"oracle={json.dumps(o[key], sort_keys=True)[:300]} "
f"kernel={json.dumps(k[key], sort_keys=True)[:300]}")
# record_impact_delta line parity
delta = o["descriptive_impact"]
counts["fuzz"] += 1
if json.dumps(delta, sort_keys=True) != \
itr_loader.record_delta_line(delta):
fail("fuzz", f"fuzz{i}/delta_line", "line mismatch")
# invalidate parity (deep-copied docs both sides)
changed = set(rnd.sample(
[e["id"] for e in model.doc["entities"]],
k=min(2, len(model.doc["entities"]))))
bo = BehaviourLedger.__new__(BehaviourLedger)
bo.doc = copy.deepcopy(bh.doc)
os.environ["RUNE_ITR_CORE"] = "python"
recs_o = it.invalidate_behaviours(model, bo,
changed_entities=changed,
generation="gz")
os.environ["RUNE_ITR_CORE"] = "auto"
bk = BehaviourLedger.__new__(BehaviourLedger)
bk.doc = copy.deepcopy(bh.doc)
recs_k = it.invalidate_behaviours(model, bk,
changed_entities=changed,
generation="gz")
counts["fuzz"] += 1
if json.dumps(bo.doc, sort_keys=True) != json.dumps(
bk.doc, sort_keys=True) or \
json.dumps(recs_o, sort_keys=True) != \
json.dumps(recs_k, sort_keys=True):
fail("fuzz", f"fuzz{i}/invalidate", "doc/recs mismatch")
def main():
if not itr_loader.available():
print("kernel not built — build src/rust/iteration first")
return 1
os.environ["RUNE_ITR_CORE"] = "python"
frozen()
live_and_fuzz()
os.environ["RUNE_ITR_CORE"] = "auto"
total = counts["frozen"] + counts["live"] + counts["fuzz"]
print(f"parity {total - len(fails)}/{total} "
f"(frozen {counts['frozen']}, live {counts['live']}, "
f"fuzz {counts['fuzz']})")
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())
+164
View File
@@ -0,0 +1,164 @@
#!/usr/bin/env python3
"""Live parity: rune_profiler Rust kernel vs Python oracle (dichotomy
wave). Layers:
1. FROZEN — 9 frozen-oracle cases (controlled dyadic elapsed deltas)
replayed through BOTH the Python floor and the Rust kernel; means
are BIT-FOR-BIT.
2. FUZZ — 800 seeded random dyadic elapsed sequences (seed 2479)
driven through the oracle with the same monkeypatched clock and
through the kernel; exact compare.
3. LIVE — the real measured path: oracle floor vs facade(kernel) on
the same workloads; timings are nondeterministic by nature so the
comparison is STRUCTURE + INVARIANTS (key set, iterations, ordering
min<=median<=max, p95/p99 within [median, max], mean within
[min, max]).
"""
import itertools
import json
import os
import random
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.rune_profiler as rp # noqa: E402
from rune import rp_loader # noqa: E402
UNIT_NS = 15625 # 1/64 ms — dyadic
REAL_CLOCK = rp.time.perf_counter_ns
REAL_OLLAMA = rp._execute_ollama
TRUTH = json.loads(
(REPO / "src" / "rust" / "rune_profiler" / "src" / "frozen_rp_truth.json")
.read_text())
fails = []
counts = {"frozen": 0, "fuzz": 0, "live": 0}
def fail(layer, name, detail):
fails.append((layer, name, detail))
print(f"FAIL[{layer}] {name}: {detail}")
def drive_oracle(elapsed_units, iterations, model_call):
vals, c = [], 0
for u in elapsed_units:
vals.append(c)
vals.append(c + u * UNIT_NS)
c += u * UNIT_NS
clock = iter(list(vals) + [c])
rp.time.perf_counter_ns = lambda: next(clock)
stub = itertools.count()
rp._execute_ollama = lambda *a, **k: next(stub)
if model_call:
return rp.profile_model_call(iterations=iterations)
return rp.profile_function(lambda: None, iterations=iterations)
def frozen():
for group, cases in TRUTH.items():
if group in ("module", "unit_ns"):
continue
for c in cases:
counts["frozen"] += 1
args = c["args"]
model_call = group == "profile_model_call_cases"
units = [round(t * 64) for t in args["times"]]
want = c["expect"]
got_o = drive_oracle(units, args["iterations"], model_call)
got_k = rp_loader.profile_stats(args["times"],
args["iterations"], model_call)
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if json.dumps(got, sort_keys=True) != json.dumps(
want, sort_keys=True):
fail("frozen", f"{c['name']}/{tag}",
f"want={json.dumps(want, sort_keys=True)[:260]} "
f"got={json.dumps(got, sort_keys=True)[:260]}")
def fuzz():
rnd = random.Random(2479)
for i in range(800):
counts["fuzz"] += 1
n = rnd.choice([1, 2, 3, 5, 20, 100, 101])
model_call = rnd.random() < 0.4
units = [(rnd.randint(1, 8192))] * 0 or \
[rnd.randint(1, 8192) for _ in range(n)]
want = drive_oracle(units, n, model_call)
got = rp_loader.profile_stats([u * UNIT_NS / 1_000_000
for u in units], n, model_call)
if json.dumps(want, sort_keys=True) != json.dumps(
got, sort_keys=True):
fail("fuzz", f"fuzz{i}", f"oracle={want} kernel={got}")
def invariants(stats, n, model_call):
keys = {"min_ms", "max_ms", "mean_ms", "median_ms", "iterations"}
if not model_call:
keys |= {"p95_ms", "p99_ms"}
if set(stats) != keys:
return f"key set {sorted(stats)}"
if stats["iterations"] != n:
return f"iterations {stats['iterations']} != {n}"
if not (stats["min_ms"] <= stats["median_ms"] <= stats["max_ms"]):
return "min<=median<=max violated"
if not (stats["min_ms"] <= stats["mean_ms"] <= stats["max_ms"]):
return "mean out of range"
if not model_call:
if not (stats["median_ms"] <= stats["p95_ms"] <= stats["p99_ms"]
<= stats["max_ms"]):
return "percentile ordering violated"
return None
def live():
rp.time.perf_counter_ns = REAL_CLOCK
rp._execute_ollama = REAL_OLLAMA
for name, fn, n, mc in [
("salience", lambda: sum(range(50)), 50, False),
("trivial", lambda: None, 25, False),
("model_shape", lambda: "ok", 5, True),
]:
os.environ["RUNE_RP_CORE"] = "python"
o = rp.profile_function(fn, iterations=n)
om = rp.profile_model_call(iterations=3)
os.environ["RUNE_RP_CORE"] = "auto"
k = rp.profile_function(fn, iterations=n)
km = rp.profile_model_call(iterations=3)
for tag, a, b, iters, model in [
(name, o, k, n, False),
("model", om, km, 3, True),
]:
counts["live"] += 1
probs = [invariants(a, iters, model),
invariants(b, iters, model)]
if json.dumps(list(a), sort_keys=True) != \
json.dumps(list(b), sort_keys=True):
probs.append("key order differs")
probs = [p for p in probs if p]
if probs:
fail("live", tag, "; ".join(probs))
def main():
if not rp_loader.available():
print("kernel not built — build src/rust/rune_profiler first")
return 1
os.environ["RUNE_RP_CORE"] = "python"
frozen()
fuzz()
live()
os.environ["RUNE_RP_CORE"] = "auto"
total = counts["frozen"] + counts["fuzz"] + counts["live"]
print(f"parity {total - len(fails)}/{total} "
f"(frozen {counts['frozen']}, fuzz {counts['fuzz']}, "
f"live {counts['live']})")
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())
+196
View File
@@ -0,0 +1,196 @@
#!/usr/bin/env python3
"""Live parity: subconscious_pass Rust kernel vs Python oracle (dichotomy
wave). Layers: FROZEN replay (22 cases through oracle floor AND kernel),
LIVE facade-vs-oracle, FUZZ (600 seeded random turns, seed 2479).
`sp.datetime` is frozen so report timestamps and save filenames are
byte-comparable.
"""
import copy
import datetime as _dt
import json
import os
import random
import string
import sys
import tempfile
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
os.environ["RUNE_LEDGER_CORE"] = "python"
import rune.subconscious_pass as sp # noqa: E402
from rune import sp_loader # noqa: E402
FIXED_DT = _dt.datetime(2026, 10, 12, 0, 0, 1, 1, tzinfo=_dt.timezone.utc)
class _FixedDatetime(_dt.datetime):
@classmethod
def now(cls, tz=None):
return FIXED_DT
sp.datetime = _FixedDatetime
TRUTH = json.loads(
(REPO / "src" / "rust" / "subconscious_pass" / "src"
/ "frozen_sp_truth.json").read_text())
fails = []
counts = {"frozen": 0, "live": 0, "fuzz": 0}
WORDS = ("build fix cache index deploy planning drift frustrated confused "
"loader test guard topic refactor shipping agent task".split())
def rand_text(rnd, n=None):
n = n if n is not None else rnd.randint(1, 40)
txt = " ".join(rnd.choice(WORDS) for _ in range(n))
if rnd.random() < 0.2:
txt += "?"
return txt
def fail(layer, name, detail):
fails.append((layer, name, detail))
print(f"FAIL[{layer}] {name}: {detail}")
def frozen():
for group, cases in TRUTH.items():
if group in ("module", "now"):
continue
for c in cases:
counts["frozen"] += 1
args = copy.deepcopy(c["args"])
fn = c["fn"]
if fn == "reflect":
s = sp.SubconsciousPass()
want = c["expect"]
got_o = s.reflect(args["user"], args["agent"],
args.get("context"))
got_k = sp_loader.reflect(args["user"], args["agent"],
args.get("context"), args["now"])
elif fn == "extract_topic":
s = sp.SubconsciousPass()
want = c["expect"]
got_o = s._extract_topic(args["text"])
got_k = sp_loader.extract_topic(args["text"])
elif fn == "recent_findings":
s = sp.SubconsciousPass()
s.findings = list(args["reports"])
want = c["expect"]
got_o = s.get_recent_findings(args.get("limit", 10))
got_k = sp_loader.recent_findings(args["reports"],
args.get("limit", 10))
elif fn == "save_reflection":
want = c["expect"]
got_o = json.dumps(args["report"], indent=2)
got_k = sp_loader.save_report(args["report"])
else: # pragma: no cover
continue
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if json.dumps(got, sort_keys=True) != json.dumps(
want, sort_keys=True):
fail("frozen", f"{fn}/{c['name']}/{tag}",
f"want={json.dumps(want, sort_keys=True)[:260]} "
f"got={json.dumps(got, sort_keys=True)[:260]}")
def compare(name, o, k, layer="live"):
counts[layer] += 1
jo, jk = json.dumps(o, sort_keys=True), json.dumps(k, sort_keys=True)
if jo != jk:
fail(layer, name, f"oracle={jo[:260]} kernel={jk[:260]}")
def run_both(user, agent, ctx, findings):
so = sp.SubconsciousPass()
sk = sp.SubconsciousPass()
so.findings = list(findings)
sk.findings = list(findings)
os.environ["RUNE_SP_CORE"] = "python"
o = {"reflect": so.reflect(user, agent, ctx),
"extract": so._extract_topic(user),
"recent10": so.get_recent_findings(),
"recent0": so.get_recent_findings(0),
"recent3": so.get_recent_findings(3),
"recent_neg2": so.get_recent_findings(-2)}
os.environ["RUNE_SP_CORE"] = "auto"
k = {"reflect": sk.reflect(user, agent, ctx),
"extract": sk._extract_topic(user),
"recent10": sk.get_recent_findings(),
"recent0": sk.get_recent_findings(0),
"recent3": sk.get_recent_findings(3),
"recent_neg2": sk.get_recent_findings(-2)}
return o, k
def live_and_fuzz():
rnd = random.Random(2479)
findings = [{"findings": [{"type": "a", "detail": "d", "severity": "i"}]},
{"findings": []},
{"other": 1}]
# live on the frozen inputs
for group, cases in TRUTH.items():
if group in ("module", "now") or group == "save_reflection_cases":
continue
for c in cases:
args = c["args"]
o, k = run_both(args.get("user", args.get("text", "")),
args.get("agent", "ok"),
args.get("context"), findings)
for key in o:
compare(f"{c['name']}/{key}", o[key], k[key])
# fuzz
with tempfile.TemporaryDirectory(prefix="sp_parity_") as tmp:
for i in range(600):
user = rand_text(rnd, rnd.choice([1, 3, 30, 45]))
agent = rand_text(rnd, rnd.choice([1, 5, 12]))
ctx = None
if rnd.random() < 0.6:
ctx = {}
if rnd.random() < 0.7:
ctx["previous_topic"] = rnd.choice(
["", "index tuning", rand_text(rnd, 4)])
o, k = run_both(user, agent, ctx, findings)
for key in o:
compare(f"fuzz{i}/{key}", o[key], k[key], layer="fuzz")
# save_reflection byte parity through the real oracle path
report = o["reflect"]
so = sp.SubconsciousPass()
sk = sp.SubconsciousPass()
orig_dir = sp.REFLECTIONS_DIR
try:
for tag, inst in (("o", so), ("k", sk)):
d = Path(tmp) / f"{i}{tag}"
d.mkdir()
sp.REFLECTIONS_DIR = str(d)
inst.save_reflection(report)
counts["fuzz"] += 1
fo = sorted((Path(tmp) / f"{i}o").iterdir())[0]
fk = sorted((Path(tmp) / f"{i}k").iterdir())[0]
if fo.name != fk.name or fo.read_text() != fk.read_text():
fail("fuzz", f"fuzz{i}/save", "file bytes differ")
finally:
sp.REFLECTIONS_DIR = orig_dir
def main():
if not sp_loader.available():
print("kernel not built — build src/rust/subconscious_pass first")
return 1
os.environ["RUNE_SP_CORE"] = "python"
frozen()
live_and_fuzz()
os.environ["RUNE_SP_CORE"] = "auto"
total = counts["frozen"] + counts["live"] + counts["fuzz"]
print(f"parity {total - len(fails)}/{total} "
f"(frozen {counts['frozen']}, live {counts['live']}, "
f"fuzz {counts['fuzz']})")
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())
+215
View File
@@ -0,0 +1,215 @@
#!/usr/bin/env python3
"""Live parity: subsystem_health Rust kernel vs Python oracle (dichotomy
wave). Layers:
1. FROZEN — 16 frozen-oracle cases replayed through BOTH the Python
floor and the Rust kernel.
2. FUZZ — 500 seeded registry sequences + failure-core calls
(seed 2479), oracle floor vs kernel, exact compare (sets order-free).
3. LIVE — full record_failure path (logging + event_bus + filer
side effects included): fresh process-global registry, oracle floor
vs facade kernel, comparing surface bools, registry snapshots and
the observed event payloads captured via a monkeypatched event_bus.
"""
import copy
import json
import os
import random
import string
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.subsystem_health as sh # noqa: E402
from rune import sh_loader # noqa: E402
TRUTH = json.loads(
(REPO / "src" / "rust" / "subsystem_health" / "src"
/ "frozen_sh_truth.json").read_text())
fails = []
counts = {"frozen": 0, "fuzz": 0, "live": 0}
SUBS = ["cache", "store", "auth", "broker", "memory", "tui"]
ERRS = ["boom", "disk full", "timeout after 3s", "kaboom 💥", "x" * 350]
def fail(layer, name, detail):
fails.append((layer, name, detail))
print(f"FAIL[{layer}] {name}: {detail}")
def norm_state(reg):
return {"entries": copy.deepcopy(reg._entries),
"surfaced": sorted(reg._surfaced)}
def jnorm(x):
return json.dumps(x, sort_keys=True)
def frozen():
for group, cases in TRUTH.items():
if group in ("module",):
continue
for c in cases:
counts["frozen"] += 1
args = copy.deepcopy(c["args"])
fn = c["fn"]
want = c["expect"]
if fn == "registry_record":
got_k = sh_loader.record(args["entries"], args["surfaced"],
args["subsystem"], args["error"],
args["tier"])
reg = sh.SubsystemHealthRegistry()
reg._entries = args["entries"]
reg._surfaced = set(args["surfaced"])
surface = reg.record(args["subsystem"], args["error"],
args["tier"])
got_o = {"entries": reg._entries,
"surfaced": sorted(reg._surfaced),
"surface": surface}
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if jnorm({"entries": got["entries"],
"surface": got["surface"]}) != \
jnorm({"entries": want["state"]["entries"],
"surface": want["surface"]}) or \
sorted(got["surfaced"]) != \
sorted(want["state"]["surfaced"]):
fail("frozen", f"{fn}/{c['name']}/{tag}",
f"want={jnorm(want)[:260]} got={jnorm(got)[:260]}")
elif fn == "registry_snapshot":
got_o = json.loads(json.dumps(args["entries"]))
got_k = sh_loader.snapshot(args["entries"])
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if jnorm(got) != jnorm(want):
fail("frozen", f"{fn}/{c['name']}/{tag}",
f"want={jnorm(want)[:260]} got={jnorm(got)[:260]}")
elif fn == "failure_core":
got_k = sh_loader.failure_core(
args["error_type"], args["error"], args["context"],
args["tier"])
message = f"{args['error_type']}: {args['error']}"
if args["context"]:
message = f"{message} ({args['context']})"
got_o = {"message": message,
"event_type": sh._TIER_EVENTS.get(
args["tier"], "storage.degraded"),
"payload_error": message[:300]}
for tag, got in (("oracle", got_o), ("kernel", got_k)):
if jnorm(got) != jnorm(want):
fail("frozen", f"{fn}/{c['name']}/{tag}",
f"want={jnorm(want)[:260]} got={jnorm(got)[:260]}")
def fuzz():
rnd = random.Random(2479)
for i in range(500):
counts["fuzz"] += 1
reg_o = sh.SubsystemHealthRegistry()
entries, surfaced = {}, []
ok = True
for _ in range(rnd.randint(1, 8)):
subsystem = rnd.choice(SUBS)
error = rnd.choice(ERRS)
tier = rnd.choice([-1, 0, 1, 2, 3, 99])
ko = sh_loader.record(entries, surfaced, subsystem, error, tier)
surface_o = reg_o.record(subsystem, error, tier)
# the kernel OWNS the evolving state — feed its output forward
entries, surfaced = ko["entries"], list(ko["surfaced"])
if ko["surface"] != surface_o or \
jnorm(ko["entries"]) != jnorm(reg_o._entries) or \
sorted(ko["surfaced"]) != sorted(reg_o._surfaced):
fail("fuzz", f"fuzz{i}", f"record diverged at {subsystem}")
ok = False
break
if ok and jnorm(sh_loader.snapshot(entries)) != \
jnorm(reg_o.snapshot()):
fail("fuzz", f"fuzz{i}/snapshot", "snapshot diverged")
counts["fuzz"] += 1
error_type = rnd.choice(["ValueError", "KeyError", "RuntimeError"])
error = rnd.choice(ERRS)
context = rnd.choice(["", "during flush", "é" * 150])
tier = rnd.choice([-1, 0, 1, 2, 99])
core = sh_loader.failure_core(error_type, error, context, tier)
message = f"{error_type}: {error}"
if context:
message = f"{message} ({context})"
if jnorm(core) != jnorm({
"message": message,
"event_type": sh._TIER_EVENTS.get(tier, "storage.degraded"),
"payload_error": message[:300],
}):
fail("fuzz", f"fuzz{i}/core", f"core={core}")
def live():
"""Full record_failure path: surface bools + registry + observed
event payloads, oracle floor vs facade kernel."""
captured = []
class _CaptureBus:
@staticmethod
def emit(event_type, source="", payload=None):
captured.append({"event_type": event_type, "source": source,
"payload": payload})
import rune.event_bus as eb
orig_emit = eb.emit
eb.emit = _CaptureBus.emit
try:
for i in range(40):
rnd = random.Random(1000 + i)
captured.clear()
sh._AUTO_FILER = None
events = [(rnd.choice(SUBS), rnd.choice(ERRS),
rnd.choice([-1, 0, 1, 2, 3])) for _ in range(5)]
results = {}
for pin in ("python", "auto"):
reg = sh.SubsystemHealthRegistry()
os.environ["RUNE_SH_CORE"] = pin
surfaces = []
seen_events = []
captured.clear()
def fake_emit(event_type, source="", payload=None):
seen_events.append({"event_type": event_type,
"payload": payload})
eb.emit = fake_emit
for subsystem, error, tier in events:
surfaces.append(sh.record_failure(
subsystem, RuntimeError(error), tier=tier,
registry=reg))
results[pin] = {"surfaces": surfaces,
"state": norm_state(reg),
"events": seen_events}
counts["live"] += 1
if jnorm(results["python"]) != jnorm(results["auto"]):
fail("live", f"live{i}",
f"python={jnorm(results['python'])[:260]} "
f"auto={jnorm(results['auto'])[:260]}")
finally:
eb.emit = orig_emit
os.environ["RUNE_SH_CORE"] = "auto"
def main():
if not sh_loader.available():
print("kernel not built — build src/rust/subsystem_health first")
return 1
os.environ["RUNE_SH_CORE"] = "python"
frozen()
fuzz()
live()
os.environ["RUNE_SH_CORE"] = "auto"
total = counts["frozen"] + counts["fuzz"] + counts["live"]
print(f"parity {total - len(fails)}/{total} "
f"(frozen {counts['frozen']}, fuzz {counts['fuzz']}, "
f"live {counts['live']})")
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for <module>.
verifying+closed back-to-back IN ONE PROCESS (shared-store clobber hazard).
Usage: close_contract_batch_a.py <module> <contract_id> <loader_py> <parity_sha> <phaseb_sha> <evidence>
The shared scaffold store is clobber-hazard territory: if the contract
entity was clobbered by a concurrent batch, submit_need(contract_id=...)
re-walks the SAME contract id on the fresh store (concept_topology law).
"""
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
module, cid, loader_py, parity_sha, phaseb_sha = sys.argv[1:6]
evidence = sys.argv[6]
iface = ConstructionInterface(builder="factory-batch-a")
r = iface.submit_need(
f"Port src/rune/{module}.py to FULL Rust (dichotomy factory, issue "
f"#2479 tranche): doc-envelope FFI, ctypes loader, facade delegation "
f"pin, frozen-truth battery, live parity 100%, Phase B "
f"language-advantage pass.",
origin="builder",
contract_id=cid,
)
print("submit_need:", json.dumps(r)[:300])
if not r.get("success"):
print("NEED FAILED — aborting")
sys.exit(1)
t = iface.transition(cid, "verifying")
print("transition->verifying:", json.dumps(t)[:300])
if not t.get("success"):
sys.exit(1)
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": evidence,
}], scope_files=[
f"src/rune/{module}.py",
f"src/rune/{loader_py}",
f"src/rust/{module}/src/lib.rs",
f"src/rust/{module}/src/branch_battery.rs",
f"scripts/gen_{module}_truth.py",
])
print("close:", json.dumps(c)[:400])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for connection_pool
with SHA evidence."""
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
cid = sys.argv[1]
iface = ConstructionInterface(builder="factory-batch-b")
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "connection_pool dichotomy completion — parity 19887b9b "
"feat(connection_pool): port to FULL Rust — dichotomy wave; "
"Phase B (Action enum + zero-copy borrowed pooling-order "
"scan) pushed gitea/master. Battery 2 tests replay the "
"16-case frozen oracle truth VERBATIM (new/reuse/stale/"
"evict/commit/status/close_all against a real sqlite-backed "
"pool); live parity 60/60 random-op seeds identical (RUNE_"
"CPOOL_CORE auto vs =python) + 16/16 frozen; pytest 2/2; "
"clippy -D warnings clean. Classification flipped GO→RUST "
"in store/rebase/classification.json (programme verdict; "
"sqlite handles stay in the facade). Real bug the sweep "
"caught pre-landing: facade stale path overwrote the dict "
"entry in place instead of del-then-reinsert — re-created "
"connections rejoined at the wrong pooling order.",
}], scope_files=[
"src/rune/connection_pool.py",
"src/rune/cpool_loader.py",
"src/rust/connection_pool/src/lib.rs",
"src/rust/connection_pool/src/branch_battery.rs",
"src/rust/connection_pool/frozen_cpool_truth.json",
"scripts/gen_connection_pool_truth.py",
"tests/test_connection_pool.py",
"store/rebase/classification.json",
"scripts/walk_contract_connection_pool.py",
"scripts/close_contract_connection_pool.py",
])
print("close:", json.dumps(c)[:300])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for
construction_depth with SHA evidence."""
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
cid = sys.argv[1]
iface = ConstructionInterface(builder="factory-batch-b")
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "construction_depth dichotomy completion — parity 265bb509 "
"feat(construction_depth): port to FULL Rust — dichotomy wave; "
"Phase B b8b14d5b refactor(construction_depth): Phase B "
"language-advantage pass — dichotomy wave (both pushed "
"gitea/master). Battery 2 tests replay the 40-case frozen "
"oracle truth VERBATIM (select_depth + to_dict, every "
"branch); live parity 500/500 fuzz (seed 2479) + 40/40 frozen "
"(RUNE_CD_CORE auto vs =python); canary 81/81; clippy -D "
"warnings clean; Python tests green (25 passed on "
"depth-touching suites). Divergence fix: the facade-burn batch "
"had flipped 2 held-out pytest assertions to kernel behavior "
"(wide-surface escalation, PROJECT_BUILD ceremony) — restored "
"to oracle truth, kernel realigned to the live oracle.",
}], scope_files=[
"src/rune/construction_depth.py",
"src/rune/cd_loader.py",
"src/rust/construction_depth/src/lib.rs",
"src/rust/construction_depth/src/branch_battery.rs",
"src/rust/construction_depth/frozen_cd_truth.json",
"src/rust/construction_depth/canary_construction_depth.py",
"scripts/gen_construction_depth_truth.py",
"scripts/walk_contract_construction_depth.py",
"scripts/close_contract_construction_depth.py",
])
print("close:", json.dumps(c)[:400])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
@@ -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")
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for
intent_continuity with SHA evidence."""
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
cid = sys.argv[1]
iface = ConstructionInterface(builder="factory-batch-b")
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "intent_continuity dichotomy completion — parity 5893a37c "
"feat(intent_continuity): port to FULL Rust — dichotomy wave; "
"Phase B 6f9e0cfa refactor(intent_continuity): Phase B "
"language-advantage pass — dichotomy wave (both pushed "
"gitea/master). Battery 2 tests replay the 16-case frozen "
"oracle truth VERBATIM (every transition/branch incl. error "
"envelopes, stubbed clock); live parity 16/16 frozen + 40/40 "
"fuzz seeds (RUNE_IC_CORE auto vs =python); pytest 26 passed "
"(intent_continuity + await_intent); clippy -D warnings "
"clean. Divergences the fuzz caught pre-landing: KeyError "
"double-quoting, create_detour validation order (parent "
"existence before classification), and PARK-by-id vs the "
"oracle's PARK-the-looked-up-object semantics when "
"id==parent_intent.",
}], scope_files=[
"src/rune/intent_continuity.py",
"src/rune/ic_loader.py",
"src/rust/intent_continuity/src/lib.rs",
"src/rust/intent_continuity/src/branch_battery.rs",
"src/rust/intent_continuity/frozen_ic_truth.json",
"scripts/gen_intent_continuity_truth.py",
"scripts/walk_contract_intent_continuity.py",
"scripts/close_contract_intent_continuity.py",
])
print("close:", json.dumps(c)[:300])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave construction contract for recall_uplift
with SHA evidence."""
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
cid = sys.argv[1]
iface = ConstructionInterface(builder="factory-batch-b")
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": "recall_uplift dichotomy completion — parity de8c93c9 "
"feat(recall_uplift): port to FULL Rust — dichotomy wave; "
"Phase B b0aaf4b5 refactor(recall_uplift): Phase B "
"language-advantage pass — dichotomy wave (both pushed "
"gitea/master). Battery 2 tests replay the 12-case frozen "
"oracle truth VERBATIM (map branches, store pass, LIMIT-32, "
"df filter, 24-term cap, degrade); live parity 12/12 frozen "
"+ 300/300 fuzz seed 2479 (RUNE_RU_CORE auto vs =python); "
"pytest test_recall_uplift 5/5 (2 pre-existing unrelated "
"RecursionError failures in memory_store._rank_fusion on the "
"clean tree); clippy -D warnings clean. Portable law baked "
"into the truth: CPython set iteration makes same-count "
"candidate tie order hash-random — frozen corpora engineered "
"tie-free.",
}], scope_files=[
"src/rune/recall_uplift.py",
"src/rune/ru_loader.py",
"src/rust/recall_uplift/src/lib.rs",
"src/rust/recall_uplift/src/branch_battery.rs",
"src/rust/recall_uplift/frozen_ru_truth.json",
"scripts/gen_recall_uplift_truth.py",
"scripts/walk_contract_recall_uplift.py",
"scripts/close_contract_recall_uplift.py",
])
print("close:", json.dumps(c)[:300])
print("CONTRACT", cid, "closed" if c.get("success") else "CLOSE_FAILED")
+20 -1
View File
@@ -37,6 +37,12 @@ TEST_INFRA = {
"conftest", "test_truth", "test_adaptive_router", "test_canaries",
}
RETIRES = {"memory_env", "__main__"}
# The *_loader family is the programme's OWN ctypes FFI machinery — the
# delegation glue created by the ports themselves (broker_loader.py et al).
# Per the strangler-fig deletion doctrine they burn with the Python facades
# at stage 3; porting a loader to Rust is circular. Machinery, not port
# surface — same category as dunders.
FFI_MACHINERY = ("_loader",)
def snake_to_camel(name: str) -> list[str]:
@@ -96,10 +102,14 @@ def implementation_corpus() -> dict[str, str]:
for d in sorted(RUST.iterdir()):
src = d / "src"
if src.exists():
# A module may have BOTH a Go and a Rust implementation
# (e.g. verification_layer: full Go port + partial Rust
# crate). Concatenate — never let one side shadow the other.
chunks = [f.read_text(encoding="utf-8", errors="replace")
for f in src.rglob("*.rs")]
if chunks:
corpus[d.name] = "\n".join(chunks)
corpus[d.name] = corpus.get(d.name, "") + "\n" + "\n".join(chunks)
return corpus
@@ -107,6 +117,10 @@ 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"],
@@ -145,6 +159,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"],
}
@@ -173,6 +188,10 @@ def audit() -> dict:
rows.append({"module": stem, "lines": len(path.read_text(errors='replace').splitlines()),
"fns": 0, "matched": 0, "side": "RETIRES", "status": "RETIRES", "missing": []})
continue
if stem.endswith(FFI_MACHINERY) or stem == "ffi_query_memory_smoke":
rows.append({"module": stem, "lines": len(path.read_text(errors='replace').splitlines()),
"fns": 0, "matched": 0, "side": "FFI-MACHINERY", "status": "RETIRES", "missing": []})
continue
if stem.startswith(TEST_PREFIXES) or stem in TEST_INFRA:
rows.append({"module": stem, "lines": len(path.read_text(errors='replace').splitlines()),
"fns": 0, "matched": 0, "side": "TEST", "status": "TEST", "missing": []})
+125
View File
@@ -0,0 +1,125 @@
#!/usr/bin/env python3
"""freeze_truth.py — shared truth-freezing harness for dichotomy ports.
ONE law for every factory agent freezing oracle truth. Replaces per-agent
reinvention of: pinned clock, deep-copy inputs, envelope shape, verbatim
embedding. Same conventions as the port laws in the verification ladder:
* RUNE_*_CORE=python pinned during capture (oracle runs pure Python)
* `now` is always an argument (no-clock law) — callers pass ISO-8601
* inputs are deep-copied before every call (no live-reference aliasing)
* truth is JSON: [{"fn", "args", "kwargs", "expected"}...] — embedded
VERBATIM into the battery (never hand-transcribed)
Usage (as a library, from a generator script):
from freeze_truth import freeze
cases = freeze("module_name", [
("fn_name", (arg1, arg2), {"kw": 1}),
("other_fn", (deep_copied_obj,), {}),
], oracle_module="rune.module_name")
Usage (as a script, to re-verify a frozen file against the live oracle):
python3 scripts/freeze_truth.py --verify src/rust/<crate>/frozen_truth.json \
--module rune.<module>
The generator script (per module) imports this, builds the case list
exercising EVERY public function and branch, then writes the JSON file.
"""
from __future__ import annotations
import argparse
import copy
import importlib
import json
import os
import sys
from pathlib import Path
REPO = Path(__file__).resolve().parents[1]
def _pin_oracle_cores(module_name: str) -> None:
"""Set RUNE_<MODULE>_CORE=python for the oracle's own loader."""
stem = module_name.rsplit(".", 1)[-1]
os.environ[f"RUNE_{stem.upper()}_CORE"] = "python"
def _snap(value):
"""Deep-snapshot a value into JSON-safe form (live-reference aliasing law)."""
return copy.deepcopy(value)
def freeze(module_name: str, cases, oracle_module: str | None = None) -> list[dict]:
"""Run each (fn_name, args, kwargs) against the live oracle; return truth.
Args and kwargs are deep-copied before EVERY call — the oracle may
mutate its inputs (live-reference aliasing trap). The recorded "args"
are the post-copy snapshots, so the battery replays byte-identical
inputs.
"""
_pin_oracle_cores(oracle_module or module_name)
mod = importlib.import_module(oracle_module or module_name)
truth = []
for entry in cases:
if len(entry) == 3:
fn_name, args, kwargs = entry
elif len(entry) == 2:
fn_name, args = entry
kwargs = {}
else:
raise ValueError(f"bad case entry: {entry!r}")
fn = getattr(mod, fn_name, None)
if fn is None:
raise AttributeError(f"{oracle_module or module_name}.{fn_name} missing — case list must name real functions")
a_snap = _snap(list(args))
k_snap = _snap(dict(kwargs))
result = fn(*copy.deepcopy(a_snap), **copy.deepcopy(k_snap))
truth.append({
"fn": fn_name,
"args": a_snap,
"kwargs": k_snap,
"expected": _snap(result),
})
return truth
def write(truth: list[dict], path: Path) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(truth, indent=2, ensure_ascii=False, sort_keys=False) + "\n")
def verify(path: Path, oracle_module: str) -> int:
"""Re-freeze from the live oracle and byte-compare against the frozen file.
Catches self-consistent misreads: the battery and the generator can
agree while the oracle drifted. Returns 0 on byte-exact match.
"""
frozen = json.loads(path.read_text())
cases = [(c["fn"], c["args"], c["kwargs"]) for c in frozen]
fresh = freeze(oracle_module, cases, oracle_module)
if json.dumps(fresh, sort_keys=True) != json.dumps(frozen, sort_keys=True):
print(f"MISMATCH: regenerated truth differs from {path}")
for f, g in zip(frozen, fresh):
if json.dumps(f, sort_keys=True) != json.dumps(g, sort_keys=True):
print(f" first divergence at fn={f['fn']}")
print(f" frozen: {json.dumps(f['expected'])[:200]}")
print(f" oracle: {json.dumps(g['expected'])[:200]}")
break
return 1
print(f"OK: {len(frozen)} cases byte-identical against live oracle {oracle_module}")
return 0
def main() -> int:
ap = argparse.ArgumentParser()
ap.add_argument("--verify", type=Path, help="frozen truth JSON to verify")
ap.add_argument("--module", required=True, help="dotted oracle module, e.g. rune.work_manager")
args = ap.parse_args()
if args.verify:
return verify(args.verify, args.module)
ap.print_help()
return 2
if __name__ == "__main__":
sys.exit(main())
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""gen_connection_pool_truth.py — freeze the connection_pool parity oracle
(dichotomy wave #2479 tranche).
Generator law: RUNE_CPOOL_CORE=python pinned (the Rust core must never see
the freeze), inputs deep-copied, every public kernel branch exercised
(new / reuse / stale-removal / capacity-eviction / commit / status /
close_all) against a REAL sqlite-backed pool in a temp dir. Output:
src/rust/connection_pool/frozen_cpool_truth.json — replayed VERBATIM by the
crate's cfg(test) battery.
"""
import copy
import json
import os
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
os.environ["RUNE_CPOOL_CORE"] = "python"
from rune.connection_pool import ConnectionPool # noqa: E402
MAX = 2
cases: list = []
def pool_state(p: ConnectionPool) -> dict:
"""The kernel-shaped pool state, as the oracle holds it right now."""
st = p.get_status()
return {"max_connections": st["max_connections"],
"databases": copy.deepcopy(st["databases"])}
def record_begin_get(p: ConnectionPool, db_path: str, valid: bool) -> None:
"""Run one oracle get_connection op and freeze it: a cpool_begin_get
case (and, when the oracle created a connection, the matching
cpool_commit case)."""
before = pool_state(p)
pooled_before = dict(p.connections)
conn = p.get_connection(db_path)
after_full = pool_state(p)
reuse = db_path in pooled_before and conn is pooled_before[db_path]
if reuse:
after_begin = copy.deepcopy(before)
else:
after_begin = {"max_connections": after_full["max_connections"],
"databases": [d for d in after_full["databases"]
if d != db_path]}
evicted = (set(before["databases"]) - set(after_full["databases"])
- {db_path})
cases.append({
"fn": "cpool_begin_get",
"args": {"pool": copy.deepcopy(before), "db_path": db_path,
"valid": valid},
"expected": {"pool": after_begin, "reuse": reuse,
"evict": sorted(evicted)[0] if evicted else None},
})
if not reuse:
cases.append({
"fn": "cpool_commit",
"args": {"pool": copy.deepcopy(after_begin), "db_path": db_path},
"expected": {"pool": copy.deepcopy(after_full)},
})
def main() -> None:
with tempfile.TemporaryDirectory() as td:
p = ConnectionPool(max_connections=MAX)
cases.append({
"fn": "cpool_new",
"args": {"max_connections": MAX},
"expected": copy.deepcopy(pool_state(p)),
})
dbs = [os.path.join(td, f"{n}.db") for n in "ABCD"]
record_begin_get(p, dbs[0], True) # create A
record_begin_get(p, dbs[0], True) # reuse A
record_begin_get(p, dbs[1], True) # create B
record_begin_get(p, dbs[2], True) # create C — evicts A
# force B stale: close the underlying connection, then re-get
p.connections[dbs[1]].close()
record_begin_get(p, dbs[1], False) # stale B — no evict
record_begin_get(p, dbs[3], True) # create D — evicts C
before_status = pool_state(p)
cases.append({
"fn": "cpool_status",
"args": {"pool": copy.deepcopy(before_status)},
"expected": copy.deepcopy(p.get_status()),
})
before_close = pool_state(p)
p.close_all()
cases.append({
"fn": "cpool_close_all",
"args": {"pool": copy.deepcopy(before_close)},
"expected": copy.deepcopy(pool_state(p)),
})
record_begin_get(p, dbs[0], True) # fresh pool: create A
doc = {
"module": "connection_pool",
"pin": "RUNE_CPOOL_CORE=python",
"frozen_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"cases": cases,
}
out = ROOT / "src" / "rust" / "connection_pool" / "frozen_cpool_truth.json"
out.write_text(json.dumps(doc, indent=1) + "\n")
print(f"frozen {len(cases)} cases -> {out}")
if __name__ == "__main__":
main()
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env python3
"""gen_construction_depth_truth.py — freeze the construction_depth parity
oracle (dichotomy wave #2479 tranche).
Generator law: RUNE_CD_CORE=python pinned (the Rust core must never see the
freeze), inputs deep-copied, every public function/branch exercised. Output:
src/rust/construction_depth/frozen_cd_truth.json — replayed VERBATIM by the
crate's cfg(test) battery.
"""
import copy
import json
import os
import sys
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
os.environ["RUNE_CD_CORE"] = "python"
from rune.construction_depth import Depth, select_depth # noqa: E402
WIDE = [f"surface-{i}" for i in range(6)]
CASES = [
# branch: NOT_CONSTRUCTION → NONE, everything bypassed
dict(mode="NOT_CONSTRUCTION"),
# branch: UNKNOWN → UNRESOLVED, probe/clarify
dict(mode="UNKNOWN"),
# branch: LOCAL_CHANGE → LIGHT, minimal ceremony
dict(mode="LOCAL_CHANGE", objective="fix typo"),
# branch: LOCAL_CHANGE + user-locked layout
dict(mode="LOCAL_CHANGE", objective="tweak layout", user_locked_layout=True),
# branch: PROJECT_BUILD → FULL lifecycle
dict(mode="PROJECT_BUILD", objective="new project"),
# branch: EXISTING_PROJECT_CHANGE base (default path)
dict(mode="EXISTING_PROJECT_CHANGE", objective="add feature"),
# modifier: migration
dict(mode="EXISTING_PROJECT_CHANGE", has_migration=True),
# modifier: breaking
dict(mode="EXISTING_PROJECT_CHANGE", breaking=True),
# modifier: user-locked layout
dict(mode="EXISTING_PROJECT_CHANGE", user_locked_layout=True),
# modifier: external service
dict(mode="EXISTING_PROJECT_CHANGE", external_service=True),
# modifier: uncertainty high (inserts evidence probe at ceremony[0])
dict(mode="EXISTING_PROJECT_CHANGE", uncertainty="high"),
# modifier: uncertainty partial (no-op branch — no probe)
dict(mode="EXISTING_PROJECT_CHANGE", uncertainty="partial"),
# modifier: wide surface (>5 entries) → FULL
dict(mode="EXISTING_PROJECT_CHANGE", affected_surface=list(WIDE)),
# modifier: breaking + migration → FULL
dict(mode="EXISTING_PROJECT_CHANGE", breaking=True, has_migration=True),
# every modifier at once (wide surface wins over breaking+migration reason)
dict(mode="EXISTING_PROJECT_CHANGE", has_migration=True, breaking=True,
user_locked_layout=True, external_service=True,
uncertainty="high", affected_surface=list(WIDE)),
# non-canonical mode falls through to the EXISTING_PROJECT_CHANGE path
dict(mode="RESEARCHED_CHANGE", objective="investigate options"),
dict(mode="WEIRD_MODE"),
# empty affected_surface list (falsy — no wide-surface branch)
dict(mode="EXISTING_PROJECT_CHANGE", affected_surface=[]),
# exactly 5 entries — boundary (not > 5, stays STANDARD)
dict(mode="EXISTING_PROJECT_CHANGE",
affected_surface=[f"s{i}" for i in range(5)]),
# objective passthrough (ignored by the kernel — recorded for truth)
dict(mode="LOCAL_CHANGE", objective="rename variable", uncertainty=""),
]
def main() -> None:
cases = []
for kwargs in CASES:
args = copy.deepcopy(kwargs)
d = select_depth(**copy.deepcopy(kwargs))
expected = copy.deepcopy(d.to_dict())
cases.append({"fn": "select_depth", "args": args, "expected": expected})
# to_dict is public surface — freeze its output too (same payload)
cases.append({"fn": "to_dict",
"args": {"select": copy.deepcopy(kwargs)},
"expected": copy.deepcopy(d.to_dict())})
doc = {
"module": "construction_depth",
"pin": "RUNE_CD_CORE=python",
"frozen_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"cases": cases,
}
out = ROOT / "src" / "rust" / "construction_depth" / "frozen_cd_truth.json"
out.write_text(json.dumps(doc, indent=1) + "\n")
print(f"frozen {len(cases)} cases -> {out}")
if __name__ == "__main__":
main()
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}")
+375
View File
@@ -0,0 +1,375 @@
#!/usr/bin/env python3
"""Freeze the oracle truth for the GO port of src/rune/forge.py (dichotomy
wave #2479, GO). Every public function, every branch, against the LIVE
oracle. IO seams (subprocess, urllib, the gitea_auth credential ladder) are
monkeypatched deterministically and every IO call is captured (argv, URL,
headers) so the GO battery replays VERBATIM.
machine-dependent values are normalized:
* subprocess argv[0] (sys.executable) is dropped — the GO port's python
binary is a seam default ("python3"), so rows pin argv[1:] only
* the credential ladder error message pins $HOME as <HOME>
"""
from __future__ import annotations
import contextlib
import json
import os
import subprocess
import sys
import tempfile
import types
import urllib.request
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
sys.path.insert(0, str(ROOT / "scripts"))
from rune import forge # noqa: E402
import gitea_auth # noqa: E402
rows: list[dict] = []
class FakeResponse:
def __init__(self, body: bytes):
self._body = body
def read(self) -> bytes:
return self._body
def __enter__(self):
return self
def __exit__(self, *exc):
return False
class CapturedRequest:
def __init__(self, req: urllib.request.Request):
self.method = req.get_method()
self.url = req.full_url
self.headers = {k.lower(): v for k, v in req.header_items()}
@contextlib.contextmanager
def fake_http(handler):
"""handler(captured: CapturedRequest) → body bytes | raises OSError."""
calls = []
def urlopen(req, timeout=None):
cap = CapturedRequest(req)
calls.append({"method": cap.method, "url": cap.url,
"headers": cap.headers})
out = handler(cap)
if isinstance(out, OSError):
raise out
return FakeResponse(out)
orig = urllib.request.urlopen
urllib.request.urlopen = urlopen
try:
yield calls
finally:
urllib.request.urlopen = orig
class FakeProc:
def __init__(self, rc, stdout="", stderr=""):
self.returncode = rc
self.stdout = stdout
self.stderr = stderr
@contextlib.contextmanager
def fake_subprocess(calls):
def run(argv, capture_output=False, text=False, **kw):
calls.append({"argv": list(argv)})
return FakeProc(*PENDING_RC.get("args", (0, "", "")))
orig = subprocess.run
subprocess.run = run
try:
yield calls
finally:
subprocess.run = orig
PENDING_RC = {"args": (0, "", "")}
def record(name, op, setup, want):
rows.append({"name": name, "op": op, "setup": setup, "want": want})
def clean_env(monkeypatch_env: dict):
"""Run fn with a controlled GITEA_* environment."""
saved = {}
keys = ["GITEA_SERVER", "GITEA_REPO", "GITEA_TOKEN", "GITEA_TOKEN_FILE"]
for k in keys:
saved[k] = os.environ.pop(k, None)
os.environ.update({k: v for k, v in monkeypatch_env.items()})
return saved
def restore_env(saved):
for k, v in saved.items():
if v is None:
os.environ.pop(k, None)
else:
os.environ[k] = v
# ── default_forge ───────────────────────────────────────────────────────────
f = forge.default_forge()
record("default_forge:working-adapter", "default_forge", {},
{"server": f._server, "repo": f._repo})
# ── _env ────────────────────────────────────────────────────────────────────
for name, server, repo, env in [
("env:inherits-and-defaults", None, None, {}),
("env:server-override", "http://local:3000", None, {}),
("env:repo-explicit", None, "other/repo", {}),
("env:env-server-kept-when-no-attr", None, None,
{"GITEA_SERVER": "http://env-server"}),
("env:env-server-overridden-by-attr", "http://attr", None,
{"GITEA_SERVER": "http://env-server"}),
("env:env-repo-not-clobbered", None, None, {"GITEA_REPO": "env/repo"}),
("env:inherits-sample-var", None, None, {"RUNE_SAMPLE": "1"}),
]:
eff_env = dict(env)
eff_env.setdefault("RUNE_SAMPLE", "")
saved = clean_env(eff_env)
os.environ["RUNE_SAMPLE"] = eff_env["RUNE_SAMPLE"]
gf = forge.GiteaForge(server=server, repo=repo or "conductor/rune")
built = gf._env()
want = {k: built.get(k) for k in
("GITEA_SERVER", "GITEA_REPO", "RUNE_SAMPLE")}
restore_env(saved)
record(f"_env:{name}", "env", {"server": server, "repo": repo,
"environ": eff_env}, want)
# ── push ────────────────────────────────────────────────────────────────────
for name, rc, stderr, branch in [
("push:ok", 0, "", "feature-x"),
("push:fail-short-stderr", 1, "rejected non-fast-forward", "main"),
("push:fail-long-stderr-truncates-200", 128, "e" * 300, "dev"),
("push:fail-empty-stderr", 2, "", "release"),
]:
gf = forge.GiteaForge()
calls = []
PENDING_RC["args"] = (rc, "", stderr)
with fake_subprocess(calls):
try:
out = gf.push("ignored/repo", branch)
err = None
except forge.ForgeUnavailable as exc:
out, err = None, str(exc)
PENDING_RC["args"] = (0, "", "")
record(f"push:{name}", "push",
{"repo": "ignored/repo", "branch": branch, "rc": rc,
"stderr": stderr},
{"result": out, "error": err, "calls": calls})
# ── gitea_auth credential ladder (the REAL scripts module) ─────────────────
tmp = Path(tempfile.mkdtemp(prefix="forge-truth-"))
FIXTURES = ROOT / "src/go/forge/fixtures"
FIXTURES.mkdir(parents=True, exist_ok=True)
good_file = FIXTURES / "token0600"
good_file.write_text("filetoken123\n")
os.chmod(good_file, 0o600)
bad_file = FIXTURES / "token0644"
bad_file.write_text("weaktoken\n")
os.chmod(bad_file, 0o644)
@contextlib.contextmanager
def fake_helper():
orig = gitea_auth._token_from_credential_helper
gitea_auth._token_from_credential_helper = lambda: ""
try:
yield
finally:
gitea_auth._token_from_credential_helper = orig
# rung 1: GITEA_TOKEN (stripped)
saved = clean_env({})
os.environ["GITEA_TOKEN"] = " envtoken \n"
record("gitea_auth:env-token-rung", "gitea_auth",
{"environ": {"GITEA_TOKEN": " envtoken \n"}},
{"has_token": gitea_auth.has_token(),
"get_token": gitea_auth.get_token()})
os.environ.pop("GITEA_TOKEN")
# rung 2: token file (0600)
os.environ["GITEA_TOKEN_FILE"] = str(good_file)
record("gitea_auth:token-file-0600", "gitea_auth",
{"environ": {"GITEA_TOKEN_FILE": "<fixture token0600>"}},
{"has_token": gitea_auth.has_token(),
"get_token": gitea_auth.get_token()})
# rung 2 rejected: token file (0644 → PermissionError)
os.environ["GITEA_TOKEN_FILE"] = str(bad_file)
try:
gitea_auth.get_token()
got = {"has_token": gitea_auth.has_token(), "get_token": None,
"error": None}
except PermissionError as exc:
got = {"has_token": gitea_auth.has_token(), "get_token": None,
"error": str(exc).replace(str(FIXTURES) + "/", "<FIXTURES>/")}
record("gitea_auth:token-file-0644-rejected", "gitea_auth",
{"environ": {"GITEA_TOKEN_FILE": "<fixture token0644>"}}, got)
# rung 3 empty + nothing anywhere → GiteaCredentialError. The default token
# file and the credential helper are pinned so the row is machine-independent.
os.environ.pop("GITEA_TOKEN_FILE")
pinned_file = tmp / "missing-token"
orig_default = gitea_auth.DEFAULT_TOKEN_FILE
gitea_auth.DEFAULT_TOKEN_FILE = pinned_file
with fake_helper():
try:
gitea_auth.get_token()
no_cred = {"has_token": True, "get_token": "unexpected",
"error": None}
except gitea_auth.GiteaCredentialError as exc:
no_cred = {"has_token": gitea_auth.has_token(), "get_token": None,
"error": str(exc).replace(str(tmp) + "/", "<TMP>/")}
gitea_auth.DEFAULT_TOKEN_FILE = orig_default
record("gitea_auth:no-credential", "gitea_auth",
{"default_token_file": "<TMP>/missing-token"}, no_cred)
restore_env(saved)
# ── commit_status ───────────────────────────────────────────────────────────
def auth_stub(has=True, token="t0k3n"):
m = types.SimpleNamespace()
m.has_token = lambda: has
m.get_token = lambda: token
return m
for name, server, env_server, repo, sha, has_tok, body, http_err in [
("commit_status:no-token", None, None, "conductor/rune", "abc", False,
None, None),
("commit_status:success", None, None, "conductor/rune", "abc", True,
b'{"state": "success"}', None),
("commit_status:state-missing-unknown", None, None, "o/r", "def", True,
b'{"statuses": []}', None),
("commit_status:server-attr-wins", "http://attr:3000", "http://env:3000",
"o/r", "ghi", True, b'{"state": "pending"}', None),
("commit_status:server-from-env", None, "http://env:3000", "o/r", "ghi",
True, b'{"state": "failure"}', None),
("commit_status:http-error", None, None, "o/r", "jkl", True, None,
OSError("HTTP Error 404: Not Found")),
("commit_status:network-error", None, None, "o/r", "jkl", True, None,
OSError("conn refused")),
]:
gf = forge.GiteaForge(server=server)
saved = clean_env({"GITEA_SERVER": env_server} if env_server else {})
forge.GiteaForge._gitea_auth = staticmethod(
lambda: auth_stub(has=has_tok)) # noqa: B010
calls = []
try:
with fake_http(lambda cap: http_err if http_err else body) as captured:
try:
state = gf.commit_status(repo, sha)
err = None
except forge.ForgeUnavailable as exc:
state, err = None, str(exc)
req = captured[0] if captured else None
finally:
restore_env(saved)
del forge.GiteaForge._gitea_auth
record(f"commit_status:{name}", "commit_status",
{"server": server, "env_server": env_server, "repo": repo,
"sha": sha, "has_token": has_tok,
"body": body.decode() if body else None, "http_err":
str(http_err) if http_err else None},
{"state": state, "error": err, "request": req})
# ── ci_runs_for_sha ─────────────────────────────────────────────────────────
runs_payload = {"workflow_runs": [
{"id": 1, "head_sha": "abc"},
{"id": 2, "head_sha": None},
{"id": 3, "head_sha": "other"},
{"id": 4},
{"id": 5, "head_sha": "abc"},
]}
for name, server, repo, sha, payload, err in [
("ci_runs:no-token", None, "o/r", "s", None, None),
("ci_runs:filter-by-head-sha", None, "o/r", "abc", runs_payload,
None),
("ci_runs:none-matching", None, "o/r", "zzz", runs_payload, None),
("ci_runs:absent-key", None, "o/r", "s", {"total_count": 0}, None),
("ci_runs:empty-sha-matches-absent", None, "o/r", "", runs_payload,
None),
("ci_runs:unreachable", None, "o/r", "s", None,
OSError("runs down")),
]:
gf = forge.GiteaForge(server=server)
saved = clean_env({})
forge.GiteaForge._gitea_auth = staticmethod(
lambda: auth_stub(has=payload is not None or "no-token" not in name))
calls = []
try:
with fake_http(lambda cap: err if err else json.dumps(payload).encode()) as captured:
try:
got = gf.ci_runs_for_sha(repo, sha)
e = None
except forge.ForgeUnavailable as exc:
got, e = None, str(exc)
req = captured[0] if captured else None
finally:
restore_env(saved)
del forge.GiteaForge._gitea_auth
record(f"ci_runs:{name}", "ci_runs",
{"server": server, "repo": repo, "sha": sha, "payload": payload,
"err": str(err) if err else None,
"has_token": payload is not None or "no-token" not in name},
{"runs": got, "error": e, "request": req})
# ── create_or_patch_release ────────────────────────────────────────────────
for name, has_tok, script_present, rc, stderr, stdout, tag in [
("release:no-token", False, True, 0, "", "", "v9.9.9"),
("release:published", True, True, 0, "", "", "v1.2.3"),
("release:script-fails-stderr", True, True, 3, "tag exists already",
"", "v0.0.1"),
("release:script-fails-falls-back-stdout", True, True, 4, "",
"o" * 250, "v0.0.2"),
("release:script-missing", True, False, 0, "", "", "v0.0.3"),
]:
gf = forge.GiteaForge()
saved = clean_env({})
forge.GiteaForge._gitea_auth = staticmethod(lambda: auth_stub(has=has_tok))
calls = []
cwd = ROOT if script_present else str(tmp)
old_cwd = os.getcwd()
os.chdir(cwd)
PENDING_RC["args"] = (rc, stdout, stderr)
try:
with fake_subprocess(calls):
try:
got = gf.create_or_patch_release("o/r", tag, "T", "B")
e = None
except forge.ForgeUnavailable as exc:
got, e = None, str(exc)
finally:
os.chdir(old_cwd)
del forge.GiteaForge._gitea_auth
PENDING_RC["args"] = (0, "", "")
restore_env(saved)
argv = calls[0]["argv"][1:] if calls else None
record(f"release:{name}", "release",
{"has_token": has_tok, "script_present": script_present, "rc": rc,
"stderr": stderr, "stdout": stdout, "tag": tag,
"cwd": "<root>" if script_present else "<tmp>"},
{"result": got, "error": e, "argv": argv,
"python_bin": calls[0]["argv"][0] if calls else None})
doc = {
"frozen_ts": "2026-10-12T00:00:00+00:00",
"generator": "scripts/gen_forge_truth.py — live oracle src/rune/forge.py",
"rows": rows,
}
out = ROOT / "src/go/forge/truth.json"
out.write_text(json.dumps(doc, indent=1, ensure_ascii=False) + "\n",
encoding="utf-8")
print(f"frozen {len(rows)} rows → {out}")
+180
View File
@@ -0,0 +1,180 @@
#!/usr/bin/env python3
"""Freeze inference_trace truth (dichotomy wave #2479, contract
BUILDER-2026-10-12T13:55:29Z-148b8f-factory-wave).
Generator exercises EVERY public function of the live Python oracle
(src/rune/inference_trace.py) across all branches with RUNE_IT_CORE=python
pinned and an isolated trace dir, freezing kernel-shaped truth
(price_for, path resolution, serialization, rotation verdicts, read
selection) to src/rust/inference_trace/src/frozen_it_truth.json.
File IO (append/rotate/read) is recorded as ordered events so the Rust
kernel decides WHAT to do and the Python facade performs it.
"""
import contextlib
import io
import json
import os
import sys
import tempfile
from dataclasses import asdict
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
# PARITY=1: leave RUNE_IT_CORE unset (auto) so the live run goes through the
# Rust core — output must byte-match the frozen truth file.
PARITY = bool(os.environ.get("PARITY"))
os.environ["RUNE_IT_CORE"] = "auto" if PARITY else "python" # PIN: live oracle
# Deterministic home so the parity run byte-matches the frozen file.
tmp = str(ROOT / "target" / "it_truth_home")
os.makedirs(tmp, exist_ok=True)
os.environ["RUNE_HOME"] = tmp
sys.path.insert(0, str(ROOT / "src"))
from rune import inference_trace as it # noqa: E402
CASES = {
"frozen": {
"contract": "BUILDER-2026-10-12T13:55:29Z-148b8f-factory-wave",
"oracle": "src/rune/inference_trace.py",
"pin": "RUNE_IT_CORE=python",
},
"price_for": [],
"trace_path": [],
"record": [],
"read": [],
"main": [],
}
# ---------------------------------------------------------------- price_for
# Every branch: empty price map → None for any model.
for model in ["qwen2.5:3b", "qwen3:14b", "mimo-v2.5-pro", "gpt-4", "", "unknown-model"]:
CASES["price_for"].append({"model": model, "out": it.price_for(model)})
# ---------------------------------------------------------------- paths
home = Path(tmp)
dir_cases = [
None, # default: <rune_home>/state
Path(tmp) / "custom_traces", # explicit dir
Path(tmp) / "nested" / "deeper", # explicit nested
]
for d in dir_cases:
CASES["trace_path"].append({
"trace_dir": str(d) if d is not None else None,
"home": tmp,
"out_dir": str(it._trace_dir(d)),
"out_path": str(it._trace_path(d)),
})
# rune_home default (no explicit dir) resolves from RUNE_HOME
assert str(home) in str(it._trace_dir()), "RUNE_HOME isolation broken"
# ---------------------------------------------------------------- record
def mk_trace(**over):
base = dict(
schema_version=5, provider="ollama", model="qwen3:14b",
task_id="T42", channel="chat", resolved_context_window=32768,
input_budget=24000, model_calls=2, prompt_tokens_estimated=5150,
prompt_tokens_served=5102, output_tokens=733, latency_ms=8123.4,
model_time_ms=6210.9,
per_block_tokens={"constitution": 412, "project": 1300},
dropped_blocks=[{"name": "human", "tokens": 88}],
tools_exposed=["read", "edit"], memories_exposed=["constitution"],
memory_tokens=1712, degraded=[], cache=None, cost_usd=None,
cost_basis="local-unpriced", success=True, error="",
)
base.update(over)
return it.InferenceTrace(**base)
# serialized line shape (sort_keys, compact separators)
for name, tr in [
("v1-minimal", mk_trace()),
("v5-full", mk_trace(
routing_reason="tier:hot", routing_mode="local", task_family="coding",
selected_tools=["read"], capability_reason="allowlist",
find_capability_calls=1,
capsule_messages=[{"role": "user", "content": "hi"}],
capsule_content_hashes={"constitution": "a" * 64},
capsule_token_count=5150,
memory_candidates=9, memory_selected=2, memory_abstained=False,
memory_types_queried=["project"],
)),
("degraded-error", mk_trace(success=False, error="model timeout",
degraded=["memory"], model_calls=1,
output_tokens=0)),
("abstained", mk_trace(memory_candidates=4, memory_selected=0,
memory_abstained=True)),
]:
line = json.dumps(asdict(tr), sort_keys=True, separators=(",", ":"))
CASES["record"].append({"tag": name, "trace": asdict(tr), "out_line": line})
# rotation verdicts: given current size, does rotation fire, and what
# shift sequence runs? (kernel decides; facade performs)
for size in [0, 9_999_999, 10_000_000, 10_000_001, 25_000_000]:
CASES["record"].append({
"tag": f"rotate-{size}", "current_size": size,
"rotate_bytes": it.TRACE_ROTATE_BYTES, "backups": it.TRACE_BACKUPS,
"out": size > it.TRACE_ROTATE_BYTES,
})
# ---------------------------------------------------------------- read
# read_traces selection: no file → [], limit trims to last N, blank lines
# skipped. (content round-trips through the record serializer)
READ_DIR = Path(tmp) / "read_traces"
READ_DIR.mkdir(parents=True, exist_ok=True)
lines = [
json.dumps(asdict(mk_trace(task_id=f"R{i}")), sort_keys=True,
separators=(",", ":"))
for i in range(5)
]
raw = "\n".join(lines[:3]) + "\n\n\n" + "\n".join(lines[3:]) + "\n"
(READ_DIR / it.TRACE_FILENAME).write_text(raw, encoding="utf-8")
CASES["read"].append({"tag": "all", "exists": True, "limit": None,
"line_count": len(lines), "raw_line_count": 8,
"out_count": len(it.read_traces(READ_DIR))})
CASES["read"].append({"tag": "limit-2", "exists": True, "limit": 2,
"line_count": len(lines), "raw_line_count": 8,
"out_count": len(it.read_traces(READ_DIR, limit=2))})
CASES["read"].append({"tag": "limit-99", "exists": True, "limit": 99,
"line_count": len(lines), "raw_line_count": 8,
"out_count": len(it.read_traces(READ_DIR, limit=99))})
CASES["read"].append({"tag": "missing-file", "exists": False, "limit": None,
"line_count": 0, "raw_line_count": 0,
"out_count": len(it.read_traces(Path(tmp) / "nowhere"))})
# ---------------------------------------------------------------- main
# CLI tail: main(count) prints each record indented+sorted and returns 0.
probe = Path(tmp) / "main_probe"
probe.mkdir(parents=True, exist_ok=True)
for i in range(3):
it.record_trace(mk_trace(task_id=f"M{i}"), probe)
for count in [None, 2]:
buf = io.StringIO()
old_argv = sys.argv
sys.argv = ["inference_trace.py"] + ([str(count)] if count is not None else [])
old_tp = it._trace_path
it._trace_path = lambda d=None: probe / it.TRACE_FILENAME # aim main at probe
try:
with contextlib.redirect_stdout(buf):
rc = it.main()
finally:
it._trace_path = old_tp
sys.argv = old_argv
out = buf.getvalue()
CASES["main"].append({
"count": count,
"records": [asdict(t) for t in [mk_trace(task_id=f"M{i}") for i in range(3)]],
"out": out, "rc": rc,
# the exact print format for the records the kernel must produce
"out_lines": out.count("}"),
})
out = ROOT / "src" / "rust" / "inference_trace" / "src" / "frozen_it_truth.json"
if PARITY:
out = Path(tempfile.mkdtemp(prefix="it_parity_")) / "parity_it_truth.json"
out.write_text(json.dumps(CASES, indent=1, ensure_ascii=False) + "\n")
counts = {k: len(v) for k, v in CASES.items() if k != "frozen"}
print("frozen:", out)
print("cases:", json.dumps(counts))
+127
View File
@@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""gen_intent_continuity_truth.py — freeze the intent_continuity parity
oracle (dichotomy wave #2479 tranche).
Generator law: RUNE_IC_CORE=python pinned, the clock STUBBED (deterministic
per-op `now`), inputs deep-copied, every public transition/branch exercised
(create, create_detour incl. PARKED-parent no-op, resolve incl. missing and
already-resolved, resolve_detour incl. re-entry and un-parking, supersede
incl. obligations guard + KeyError). Output:
src/rust/intent_continuity/frozen_ic_truth.json — replayed VERBATIM by the
crate's cfg(test) battery.
"""
import copy
import json
import os
import sys
import tempfile
import types
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
os.environ["RUNE_IC_CORE"] = "python"
import rune.intent_continuity as ic # noqa: E402
# deterministic clock: op k gets 2026-10-12T00:00:kZ
_tick = [0]
def _fake_strftime(_fmt, _t):
_tick[0] += 1
return f"2026-10-12T00:00:{_tick[0]:02d}Z"
ic.time = types.SimpleNamespace(strftime=_fake_strftime, gmtime=lambda: 0)
cases: list = []
def ledger_state(led: ic.IntentLedger) -> dict:
return {"intents": [r.to_dict() for r in led.records.values()]}
def record_op(led, fn, op_args, now, expected_record, before, after, err=None):
"""Freeze one op: kernel args from the pre-op state, expected from the
observed oracle outcome."""
args = {"ledger": copy.deepcopy(before), "now": now, **copy.deepcopy(op_args)}
if err is not None:
expected = {"err": err}
else:
expected = {"ledger": copy.deepcopy(after),
"record": copy.deepcopy(expected_record)}
cases.append({"fn": fn, "args": args, "expected": expected})
def op(led, fn, run, **kwargs):
"""run(**kwargs) performs the oracle op (e.g. led.create); kwargs are
recorded verbatim as kernel args."""
before = ledger_state(led)
now = f"2026-10-12T00:00:{_tick[0] + 1:02d}Z" # the now this op will get
try:
rec = run(**kwargs)
after = ledger_state(led)
record_op(led, fn, kwargs, now, rec.to_dict() if rec else None, before, after)
except (ValueError, KeyError) as e:
# kernel err strings match the oracle's exception text: the facade
# re-raises KeyError(e.args[0]) whose str is the quoted form, so the
# kernel carries the BARE id after the prefix
err = (f"KeyError: {e.args[0]}" if isinstance(e, KeyError) else str(e))
record_op(led, fn, kwargs, now, None, before, before, err=err)
return now
def main() -> None:
with tempfile.TemporaryDirectory() as td:
led = ic.IntentLedger(os.path.join(td, "intents.json"))
op(led, "ic_create", led.create,
id="t1", objective="ship the parser fix", classification="FIX")
op(led, "ic_create", led.create,
id="t2", objective="rewrite recall", classification="EXTENSION",
success_condition="A/B parity shown",
unresolved_obligations=["o1", "o2"])
op(led, "ic_create_detour", led.create_detour,
id="d1", objective="hotfix CI", classification="BLOCKER",
parent_intent="t1", return_when="CI green", return_to="t1")
op(led, "ic_create_detour", led.create_detour,
id="d2", objective="second detour", classification="LATER",
parent_intent="t1", # t1 already PARKED
return_when="later", return_to="t1")
op(led, "ic_resolve", led.resolve, intent_id="t2")
op(led, "ic_resolve", led.resolve, intent_id="t2") # already RESOLVED → None
op(led, "ic_resolve", led.resolve, intent_id="d1") # DETOUR → RESOLVED
op(led, "ic_resolve_detour", led.resolve_detour, detour_id="d1") # un-parks t1
op(led, "ic_resolve_detour", led.resolve_detour, detour_id="d1") # re-entry → parent
op(led, "ic_resolve", led.resolve, intent_id="missing")
op(led, "ic_resolve_detour", led.resolve_detour, detour_id="missing")
op(led, "ic_supersede", led.supersede,
old_id="t2", new_id="t2b", objective="rewrite recall v2",
classification="SUPERSEDING", carry_obligations=True)
op(led, "ic_supersede", led.supersede,
old_id="t2", new_id="t2c", objective="drop obligations",
classification="SUPERSEDING", carry_obligations=False)
op(led, "ic_supersede", led.supersede,
old_id="missing", new_id="x", objective="o", classification="FIX")
op(led, "ic_create", led.create,
id="bad", objective="o", classification="BOGUS")
op(led, "ic_create_detour", led.create_detour,
id="d3", objective="o", classification="FIX",
parent_intent="nope", return_when="w", return_to="r")
doc = {
"module": "intent_continuity",
"pin": "RUNE_IC_CORE=python",
"frozen_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"cases": cases,
}
out = ROOT / "src" / "rust" / "intent_continuity" / "frozen_ic_truth.json"
out.write_text(json.dumps(doc, indent=1) + "\n")
print(f"frozen {len(cases)} cases -> {out}")
if __name__ == "__main__":
main()
+263
View File
@@ -0,0 +1,263 @@
#!/usr/bin/env python3
"""Freeze the dichotomy-wave truth corpus for src/rune/iteration.py.
LAW (poisoned-truth): RUNE_IT_CORE=python is pinned at the top — truth is
generated by the PYTHON ORACLE ONLY, never by the kernel under test.
RUNE_LEDGER_CORE=python pins the capability ledger to its Python floor.
The evidence_provenance cdylib stays LIVE: it is part of the oracle stack
(behaviour_ledger has no Python floor) and is already parity-verified.
Every public function is exercised across ALL branches. Timestamps:
iteration._now / behaviour_ledger._now are monkeypatched to a FIXED value
so the frozen corpus is byte-stable; the Rust kernel receives `now` as an
argument (the same determinism seam the facade uses live).
"""
import copy
import json
import os
import shutil
import sys
import tempfile
from pathlib import Path
os.environ["RUNE_IT_CORE"] = "python" # poisoned-truth law
os.environ["RUNE_LEDGER_CORE"] = "python" # capability_ledger floor
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
sys.path.insert(0, str(REPO / "src" / "rust" / "evidence_provenance"))
import rune.iteration as it # noqa: E402
import rune.behaviour_ledger as bl_mod # noqa: E402
from rune.structural_model import StructuralModel # noqa: E402
from rune.capability_ledger import CapabilityLedger # noqa: E402
from rune.behaviour_ledger import BehaviourLedger # noqa: E402
FIXED_NOW = "2026-10-12T00:00:00Z"
it._now = lambda: FIXED_NOW
bl_mod._now = lambda: FIXED_NOW
OUT = REPO / "src" / "rust" / "iteration" / "src" / "frozen_it_truth.json"
cases = []
def case(fn, name, args, expect):
cases.append({"fn": fn, "name": name,
"args": args, "expect": expect})
def build_fixture(tmp):
model = StructuralModel(Path(tmp) / "model", "demo")
model.add("subsystem", "core")
model.add("component", "alpha", parent="subsystem:core",
ext={"source": "src/alpha.py"})
model.add("component", "beta", parent="subsystem:core")
for e in model.doc["entities"]:
if e["id"] == "component:beta":
e["identities"]["source"] = "src/beta.py"
model.add("interface", "api")
model.add("interface", "legacy")
model.add("state_store", "db")
model.add("test_suite", "t1")
model.add("deployment_surface", "prod")
model.add("component", "gamma", parent="subsystem:core")
model.add("component", "delta", parent="subsystem:core")
model.relate("component:alpha", "provides", "interface:api")
model.relate("component:gamma", "consumes", "interface:api")
model.relate("component:delta", "depends_on", "component:alpha",
status="stale")
model.relate("component:alpha", "consumes", "interface:legacy")
model.relate("component:alpha", "owns", "state_store:db")
model.relate("component:alpha", "verified_by", "test_suite:t1")
model.relate("component:alpha", "deployed_by", "deployment_surface:prod")
model.relate("component:gamma", "provides", "interface:legacy")
model.relate("component:gamma", "owns", "state_store:db")
model.save()
ledger = CapabilityLedger(Path(tmp) / "ledger")
ledger.define(
capability_id="alpha-cap", name="alpha", purpose="alpha purpose",
owning_project="demo", component="component:alpha",
source_locations=["src/alpha.py", "src/alpha_util.py"],
contract="alpha contract", state_touched="state_store:db",
dependencies=["interface:legacy"], consumers=["component:gamma"],
invariants=["inv-1"], behaviour_specs=["b-alpha"],
constraints="no network", generation="g1")
ledger.define(
capability_id="beta-cap", name="beta", purpose="beta purpose",
owning_project="demo", component="component:beta",
source_locations=["src/beta.py"])
ledger.doc["capabilities"]["capability:beta-cap"]["maturity"] = "retired"
ledger.define(
capability_id="gamma-cap", name="gamma", purpose="gamma purpose",
owning_project="demo", component="component:gamma",
source_locations=["src/gamma.py", "src/gamma_more.py"])
behaviours = BehaviourLedger(Path(tmp) / "behaviours")
behaviours.define(
behaviour_id="b-alpha", owning_project="demo",
intended_behaviour="alpha behaves", owner_component="component:alpha",
dependencies=["component:beta"])
behaviours.define(
behaviour_id="b-gamma", owning_project="demo",
intended_behaviour="gamma behaves", owner_component="component:gamma")
behaviours.record_real_world("b-alpha", passed=True, detail="ok")
return model, ledger, behaviours
def main():
tmp = tempfile.mkdtemp(prefix="it_truth_")
try:
model, ledger, behaviours = build_fixture(tmp)
model_doc = model.doc
ledger_doc = ledger.doc
bh_doc = behaviours.doc
# ── context_packet ────────────────────────────────────────────
r = it.context_packet(model, ledger, "component:alpha")
case("context_packet", "alpha_full",
{"model": model_doc, "ledger": ledger_doc,
"target": "component:alpha", "now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "nope:missing")
case("context_packet", "unknown_target",
{"model": model_doc, "ledger": ledger_doc,
"target": "nope:missing", "now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "component:gamma",
intent="ship gamma", basis_summary={"depth": 2})
case("context_packet", "gamma_intent_basis",
{"model": model_doc, "ledger": ledger_doc,
"target": "component:gamma", "intent": "ship gamma",
"basis_summary": {"depth": 2}, "now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "component:alpha",
max_local_files=1)
case("context_packet", "alpha_truncated",
{"model": model_doc, "ledger": ledger_doc,
"target": "component:alpha", "max_local_files": 1,
"now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "component:beta")
case("context_packet", "beta_identities_source",
{"model": model_doc, "ledger": ledger_doc,
"target": "component:beta", "now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "interface:api")
case("context_packet", "interface_target",
{"model": model_doc, "ledger": ledger_doc,
"target": "interface:api", "now": FIXED_NOW}, r)
r = it.context_packet(model, ledger, "project:demo")
case("context_packet", "root_project",
{"model": model_doc, "ledger": ledger_doc,
"target": "project:demo", "now": FIXED_NOW}, r)
empty = CapabilityLedger.__new__(CapabilityLedger)
empty.doc = {"schema_version": 1, "capabilities": {}}
r = it.context_packet(model, empty, "component:alpha")
case("context_packet", "empty_ledger",
{"model": model_doc, "ledger": empty.doc,
"target": "component:alpha", "now": FIXED_NOW}, r)
# ── predictive_impact ─────────────────────────────────────────
for name, target in [("alpha", "component:alpha"),
("unknown", "nope:missing"),
("leaf", "component:beta")]:
r = it.predictive_impact(model, target)
case("predictive_impact", name,
{"model": model_doc, "target": target}, r)
# ── descriptive_impact ────────────────────────────────────────
for name, kwargs in [
("full_overlap", {"observed_changed": ["component:alpha",
"component:gamma"]}),
("unexpected", {"observed_changed": ["component:alpha",
"surprise:one"]}),
("none_observed", {"observed_changed": []}),
]:
r = it.descriptive_impact(model, "component:alpha", **kwargs)
case("descriptive_impact", name,
{"model": model_doc, "target": "component:alpha",
"observed_changed": kwargs["observed_changed"],
"now": FIXED_NOW}, r)
r = it.descriptive_impact(model, "component:alpha",
observed_changed=["component:gamma"],
generation="g7")
case("descriptive_impact", "generation_tag",
{"model": model_doc, "target": "component:alpha",
"observed_changed": ["component:gamma"],
"generation": "g7", "now": FIXED_NOW}, r)
r = it.descriptive_impact(model, "nope:missing",
observed_changed=["x"])
case("descriptive_impact", "unknown_target",
{"model": model_doc, "target": "nope:missing",
"observed_changed": ["x"], "now": FIXED_NOW}, r)
# ── record_impact_delta (exact jsonl line — file IO facade) ───
deltas = [
{"target": "component:alpha", "generation": "g1",
"predicted": ["component:alpha"], "observed": [],
"unexpected": [], "unaffected_as_predicted":
["component:alpha"], "recorded_at": FIXED_NOW},
{"b": 1, "a": [1.5, 2], "c": None, "s": "é\nx"},
{"nested": {"z": True, "y": 0.1}},
]
for i, delta in enumerate(deltas):
d = Path(tmp) / f"deltas{i}"
d.mkdir()
it.record_impact_delta(d, delta)
line = (d / "impact_deltas.jsonl").read_text()
assert line.endswith("\n") and line.count("\n") == 1
case("record_impact_delta", f"line{i}", {"delta": delta},
line[:-1])
# ── invalidate_behaviours ─────────────────────────────────────
for name, changed in [
("hit_deps_and_owner", {"component:alpha", "component:beta"}),
("owner_only", {"component:gamma"}),
("no_intersection", {"component:delta"}),
]:
b = BehaviourLedger.__new__(BehaviourLedger)
b.doc = copy.deepcopy(bh_doc)
recs = it.invalidate_behaviours(
model, b, changed_entities=changed, generation="g9")
case("invalidate_behaviours", name,
{"behaviours": bh_doc, "changed": sorted(changed),
"generation": "g9", "now": FIXED_NOW},
{"doc": b.doc, "recs": recs})
# ── post_change_obligations ───────────────────────────────────
for name, target, changed in [
("alpha_default", "component:alpha", None),
("alpha_two_changed", "component:alpha",
["component:alpha", "component:gamma"]),
("beta_leaf", "component:beta", None),
("gamma_consumes_iface", "component:gamma", None),
("delta_stale_dep", "component:delta", None),
("unknown_in_changed", "component:beta",
["component:beta", "ghost:x"]),
]:
if changed is None:
r = it.post_change_obligations(model, target)
args = {"model": model_doc, "target": target}
else:
r = it.post_change_obligations(
model, target, changed_entities=set(changed))
args = {"model": model_doc, "target": target,
"changed": changed}
case("post_change_obligations", name, args, r)
r = it.post_change_obligations(model, "component:alpha",
behaviours=behaviours)
case("post_change_obligations", "alpha_with_behaviours",
{"model": model_doc, "target": "component:alpha",
"behaviours": bh_doc}, r)
OUT.parent.mkdir(parents=True, exist_ok=True)
groups = {}
for c in cases:
groups.setdefault(f"{c['fn']}_cases", []).append(c)
OUT.write_text(json.dumps(
{"module": "iteration", "now": FIXED_NOW, **groups},
indent=1, sort_keys=True) + "\n")
print(f"frozen {len(cases)} cases -> {OUT}")
finally:
shutil.rmtree(tmp, ignore_errors=True)
if __name__ == "__main__":
main()
+205
View File
@@ -0,0 +1,205 @@
#!/usr/bin/env python3
"""gen_recall_uplift_truth.py — freeze the recall_uplift parity oracle
(dichotomy wave #2479 tranche).
Generator law: RUNE_RU_CORE=python pinned, inputs deep-copied, every
expand() branch exercised: empty query, expansion-map matching (k in q /
q in k / k in t), store pass (LIKE match, LIMIT 32, distinct-doc
co-occurrence, df<5% distinctive filter, 24-term cap), and the best-effort
degrade (no store / sqlite error → map terms only).
PORTABLE LAW: CPython set iteration is hash-random, and the oracle's
candidate sort is stable over dict insertion order — so the frozen corpus
gives every co-occurring candidate word a DISTINCT doc count (ties would
make even Python-vs-Python output order nondeterministic).
Output: src/rust/recall_uplift/frozen_ru_truth.json — replayed VERBATIM by
the crate's cfg(test) battery.
"""
import copy
import json
import os
import sqlite3
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
os.environ["RUNE_RU_CORE"] = "python"
from rune import recall_uplift # noqa: E402
cases: list = []
def freeze(query: str, corpus, expected):
cases.append({
"fn": "expand",
"args": {"query": query, "corpus": copy.deepcopy(corpus)},
"expected": copy.deepcopy(expected),
})
def build_db(rows):
"""rows: list[str|None] — active entry texts in insertion order."""
fd, path = tempfile.mkstemp(suffix=".db")
os.close(fd)
os.unlink(path)
db = sqlite3.connect(path)
db.execute("CREATE TABLE entries (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"text TEXT, status TEXT)")
for text in rows:
db.execute("INSERT INTO entries (text, status) VALUES (?, 'active')",
(text,))
db.commit()
db.close()
return path
def fetch_corpus(path):
db = sqlite3.connect(path)
try:
return [r[0] for r in db.execute(
"SELECT text FROM entries WHERE status='active'").fetchall()]
finally:
db.close()
def case_store(path, query):
"""Freeze one store-backed case: RUNE_STORE_DB pointed at the fixture,
corpus embedded verbatim in args."""
old = os.environ.get("RUNE_STORE_DB")
os.environ["RUNE_STORE_DB"] = path
try:
corpus = fetch_corpus(path)
expected = recall_uplift.expand(query)
finally:
if old is None:
os.environ.pop("RUNE_STORE_DB", None)
else:
os.environ["RUNE_STORE_DB"] = old
freeze(query, corpus, expected)
def case_degraded(query):
"""Freeze the no-store degrade (RUNE_STORE_DB points nowhere)."""
old = os.environ.get("RUNE_STORE_DB")
os.environ["RUNE_STORE_DB"] = "/nonexistent/rune-truth/memory.db"
try:
expected = recall_uplift.expand(query)
finally:
if old is None:
os.environ.pop("RUNE_STORE_DB", None)
else:
os.environ["RUNE_STORE_DB"] = old
freeze(query, None, expected)
def main() -> None:
# ── map-only branches (no store) ─────────────────────────────────────
case_degraded("") # empty query → []
case_degraded(" ") # whitespace query → []
case_degraded("housing crisis") # k in q branch
case_degraded("hous") # q in k branch
case_degraded("routers and models") # k in t branch (router⊂routers)
case_degraded("zebra crossing") # no match at all → [zebra, crossing]
case_degraded("CI pipeline") # mixed-case key match, short tokens
# map-only over an existing-but-empty store (corpus=[] branch)
empty_db = build_db([])
case_store(empty_db, "housing crisis")
os.unlink(empty_db)
# ── store pass, engineered corpus A (200 rows, distinct co-occur counts)
# matched rows 0..11 (testing 0..3 / memory 4..8 / recall 8..11 — recall
# is a seen map term, so it co-occurs but is skipped). NO filler text in
# matched rows (filler would become a tie-counted co-occur candidate).
rows = ["filler word"] * 200
CO = [("allocator", 9), ("snapshot", 8), ("checkpoint", 7), ("ledger", 6),
("walrus", 3), ("quixotic", 2), ("zephyr", 1)]
for w, n in CO:
for r in range(n):
rows[r] = (rows[r] + f" {w}").strip()
for r in range(4):
rows[r] += " testing" # co-occur count 4
for r in range(4, 9):
rows[r] += " memory" # co-occur count 5
for r in range(8, 12):
rows[r] += " recall" # in seen → skipped
for r in range(4):
rows[r] += " pipeline" # w == t quirk: last token skipped
for r in range(5):
rows[r] += " other" # stopword → skipped
for r in range(6):
rows[r] += " retrieval" # already in seen → skipped
for r in range(20): # df 20/200 = 0.1 → filtered branch
rows[r] += " orbital" # co-occur 12 (distinct, top candidate)
rows[150] = None # NULL text: counts in total, never matches
db_a = build_db(rows)
case_store(db_a, "testing memory recall pipeline")
os.unlink(db_a)
# ── 24-term cap boundary (400 rows, co-occur counts 19..1, distinct) ──
rows = ["filler word"] * 400
for i in range(19): # word in (19-i) matched rows; letters
w = "kv" + chr(97 + i) * 2 # only — the tokenizer is [a-z']{4,}
for r in range(19 - i):
rows[r] = (rows[r] + f" {w}").strip()
for r in range(20):
rows[r] = f"housing policy{rows[r]}" # no filler in matched rows;
# policy co-occurs in all 20 matched rows → df 20/400 = 0.05 → filtered
db_b = build_db(rows)
case_store(db_b, "housing policy anchor")
os.unlink(db_b)
# ── LIMIT-32 branch (100 rows: matches beyond the first 32 don't co-occur)
rows = ["filler word"] * 100
for r in range(40):
rows[r] = "alpha"
for r in range(8):
rows[r] += " beta"
for r in range(3):
rows[r] += " delta"
for r in range(4):
rows[r] += " gamma" # last token → w == t skip
for r in range(33, 40):
rows[r] += " omega" # beyond the LIMIT-32 cut → not in co-occur
db_c = build_db(rows)
case_store(db_c, "alpha beta gamma")
os.unlink(db_c)
# ── sqlite-error degrade: db present, entries table missing ──────────
fd, bad = tempfile.mkstemp(suffix=".db")
os.close(fd)
os.unlink(bad)
db = sqlite3.connect(bad)
db.execute("CREATE TABLE other (x TEXT)")
db.commit()
db.close()
old = os.environ.get("RUNE_STORE_DB")
os.environ["RUNE_STORE_DB"] = bad
try:
expected = recall_uplift.expand("housing crisis")
finally:
if old is None:
os.environ.pop("RUNE_STORE_DB", None)
else:
os.environ["RUNE_STORE_DB"] = old
freeze("housing crisis", None, expected)
os.unlink(bad)
doc = {
"module": "recall_uplift",
"pin": "RUNE_RU_CORE=python",
"frozen_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
"cases": cases,
}
out = ROOT / "src" / "rust" / "recall_uplift" / "frozen_ru_truth.json"
out.write_text(json.dumps(doc, indent=1) + "\n")
print(f"frozen {len(cases)} cases -> {out}")
if __name__ == "__main__":
main()
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""Freeze the dichotomy-wave truth corpus for src/rune/rune_profiler.py.
LAW (poisoned-truth): RUNE_RP_CORE=python is pinned at the top — truth is
generated by the PYTHON ORACLE ONLY.
The measurement loop (perf_counter_ns over a Python callable / Ollama
HTTP call) is host-side by nature and stays in the facade; the PORTABLE
LAW is the stats computation over the measured elapsed times. Truth is
generated by monkeypatching the oracle's perf_counter_ns to a controlled
queue of elapsed deltas — every per-iteration elapsed is a multiple of
15625 ns (1/64 ms), a dyadic rational, so every sum/mean/median is f64-
exact and the oracle's statistics.mean (exact Fraction) matches the
kernel's float math BIT-FOR-BIT.
profile_function 6 cases (1/2/20/100/101 iterations, unsorted times,
single iteration, two-element median)
profile_model_call 3 cases (same stats law minus p95/p99)
"""
import itertools
import json
import os
import sys
from pathlib import Path
os.environ["RUNE_RP_CORE"] = "python" # poisoned-truth law
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.rune_profiler as rp # noqa: E402
OUT = REPO / "src" / "rust" / "rune_profiler" / "src" / "frozen_rp_truth.json"
cases = []
UNIT_NS = 15625 # 1/64 ms — dyadic, f64-exact through sums and /1e6
def freeze_stats(fn_name, elapsed_units, iterations):
"""Drive the REAL oracle with a controlled perf_counter_ns."""
vals, c = [], 0
for u in elapsed_units:
vals.append(c)
vals.append(c + u * UNIT_NS)
c += u * UNIT_NS
vals.append(c) # pad: 2 calls per iteration consumed
clock = iter(itertools.cycle(vals) if False else vals)
rp.time.perf_counter_ns = lambda: next(clock)
calls = {"n": 0}
def fake_func():
calls["n"] += 1
if fn_name == "profile_function":
r = rp.profile_function(fake_func, iterations=iterations)
else:
# profile_model_call calls the module-level _execute_ollama —
# stub it; the elapsed deltas drive the stats identically
def fake_ollama(*a, **k):
calls["n"] += 1
return "ok"
rp._execute_ollama = fake_ollama
r = rp.profile_model_call(iterations=iterations)
times_ms = [u * UNIT_NS / 1_000_000 for u in elapsed_units]
cases.append({"fn": fn_name,
"name": f"{'f' if fn_name == 'profile_function' else 'm'}"
f"{iterations}_{len(elapsed_units)}_{elapsed_units[0]}"
f"{'_shuffled' if len(set(elapsed_units)) > 1 and elapsed_units != sorted(elapsed_units) else ''}",
"args": {"times": times_ms, "iterations": iterations},
"expect": r})
assert calls["n"] == iterations, (calls["n"], iterations)
def main():
# ── profile_function ─────────────────────────────────────────────
freeze_stats("profile_function", [10], 1)
freeze_stats("profile_function", [3, 7], 2) # median = mean of 2
freeze_stats("profile_function", [5, 1, 9, 2, 8, 4, 6, 3, 7, 1,
2, 9, 4, 8, 1, 6, 2, 7, 3, 5], 20)
freeze_stats("profile_function", [1] * 100, 100) # p95/p99 = same value
freeze_stats("profile_function",
[(i % 13) + 1 for i in range(101)], 101) # odd count median
freeze_stats("profile_function",
[((i * 37) % 29) + 1 for i in range(100)], 100)
# ── profile_model_call ───────────────────────────────────────────
freeze_stats("profile_model_call", [6400, 3200, 12800, 1600, 6400], 5)
freeze_stats("profile_model_call", [1, 2], 2)
freeze_stats("profile_model_call", [811], 1)
OUT.parent.mkdir(parents=True, exist_ok=True)
groups = {}
for c in cases:
groups.setdefault(f"{c['fn']}_cases", []).append(c)
OUT.write_text(json.dumps(
{"module": "rune_profiler", "unit_ns": UNIT_NS, **groups},
indent=1, sort_keys=True) + "\n")
print(f"frozen {len(cases)} cases -> {OUT}")
if __name__ == "__main__":
main()
+157
View File
@@ -0,0 +1,157 @@
#!/usr/bin/env python3
"""Freeze the dichotomy-wave truth corpus for src/rune/subconscious_pass.py.
LAW (poisoned-truth): RUNE_SP_CORE=python is pinned at the top — truth is
generated by the PYTHON ORACLE ONLY.
Every public function is exercised across ALL branches:
reflect 10 cases (topic_shift hit/same-topic/no-context/
empty-context; unresolved_question both; action
words; emotional words; short_response; combo)
_extract_topic 4 (multiword / single / empty / whitespace)
get_recent_findings 4 (default limit / limit>len / limit=0 / sparse)
save_reflection 2 (the exact json.dump(indent=2) file bytes — the
timestamped FILENAME and the write stay in the
facade; the byte law is the kernel's)
Timestamps: the report `timestamp` and the save filename clock are facade
ARGUMENTS (`now`), monkeypatched to a FIXED value so the corpus is
byte-stable.
"""
import json
import os
import sys
from pathlib import Path
os.environ["RUNE_SP_CORE"] = "python" # poisoned-truth law
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.subconscious_pass as sp # noqa: E402
FIXED_NOW = "2026-10-12T00:00:01.000001+00:00"
OUT = (REPO / "src" / "rust" / "subconscious_pass" / "src"
/ "frozen_sp_truth.json")
cases = []
def case(fn, name, args, expect):
cases.append({"fn": fn, "name": name,
"args": args, "expect": expect})
class _FixedDatetime(sp.datetime):
@classmethod
def now(cls, tz=None):
return cls(2026, 10, 12, 0, 0, 1, 1, tzinfo=tz)
def main():
sp.datetime = _FixedDatetime
s = sp.SubconsciousPass()
# ── reflect ──────────────────────────────────────────────────────
for name, user, agent, ctx in [
("topic_shift_hit", "how do we deploy the cache layer",
"Sure, let's plan it.", {"previous_topic": "index tuning"}),
("topic_same", "more on index tuning please",
"The index tuning continues.", {"previous_topic": "index tuning"}),
("topic_none_extracted", " ",
"Empty message.", {"previous_topic": "old topic"}),
("no_context", "build the thing", "Building it.", None),
("empty_context", "build the thing", "Building it.", {}),
("unresolved_question", "What about the cache?",
"The cache is handled.", {"previous_topic": "cache"}),
("question_answered", "What about the cache?",
"Good question — the cache is handled.", {}),
("action_requested", "please fix and update the loader",
"On it.", {}),
("emotional_signal", "I'm frustrated and confused by the drift",
"Let's look at it.", {}),
("short_response", "x" * 201,
"ok"[:10], {}),
("combo_all", "build and fix it — I'm frustrated. What now?",
"ok", {"previous_topic": "planning"}),
]:
r = s.reflect(user, agent, ctx)
case("reflect", name,
{"user": user, "agent": agent, "context": ctx,
"now": FIXED_NOW}, r)
# ── _extract_topic ───────────────────────────────────────────────
for name, text, want in [
("multiword", "the quick brown fox jumps over the dog",
"the quick brown fox jumps"),
("single", "hello", "hello"),
("empty", "", None),
("whitespace", " \t\n ", None),
]:
got = s._extract_topic(text)
case("extract_topic", name, {"text": text}, got)
# ── get_recent_findings ──────────────────────────────────────────
s2 = sp.SubconsciousPass()
r1 = s2.reflect("build it", "ok" * 30, {})
r2 = s2.reflect("What?", "Nothing.", {})
r3 = s2.reflect("no findings here", "x" * 60, {})
r4 = s2.reflect("frustrated", "y" * 60, {})
case("recent_findings", "default_limit",
{"reports": [r1, r2, r3, r4]}, s2.get_recent_findings())
case("recent_findings", "limit_2",
{"reports": [r1, r2, r3, r4], "limit": 2}, s2.get_recent_findings(2))
case("recent_findings", "limit_0",
{"reports": [r1, r2, r3, r4], "limit": 0}, s2.get_recent_findings(0))
sparse = [{"findings": [{"type": "a", "detail": "d", "severity": "low"}]},
{"no_findings_key": True},
{"findings": []}]
s5 = sp.SubconsciousPass()
s5.findings = list(sparse)
case("recent_findings", "sparse_reports",
{"reports": sparse}, s5.get_recent_findings(10))
case("recent_findings", "empty",
{"reports": []}, _recent([], 10))
# ── save_reflection (exact file bytes; naming/write is facade) ───
for i, report in enumerate([r1, {"a": 1, "list": [1, 2.5], "s": "é"}]):
s3 = sp.SubconsciousPass()
# call the real oracle save path with a redirected dir
orig_dir = sp.REFLECTIONS_DIR
tmp = Path(__import__("tempfile").mkdtemp(prefix="sp_truth_"))
sp.REFLECTIONS_DIR = str(tmp)
try:
s3.save_reflection(report)
files = sorted(tmp.iterdir())
assert len(files) == 1
content = files[0].read_text()
finally:
sp.REFLECTIONS_DIR = orig_dir
import shutil
shutil.rmtree(tmp, ignore_errors=True)
# the frozen corpus round-trips the report sort_keys=True, so the
# replayable byte law is json.dump over THAT dict order
sorted_report = json.loads(json.dumps(report, sort_keys=True))
case("save_reflection", f"report{i}", {"report": sorted_report},
json.dumps(sorted_report, indent=2))
OUT.parent.mkdir(parents=True, exist_ok=True)
groups = {}
for c in cases:
groups.setdefault(f"{c['fn']}_cases", []).append(c)
OUT.write_text(json.dumps(
{"module": "subconscious_pass", "now": FIXED_NOW, **groups},
indent=1, sort_keys=True) + "\n")
print(f"frozen {len(cases)} cases -> {OUT}")
def _recent(reports, limit):
all_findings = []
for r in reports[-limit:]:
all_findings.extend(r.get("findings", []))
return all_findings
if __name__ == "__main__":
main()
+127
View File
@@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""Freeze the dichotomy-wave truth corpus for src/rune/subsystem_health.py.
LAW (poisoned-truth): RUNE_SH_CORE=python is pinned at the top — truth is
generated by the PYTHON ORACLE ONLY.
Portable law = the registry state transition + snapshot deep-copy + the
record_failure pure core (message composition, tier event mapping, payload
[:300] truncation). The side-effect shell (logging, event_bus.emit,
filer callbacks, process-global wiring, RotatingFileHandler) stays in the
facade — it cannot cross FFI.
registry.record 8 cases (tier0/1 first+repeat, tier2, multi-subsystem,
last_error/tier overwrite)
registry.snapshot 2 (deep copy incl. nested mutation isolation)
record_failure core 6 (message with/without context, tier events 0/1/2/
unknown, payload truncation at 300 incl. multibyte)
"""
import copy
import json
import os
import sys
from pathlib import Path
os.environ["RUNE_SH_CORE"] = "python" # poisoned-truth law
REPO = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(REPO / "src"))
import rune.subsystem_health as sh # noqa: E402
OUT = (REPO / "src" / "rust" / "subsystem_health" / "src"
/ "frozen_sh_truth.json")
cases = []
def case(fn, name, args, expect):
cases.append({"fn": fn, "name": name,
"args": args, "expect": expect})
def reg_state(reg):
return {"entries": copy.deepcopy(reg._entries),
"surfaced": sorted(reg._surfaced)}
def run_record(reg, subsystem, error, tier):
surface = reg.record(subsystem, error, tier)
return {"state": reg_state(reg), "surface": surface}
def main():
# ── registry.record ──────────────────────────────────────────────
for name, seq in [
("tier1_first", [("cache", "boom", 1)]),
("tier1_repeat", [("cache", "boom", 1), ("cache", "bam", 1)]),
("tier0_first", [("auth", "explode", 0)]),
("tier2_never_surfaces", ["store", "degraded", 2] and
[("store", "degraded", 2), ("store", "worse", 2)]),
("multi_subsystem", [("a", "x", 1), ("b", "y", 1), ("a", "z", 0)]),
("tier_overwrite", [("svc", "e1", 2), ("svc", "e2", 0)]),
("tier1_after_tier2_still_surfaces_once",
[("svc2", "e1", 2), ("svc2", "e2", 1), ("svc2", "e3", 1)]),
("negative_tier_surfaces", [("neg", "e", -1), ("neg", "e2", -1)]),
]:
reg = sh.SubsystemHealthRegistry()
out = None
for subsystem, error, tier in seq:
out = run_record(reg, subsystem, error, tier)
args_last = seq[-1]
# freeze: input = PRE-state + one record call; expect = post-state
pre = sh.SubsystemHealthRegistry()
for subsystem, error, tier in seq[:-1]:
run_record(pre, subsystem, error, tier)
case("registry_record", name,
{"entries": pre._entries, "surfaced": sorted(pre._surfaced),
"subsystem": args_last[0], "error": args_last[1],
"tier": args_last[2]},
out)
# ── registry.snapshot ────────────────────────────────────────────
reg = sh.SubsystemHealthRegistry()
reg.record("cache", "boom", 1)
reg.record("store", "degraded", 2)
snap = reg.snapshot()
case("registry_snapshot", "deep_copy", {"entries": reg._entries}, snap)
snap2 = reg.snapshot()
snap2["cache"]["failures"] = 999
case("registry_snapshot", "isolation",
{"entries": reg._entries}, reg.snapshot())
# ── record_failure pure core ─────────────────────────────────────
class _Err(Exception):
pass
for name, err, ctx, tier in [
("message_plain", _Err("disk on fire"), "", 1),
("message_with_context", _Err("disk on fire"), "during flush", 1),
("tier0_event", _Err("x"), "", 0),
("tier2_event", _Err("x"), "", 2),
("tier_unknown_event", _Err("x"), "", 99),
("payload_truncation", _Err("é" * 400), "", 1),
]:
message = f"{type(err).__name__}: {err}"
if ctx:
message = f"{message} ({ctx})"
event_type = sh._TIER_EVENTS.get(tier, "storage.degraded")
payload_error = message[:300]
case("failure_core", name,
{"error_type": type(err).__name__, "error": str(err),
"context": ctx, "tier": tier},
{"message": message, "event_type": event_type,
"payload_error": payload_error})
OUT.parent.mkdir(parents=True, exist_ok=True)
groups = {}
for c in cases:
groups.setdefault(f"{c['fn']}_cases", []).append(c)
OUT.write_text(json.dumps(
{"module": "subsystem_health", **groups}, indent=1, sort_keys=True)
+ "\n")
print(f"frozen {len(cases)} cases -> {OUT}")
if __name__ == "__main__":
main()
+173
View File
@@ -0,0 +1,173 @@
#!/usr/bin/env python3
"""Freeze the oracle truth for the GO port of src/rune/verification_layer.py
(dichotomy wave #2479, GO). Every public function, every branch, against the
LIVE oracle (which delegates to the Rust evidence_provenance core — parity
already proven 33/33). Rows pin the full VerificationResult field set AND the
byte-exact json.dumps(to_dict()) rendering. handle_hook + PLUGIN pinned too.
"""
from __future__ import annotations
import json
import os
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
from rune import verification_layer as vl # noqa: E402
FIXTURE = ROOT / "src/go/verification_layer/.fixtures/exists.txt"
rows: list[dict] = []
def row(name, fn, verifier_type, result):
got = getattr(vl, fn)(dict(result), verifier_type) if fn == "verify" \
else getattr(vl, fn)(dict(result))
rows.append({
"name": name,
"fn": fn,
"verifier_type": verifier_type,
"result": result,
"want": got.to_dict(),
"want_json": json.dumps(got.to_dict()),
})
def hook_row(name, event, data=None):
got = vl.handle_hook(event) if data is None else vl.handle_hook(event, data)
rows.append({
"name": name,
"fn": "handle_hook",
"verifier_type": "",
"result": {"event": event, "data": data},
"want": got,
"want_json": json.dumps(got, sort_keys=True),
})
# ── verify_exit_code: every branch ──────────────────────────────────────────
row("exit_code:absent-defaults-0", "verify_exit_code", "exit_code", {})
row("exit_code:zero-pass", "verify_exit_code", "exit_code", {"exit_code": 0})
row("exit_code:one-fail", "verify_exit_code", "exit_code", {"exit_code": 1})
row("exit_code:negative-fail", "verify_exit_code", "exit_code", {"exit_code": -3})
row("exit_code:float-zero-pass", "verify_exit_code", "exit_code", {"exit_code": 0.0})
row("exit_code:float-frac-fail", "verify_exit_code", "exit_code", {"exit_code": 0.5})
row("exit_code:bool-true-fails", "verify_exit_code", "exit_code", {"exit_code": True})
row("exit_code:bool-false-passes", "verify_exit_code", "exit_code", {"exit_code": False})
row("exit_code:str-zero-not-equal", "verify_exit_code", "exit_code", {"exit_code": "0"})
row("exit_code:null-not-equal", "verify_exit_code", "exit_code", {"exit_code": None})
row("exit_code:big-int-evidence", "verify_exit_code", "exit_code", {"exit_code": 91247})
# ── verify_unit_test ────────────────────────────────────────────────────────
row("unit_test:all-defaults-total-zero-fails", "verify_unit_test", "unit_test", {})
row("unit_test:pass", "verify_unit_test", "unit_test",
{"tests_passed": 10, "tests_failed": 0, "tests_total": 10})
row("unit_test:two-fail", "verify_unit_test", "unit_test",
{"tests_passed": 3, "tests_failed": 2, "tests_total": 5})
row("unit_test:failed-zero-total-positive", "verify_unit_test", "unit_test",
{"tests_failed": 0, "tests_total": 7})
row("unit_test:bool-failed-false-total-true", "verify_unit_test", "unit_test",
{"tests_failed": False, "tests_total": True})
row("unit_test:failed-true-counts-1", "verify_unit_test", "unit_test",
{"tests_failed": True, "tests_total": 1})
row("unit_test:str-total-ignored", "verify_unit_test", "unit_test",
{"tests_total": "5", "tests_failed": 0})
# ── verify_schema ───────────────────────────────────────────────────────────
row("schema:defaults-pass", "verify_schema", "schema", {})
row("schema:valid-true-no-errors", "verify_schema", "schema", {"schema_valid": True})
row("schema:invalid-fail", "verify_schema", "schema", {"schema_valid": False})
row("schema:errors-fail", "verify_schema", "schema",
{"schema_valid": True, "schema_errors": ["bad type at $.a", "missing $.b"]})
row("schema:empty-errors-pass", "verify_schema", "schema",
{"schema_valid": True, "schema_errors": []})
row("schema:errors-nonlist-ignored", "verify_schema", "schema",
{"schema_valid": True, "schema_errors": "nope"})
row("schema:errors-with-nested-values", "verify_schema", "schema",
{"schema_valid": False, "schema_errors": [3, {"path": "$.x", "msg": "type"}, True]})
row("schema:valid-null-defaults-true", "verify_schema", "schema",
{"schema_valid": None})
row("schema:valid-zero-falsy", "verify_schema", "schema", {"schema_valid": 0})
row("schema:valid-truthy-str", "verify_schema", "schema", {"schema_valid": "yes"})
row("schema:unicode-error-escaping", "verify_schema", "schema",
{"schema_valid": False, "schema_errors": ["ungültig bei „$.pfad“"]})
# ── verify_file_exists (fixture file is committed next to the port) ────────
row("file_exists:exists-pass", "verify_file_exists", "file_exists",
{"file_path": str(FIXTURE)})
row("file_exists:missing-fail", "verify_file_exists", "file_exists",
{"file_path": str(ROOT / "src/go/verification_layer/.fixtures/definitely_missing.txt")})
row("file_exists:empty-path-fail", "verify_file_exists", "file_exists",
{"file_path": ""})
row("file_exists:dir-counts", "verify_file_exists", "file_exists",
{"file_path": str(ROOT / "src/go/verification_layer/.fixtures")})
row("file_exists:absent-key-fail", "verify_file_exists", "file_exists", {})
# ── verify_file_changed ─────────────────────────────────────────────────────
row("file_changed:empty-expected-pass", "verify_file_changed", "file_changed",
{"file_path": "a.txt", "expected_hash": "", "actual_hash": "deadbeef"})
row("file_changed:match-pass", "verify_file_changed", "file_changed",
{"file_path": "a.txt", "expected_hash": "cafe", "actual_hash": "cafe"})
row("file_changed:mismatch-fail", "verify_file_changed", "file_changed",
{"file_path": "a.txt", "expected_hash": "cafe", "actual_hash": "beef"})
row("file_changed:no-keys-pass", "verify_file_changed", "file_changed", {})
# ── verify_tool_receipt ─────────────────────────────────────────────────────
row("tool_receipt:default-pass", "verify_tool_receipt", "tool_receipt", {})
row("tool_receipt:success-true", "verify_tool_receipt", "tool_receipt",
{"tool_success": True, "tool_name": "grep"})
row("tool_receipt:fail-with-error", "verify_tool_receipt", "tool_receipt",
{"tool_success": False, "tool_error": "boom: exit 2"})
row("tool_receipt:fail-empty-error", "verify_tool_receipt", "tool_receipt",
{"tool_success": False})
row("tool_receipt:zero-falsy", "verify_tool_receipt", "tool_receipt",
{"tool_success": 0, "tool_error": "falsy rc"})
row("tool_receipt:error-str-truthy", "verify_tool_receipt", "tool_receipt",
{"tool_success": "ok"})
# ── verify_constraint_check ─────────────────────────────────────────────────
row("constraint:default-pass", "verify_constraint_check", "constraint_check", {})
row("constraint:met-true-pass", "verify_constraint_check", "constraint_check",
{"constraints_met": True})
row("constraint:unmet-fail", "verify_constraint_check", "constraint_check",
{"constraints_met": False})
row("constraint:violations-fail", "verify_constraint_check", "constraint_check",
{"constraints_met": True, "constraint_violations": ["no secrets in diff"]})
row("constraint:violations-nested", "verify_constraint_check", "constraint_check",
{"constraints_met": False,
"constraint_violations": [{"rule": "R1", "at": 7}, 12, None]})
# ── verify dispatch (named + unknown) ───────────────────────────────────────
for vt in ("exit_code", "unit_test", "schema", "file_exists", "file_changed",
"tool_receipt", "constraint_check"):
row(f"dispatch:{vt}", "verify", vt, {})
row("dispatch:unknown-verifier", "verify", "nonexistent_verifier", {})
row("dispatch:unknown-empty-name", "verify", "", {})
row("dispatch:unknown-case-sensitive", "verify", "Exit_Code", {"exit_code": 0})
# ── handle_hook ─────────────────────────────────────────────────────────────
hook_row("hook:event-only", "verification.request")
hook_row("hook:event-with-data", "verification.done", {"passed": True})
# ── PLUGIN manifest ─────────────────────────────────────────────────────────
rows.append({
"name": "plugin:manifest",
"fn": "plugin",
"verifier_type": "",
"result": {},
"want": vl.PLUGIN,
"want_json": json.dumps(vl.PLUGIN, sort_keys=True),
})
doc = {
"frozen_ts": "2026-10-12T00:00:00+00:00",
"generator": "scripts/gen_verification_layer_truth.py — live oracle "
"src/rune/verification_layer.py (Rust evidence_provenance core)",
"rows": rows,
}
out = ROOT / "src/go/verification_layer/truth.json"
out.write_text(json.dumps(doc, indent=1, ensure_ascii=False) + "\n",
encoding="utf-8")
print(f"frozen {len(rows)} rows → {out}")
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Open the #2479 dichotomy-wave construction contract for the BATCH-A
modules (iteration, subconscious_pass, rune_profiler, subsystem_health).
Walks draft→approved→building in ONE process (shared-store clobber hazard).
Usage: open_contract_batch_a.py <module> [contract_id]
"""
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
module = sys.argv[1]
sym = {"iteration": "IT", "subconscious_pass": "SP",
"rune_profiler": "RP", "subsystem_health": "SH"}[module]
iface = ConstructionInterface(builder="factory-batch-a")
cid = sys.argv[2] if len(sys.argv) > 2 else None
r = iface.submit_need(
f"Port src/rune/{module}.py to FULL Rust (dichotomy factory, issue "
f"#2479 tranche): doc-envelope FFI, ctypes loader, facade delegation "
f"with RUNE_{sym}_CORE=python pin, frozen-truth battery, live parity "
f"100%, Phase B language-advantage pass.",
origin="builder",
contract_id=cid,
)
print("submit_need:", json.dumps(r)[:400])
if not r.get("success"):
print("NEED FAILED — aborting")
sys.exit(1)
c = r["ids"]["contract_id"]
print("contract_id:", c)
for phase in ("approved", "building"):
t = iface.transition(c, phase)
print(f"transition->{phase}:", json.dumps(t)[:300])
if not t.get("success"):
sys.exit(1)
print("OPENED", c)
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""Open the #2479 dichotomy-wave construction contract for inference_trace
(Rust port). Draft→approved→building in ONE process; verifying→closed at
delivery with SHA evidence."""
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/inference_trace.py to FULL Rust (dichotomy factory, "
"issue #2479 tranche): name-preserving doc-envelope FFI for the "
"inference-trace kernel (price_for, trace path resolution, record "
"serialization, rotation policy decision, read/limit selection; "
"file IO stays Python-side), ctypes loader it_loader.py mirroring "
"broker_loader.py (free via capability_scoring cs_free_string), facade "
"delegation with RUNE_IT_CORE=python pin, frozen-truth battery "
"generated against the live Python oracle, live parity 100%, Phase B "
"language-advantage pass.",
origin="builder",
)
print("submit_need:", json.dumps(r)[:200])
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"):
t = iface.transition(cid, phase)
print(f"transition->{phase}:", json.dumps(t)[:200])
if not t.get("success"):
sys.exit(1)
print("CONTRACT", cid, "IN BUILDING (close at delivery with SHAs)")
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
"""Open + walk the #2479 dichotomy-wave construction contract for
connection_pool to verifying. Full lifecycle in ONE process."""
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-batch-b")
r = iface.submit_need(
"Complete the connection_pool dichotomy port to FULL Rust (#2479 "
"tranche, programme verdict RUST): pool-bookkeeping kernel (pooling "
"order, stale removal, oldest-first eviction, status) as doc-envelope "
"FFI (cpool_new/begin_get/commit/close_all/status, free via "
"capability_scoring cs_free_string — no free re-export); cpool_loader "
"mirroring broker_loader.py; facade delegation with RUNE_CPOOL_CORE="
"python pin (sqlite handles stay in the facade); frozen-oracle battery "
"(16 cases, every kernel branch, frozen against a real sqlite-backed "
"pool); live parity 100% (60-seed random-op sweep); classification "
"flip GO→RUST; Phase B language-advantage pass.",
origin="builder",
)
print("submit_need:", json.dumps(r)[:300])
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)[:150])
if not t.get("success"):
sys.exit(1)
print("CONTRACT", cid, "verifying")
@@ -0,0 +1,41 @@
#!/usr/bin/env python3
"""Open + walk the #2479 dichotomy-wave construction contract for
construction_depth to verifying. Full lifecycle in ONE process (shared-store
clobber hazard). The close step runs separately (close_contract script)
after the register commit, per the dichotomy-wave store pattern."""
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-batch-b")
r = iface.submit_need(
"Complete the construction_depth dichotomy port to FULL Rust (#2479 "
"tranche): oracle-exact depth kernel (UNKNOWN ceremony/bypassed, "
"PROJECT_BUILD full-lifecycle strings, EXISTING_PROJECT_CHANGE base "
"ceremony + wide-surface escalation restored to oracle truth), "
"doc-envelope FFI (cd_select_depth, free via capability_scoring "
"cs_free_string — no free re-export), cd_loader mirroring "
"broker_loader.py, facade delegation with RUNE_CD_CORE=python pin, "
"frozen-oracle battery (40 cases, every public function/branch), live "
"parity 100%, Phase B language-advantage pass.",
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)[:200])
if not t.get("success"):
sys.exit(1)
print("CONTRACT", cid, "verifying")
@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Open → walk → close the #2479 dichotomy-wave construction contracts for
the forge + verification_layer GO batch (factory-batch-c). Full lifecycle
per contract, both back-to-back 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-batch-c")
CONTRACTS = [
{
"module": "forge",
"cid": "BUILDER-2026-10-12T17:43:29Z-ea9485-factory-batch-c",
"need": (
"Port src/rune/forge.py to FULL Go (dichotomy factory, issue "
"#2479 tranche, batch-c): the §18L forge boundary — ForgeAdapter "
"protocol, ForgeUnavailable, GiteaForge (env/push/commit_status/"
"ci_runs_for_sha/create_or_patch_release), default_forge, and the "
"scripts/gitea_auth credential ladder — name-preserving in "
"src/go/forge with IO behind CommandRunner/HTTPTransport/"
"TokenSource seams, frozen-truth battery (34 rows), live parity "
"100%, Phase B goroutine fan-out (Snapshot), compile-time seam "
"assertions."
),
"evidence": (
"forge parity port — 34/34 frozen rows replay verbatim (truth "
"regenerated live twice, byte-stable), battery covers every "
"public fn + branch (push truncation, status/runs HTTP capture "
"byte-parity, credential ladder all 3 rungs, release argv + "
"last-200 fallback), race-clean, gofmt/vet clean; Python oracle "
"tests green. SHAs: cdcae1ea (feat) ac114c32 (Phase B), pushed "
"gitea/master on top of 78a36204."
),
"scope_files": [
"src/rune/forge.py",
"src/go/forge/main.go",
"src/go/forge/truth_test.go",
"src/go/forge/phaseb.go",
"src/go/forge/phaseb_test.go",
"src/go/forge/truth.json",
"scripts/gen_forge_truth.py",
],
},
{
"module": "verification_layer",
"cid": "BUILDER-2026-10-12T17:46:05Z-c1a38e-factory-batch-c",
"need": (
"Port src/rune/verification_layer.py to FULL Go (dichotomy "
"factory, issue #2479 tranche, batch-c): all seven verifiers "
"(exit_code, unit_test, schema, file_exists, file_changed, "
"tool_receipt, constraint_check) + unknown-verifier dispatch, "
"VerificationResult.to_dict byte-rendering, handle_hook, "
"PLUGIN manifest — the Rust evidence_provenance semantics "
"carried 1:1 (verification.rs), name-preserving in "
"src/go/verification_layer with the FS probe behind a seam, "
"frozen-truth battery (62 rows), live parity 100%, Phase B "
"Verifier registry + VerifyAll goroutine fan-out."
),
"evidence": (
"verification_layer parity port — 62/62 frozen rows replay "
"verbatim byte-for-byte (truth regenerated live twice, "
"byte-stable) + 15/15 live CLI parity sweep incl. unicode "
"ensure_ascii escapes and non-string failures pass-through; "
"battery covers every verifier pass+fail branches, dispatch, "
"hook, PLUGIN; race-clean, gofmt/vet clean; Python tests green "
"(test_verification_layer_demo + test_evidence_provenance_shims, "
"7 passed). SHAs: d9009cc2 (feat) 2750eba0 (Phase B), pushed "
"gitea/master on top of 78a36204."
),
"scope_files": [
"src/rune/verification_layer.py",
"src/go/verification_layer/main.go",
"src/go/verification_layer/truth_test.go",
"src/go/verification_layer/phaseb.go",
"src/go/verification_layer/phaseb_test.go",
"src/go/verification_layer/truth.json",
"scripts/gen_verification_layer_truth.py",
],
},
]
cids = []
for spec in CONTRACTS:
r = iface.submit_need(spec["need"], origin="builder",
contract_id=spec["cid"])
print("submit_need:", json.dumps(r)[:200])
if not r.get("success"):
print("NEED FAILED — aborting")
sys.exit(1)
cid = r["ids"]["contract_id"]
cids.append(cid)
print("contract_id:", cid)
for phase in ("approved", "building", "verifying"):
t = iface.transition(cid, phase)
print(f"transition->{phase}:", json.dumps(t)[:150])
if not t.get("success"):
sys.exit(1)
c = iface.close(cid, observed_evidence=[{
"kind": "port_evidence",
"detail": spec["evidence"],
}], scope_files=spec["scope_files"])
print("close:", json.dumps(c)[:200])
print("CONTRACT", cid, spec["module"],
"closed" if c.get("success") else "CLOSE_FAILED")
print("-" * 60)
print("ALL CONTRACTS:", json.dumps(cids))
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
"""Open + walk the #2479 dichotomy-wave construction contract for
intent_continuity to verifying. Full lifecycle in ONE process."""
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-batch-b")
r = iface.submit_need(
"Complete the intent_continuity dichotomy port to FULL Rust (#2479 "
"tranche): ledger transition kernel (create/create_detour/resolve/"
"resolve_detour/supersede + record validation, oracle-exact error "
"strings and PARK-the-looked-up-object semantics) as doc-envelope FFI "
"(ic_* symbols, free via capability_scoring cs_free_string — no free "
"re-export); ic_loader mirroring broker_loader.py; facade owns file "
"persistence + clock (now passed per op), RUNE_IC_CORE=python pin; "
"frozen-oracle battery (16 cases, every transition/branch, stubbed "
"clock); live parity 100% (16/16 frozen + 40/40 fuzz seeds); Phase B "
"language-advantage pass (positional transitions).",
origin="builder",
)
print("submit_need:", json.dumps(r)[:300])
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)[:150])
if not t.get("success"):
sys.exit(1)
print("CONTRACT", cid, "verifying")
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env python3
"""Open + walk the #2479 dichotomy-wave construction contract for
recall_uplift to verifying. Full lifecycle in ONE process."""
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-batch-b")
r = iface.submit_need(
"Complete the recall_uplift dichotomy port to FULL Rust (#2479 "
"tranche): expansion kernel (tokenization, expansion map, co-occurrence "
"distinct-doc counting, LIMIT-32 like-match, distinctive-df filter, "
"term caps, best-effort degrade) as doc-envelope FFI (ru_expand, free "
"via capability_scoring cs_free_string — no free re-export); ru_loader "
"mirroring broker_loader.py; facade fetches the active corpus and "
"delegates all compute, RUNE_RU_CORE=python pin; frozen-oracle battery "
"(12 cases, every branch, tie-free engineered corpora); live parity "
"100% (12/12 frozen + 300/300 fuzz seed 2479); Phase B "
"language-advantage pass.",
origin="builder",
)
print("submit_need:", json.dumps(r)[:300])
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)[:150])
if not t.get("success"):
sys.exit(1)
print("CONTRACT", cid, "verifying")
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
View File
@@ -0,0 +1 @@
filetoken123
+1
View File
@@ -0,0 +1 @@
weaktoken
+3
View File
@@ -0,0 +1,3 @@
module rune/forge
go 1.24
+486
View File
@@ -0,0 +1,486 @@
// Package main — the FULL GO port of src/rune/forge.py (#2479 dichotomy
// wave, GO side verdict). Every public Python function has a
// name-preserving counterpart: GiteaForge (__init__ → NewGiteaForge,
// _env → env, push → Push, _gitea_auth → giteaAuth, commit_status →
// CommitStatus, ci_runs_for_sha → CiRunsForSha, create_or_patch_release →
// CreateOrPatchRelease), the ForgeAdapter protocol (→ interface),
// ForgeUnavailable (→ error type) and default_forge (→ DefaultForge).
// The gitea_auth credential ladder (scripts/gitea_auth.py) is carried
// 1:1 (env rung → 0600-enforced token file rung → git credential fill).
//
// All IO (git push, HTTP, credential helper, python release publisher)
// stays behind injectable seams (CommandRunner, HTTPTransport, TokenSource)
// so the frozen truth battery replays deterministically.
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"unicode/utf8"
)
// ── constants (scripts/gitea_auth.py + forge.py defaults) ───────────────────
const DefaultServer = "https://gitea.thingscouldgetdicey.online"
const DefaultRepo = "conductor/rune"
const GiteaHost = "gitea.thingscouldgetdicey.online"
// ── the forge boundary ──────────────────────────────────────────────────────
// ForgeAdapter — the minimum stable forge boundary (Python Protocol). All
// methods may return *ForgeUnavailable — callers treat forge failures as
// blocking-for-that-operation, never as construction-truth changes.
type ForgeAdapter interface {
Push(repo string, branch string) (map[string]any, error)
CommitStatus(repo string, sha string) (any, error)
CiRunsForSha(repo string, sha string) ([]map[string]any, error)
CreateOrPatchRelease(repo string, tag string, title string, body string) (map[string]any, error)
}
// ForgeUnavailable — the forge could not be reached or refused the
// operation (Python RuntimeError subclass; message parity is frozen).
type ForgeUnavailable struct{ Msg string }
func (e *ForgeUnavailable) Error() string { return e.Msg }
// GiteaCredentialError — scripts/gitea_auth.py's no-credential error
// (message never contains a credential).
type GiteaCredentialError struct{ Msg string }
func (e *GiteaCredentialError) Error() string { return e.Msg }
// PermissionError — the 0644-token-file rejection (Python PermissionError).
type PermissionError struct{ Msg string }
func (e *PermissionError) Error() string { return e.Msg }
// ── injectable IO seams ─────────────────────────────────────────────────────
// RunResult — subprocess capture (rc, stdout, stderr).
type RunResult struct {
Stdout string
Stderr string
RC int
}
// CommandRunner — the subprocess seam (git push, credential fill, release
// publisher). stdin carries the credential-fill payload.
type CommandRunner func(name string, args []string, stdin string) RunResult
// HTTPRequest — captured request surface (method, URL, headers).
type HTTPRequest struct {
Method string
URL string
Headers map[string]string
}
// HTTPTransport — the urllib seam. Returns the body bytes or an error whose
// Error() is byte-comparable to the oracle's str(exc).
type HTTPTransport func(req HTTPRequest) ([]byte, error)
// TokenSource — the gitea_auth credential ladder surface.
type TokenSource interface {
HasToken() bool
GetToken() (string, error)
}
// ── GiteaForge ──────────────────────────────────────────────────────────────
// GiteaForge — the real adapter (rule A: delegates to the canonical
// implementations; no duplicated API clients).
type GiteaForge struct {
Server string // "" → scripts' env/credential resolution (Python None)
Repo string
tokens TokenSource // nil → giteaLadder
runner CommandRunner // nil → execRunner
transport HTTPTransport // nil → urllibTransport
pythonBin string // "" → "python3" (sys.executable seam)
}
// NewGiteaForge — Python GiteaForge(server=None, repo="conductor/rune").
func NewGiteaForge(server string, repo string) *GiteaForge {
return &GiteaForge{Server: server, Repo: repo}
}
// compile-time assertion: GiteaForge satisfies the protocol.
var _ ForgeAdapter = (*GiteaForge)(nil)
func (f *GiteaForge) runnerOr() CommandRunner {
if f.runner != nil {
return f.runner
}
return execRunner
}
func (f *GiteaForge) transportOr() HTTPTransport {
if f.transport != nil {
return f.transport
}
return urllibTransport
}
func (f *GiteaForge) pythonBinOr() string {
if f.pythonBin != "" {
return f.pythonBin
}
return "python3"
}
// env — Python _env(): inherit os.environ; server override; repo default.
func (f *GiteaForge) env() map[string]string {
env := map[string]string{}
for _, kv := range os.Environ() {
if i := strings.IndexByte(kv, '='); i >= 0 {
env[kv[:i]] = kv[i+1:]
}
}
if f.Server != "" {
env["GITEA_SERVER"] = f.Server
}
if _, ok := env["GITEA_REPO"]; !ok {
env["GITEA_REPO"] = f.Repo
}
return env
}
// Push — git push gitea master:<branch>; failure → "push failed: <stderr[:200]>".
func (f *GiteaForge) Push(repo string, branch string) (map[string]any, error) {
r := f.runnerOr()("git", []string{"push", "gitea", "master:" + branch}, "")
if r.RC != 0 {
return nil, &ForgeUnavailable{fmt.Sprintf("push failed: %s", firstN(r.Stderr, 200))}
}
return map[string]any{"pushed": true, "branch": branch}, nil
}
// giteaAuth — Python _gitea_auth(): the canonical scripts/gitea_auth
// credential ladder (rule A: no duplicate auth). Seams overridable.
func (f *GiteaForge) giteaAuth() TokenSource {
if f.tokens != nil {
return f.tokens
}
return giteaLadder{}
}
// server — Python `self._server or os.environ.get("GITEA_SERVER", DEFAULT)`.
func (f *GiteaForge) server() string {
if f.Server != "" {
return f.Server
}
if v := os.Getenv("GITEA_SERVER"); v != "" {
return v
}
return DefaultServer
}
// CommitStatus — GET the combined commit status; returns data["state"]
// ("unknown" when the key is absent).
func (f *GiteaForge) CommitStatus(repo string, sha string) (any, error) {
tokens := f.giteaAuth()
if !tokens.HasToken() {
return nil, &ForgeUnavailable{"no forge credentials (gitea token)"}
}
tok, _ := tokens.GetToken()
req := HTTPRequest{
Method: "GET",
URL: fmt.Sprintf("%s/api/v1/repos/%s/commits/%s/status", f.server(), repo, sha),
Headers: map[string]string{"Authorization": "token " + tok},
}
body, err := f.transportOr()(req)
if err != nil {
return nil, &ForgeUnavailable{fmt.Sprintf("status unreachable: %s", err.Error())}
}
var data map[string]any
if err := decodeJSON(body, &data); err != nil {
return nil, err // Python json.loads errors propagate unwrapped
}
if v, ok := data["state"]; ok {
return v, nil
}
return "unknown", nil
}
// CiRunsForSha — GET the actions runs and keep those whose str(
// head_sha) equals sha (absent key → ""; JSON null → "None").
func (f *GiteaForge) CiRunsForSha(repo string, sha string) ([]map[string]any, error) {
tokens := f.giteaAuth()
if !tokens.HasToken() {
return nil, &ForgeUnavailable{"no forge credentials (gitea token)"}
}
tok, _ := tokens.GetToken()
req := HTTPRequest{
Method: "GET",
URL: fmt.Sprintf("%s/api/v1/repos/%s/actions/runs?limit=50", f.server(), repo),
Headers: map[string]string{"Authorization": "token " + tok},
}
body, err := f.transportOr()(req)
if err != nil {
return nil, &ForgeUnavailable{fmt.Sprintf("runs unreachable: %s", err.Error())}
}
var data map[string]any
if err := decodeJSON(body, &data); err != nil {
return nil, err
}
raw, ok := data["workflow_runs"]
if !ok {
return []map[string]any{}, nil
}
arr, _ := raw.([]any)
out := []map[string]any{}
for _, item := range arr {
run, _ := item.(map[string]any)
headSha := ""
if v, ok := run["head_sha"]; ok {
headSha = pyStrAny(v)
}
if headSha == sha {
out = append(out, run)
}
}
return out, nil
}
// CreateOrPatchRelease — delegate to the canonical idempotent publisher
// (scripts/create_release.py, CWD-relative like the oracle); the script
// path missing → "canonical release publisher not found".
func (f *GiteaForge) CreateOrPatchRelease(repo string, tag string, title string, body string) (map[string]any, error) {
tokens := f.giteaAuth()
if !tokens.HasToken() {
return nil, &ForgeUnavailable{"no forge credentials (gitea token)"}
}
if _, err := os.Stat("scripts/create_release.py"); err == nil {
r := f.runnerOr()(f.pythonBinOr(),
[]string{"scripts/create_release.py", "--tag", tag, "--title", title, "--body", body}, "")
if r.RC != 0 {
tail := r.Stderr
if tail == "" {
tail = r.Stdout
}
return nil, &ForgeUnavailable{fmt.Sprintf(
"release publication failed rc=%d: %s", r.RC, lastN(tail, 200))}
}
return map[string]any{"published": true, "tag": tag}, nil
}
return nil, &ForgeUnavailable{"canonical release publisher not found"}
}
// DefaultForge — the working adapter (rule 18L: prove Gitea still works).
func DefaultForge() *GiteaForge { return NewGiteaForge("", DefaultRepo) }
// ── gitea_auth credential ladder (scripts/gitea_auth.py, 1:1) ───────────────
// defaultTokenFilePath — ~/.config/opencode/secrets/gitea-token expanded.
var defaultTokenFilePath = func() string {
if home, err := os.UserHomeDir(); err == nil {
return filepath.Join(home, ".config", "opencode", "secrets", "gitea-token")
}
return ".config/opencode/secrets/gitea-token"
}
// giteaLadder — env rung → 0600-enforced token file rung → git credential
// fill. Never prints credentials; fails clearly when unavailable.
type giteaLadder struct {
runner CommandRunner // nil → execRunner
}
func (l giteaLadder) run() CommandRunner {
if l.runner != nil {
return l.runner
}
return execRunner
}
// HasToken — true if any rung of the credential ladder answers. Never fails.
func (l giteaLadder) HasToken() bool {
_, err := l.GetToken()
return err == nil
}
// GetToken — obtain the Gitea API token via the ladder.
func (l giteaLadder) GetToken() (string, error) {
token := strings.TrimSpace(os.Getenv("GITEA_TOKEN"))
if token != "" {
return token, nil
}
token, err := l.tokenFromFile()
if err != nil {
return "", err
}
if token != "" {
return token, nil
}
token = l.tokenFromCredentialHelper()
if token != "" {
return token, nil
}
return "", &GiteaCredentialError{fmt.Sprintf(
"Gitea credentials unavailable: set GITEA_TOKEN, create a mode-0600 "+
"token file at %s, or configure a git credential helper for %s",
defaultTokenFilePath(), GiteaHost)}
}
// tokenFromFile — GITEA_TOKEN_FILE (or the default path); must be mode 0600.
func (l giteaLadder) tokenFromFile() (string, error) {
path := os.Getenv("GITEA_TOKEN_FILE")
if path == "" {
path = defaultTokenFilePath()
}
path = expandUser(path)
st, err := os.Stat(path)
if err != nil || st.IsDir() {
return "", nil
}
if st.Mode().Perm()&0o077 != 0 {
return "", &PermissionError{fmt.Sprintf("Gitea token file must be mode 0600: %s", path)}
}
raw, err := os.ReadFile(path)
if err != nil {
return "", nil
}
return strings.TrimSpace(string(raw)), nil
}
// tokenFromCredentialHelper — `git credential fill` for the Gitea host.
func (l giteaLadder) tokenFromCredentialHelper() string {
stdin := fmt.Sprintf("protocol=https\nhost=%s\nusername=conductor\n\n", GiteaHost)
r := l.run()("git", []string{"credential", "fill"}, stdin)
for _, line := range strings.Split(r.Stdout, "\n") {
if strings.HasPrefix(line, "password=") {
return line[len("password="):]
}
}
return ""
}
// ── default seams ───────────────────────────────────────────────────────────
// execRunner — real subprocess capture (text=True semantics).
func execRunner(name string, args []string, stdin string) RunResult {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
cmd := exec.CommandContext(ctx, name, args...)
if stdin != "" {
cmd.Stdin = strings.NewReader(stdin)
}
var out, errb bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &errb
err := cmd.Run()
rc := 0
if err != nil {
if ee, ok := err.(*exec.ExitError); ok {
rc = ee.ExitCode()
} else {
rc = 127
}
}
return RunResult{Stdout: out.String(), Stderr: errb.String(), RC: rc}
}
// urllibTransport — urllib.request.urlopen(req, timeout=15) semantics:
// non-2xx → "HTTP Error <code>: <reason>", network failure →
// "<urlopen error <reason>>".
func urllibTransport(req HTTPRequest) ([]byte, error) {
full := http.Header{}
for k, v := range req.Headers {
full.Set(k, v)
}
client := &http.Client{Timeout: 15 * time.Second}
httpReq, err := http.NewRequest(req.Method, req.URL, nil)
if err != nil {
return nil, fmt.Errorf("<urlopen error %s>", err.Error())
}
httpReq.Header = full
resp, err := client.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("<urlopen error %s>", err.Error())
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf("HTTP Error %s",
strings.Replace(resp.Status, " ", ": ", 1))
}
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(resp.Body); err != nil {
return nil, fmt.Errorf("<urlopen error %s>", err.Error())
}
return buf.Bytes(), nil
}
// ── helpers ─────────────────────────────────────────────────────────────────
// decodeJSON — json.loads with Python-compatible number preservation
// (json.Number keeps the literal text so str() rendering matches).
func decodeJSON(data []byte, out *map[string]any) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
var v map[string]any
if err := dec.Decode(&v); err != nil {
return err
}
*out = v
return nil
}
// pyStrAny — Python str() of a JSON-decoded value (None/bool/int/str;
// numbers keep their JSON literal).
func pyStrAny(v any) string {
switch x := v.(type) {
case nil:
return "None"
case bool:
if x {
return "True"
}
return "False"
case string:
return x
case json.Number:
return x.String()
default:
return fmt.Sprintf("%v", x)
}
}
// firstN — Python s[:n] (codepoints).
func firstN(s string, n int) string {
if utf8.RuneCountInString(s) <= n {
return s
}
return string([]rune(s)[:n])
}
// lastN — Python s[-n:].
func lastN(s string, n int) string {
r := []rune(s)
if len(r) <= n {
return s
}
return string(r[len(r)-n:])
}
// expandUser — pathlib.Path.expanduser for the token-file path.
func expandUser(p string) string {
if p == "~" || strings.HasPrefix(p, "~/") {
if home, err := os.UserHomeDir(); err == nil {
return filepath.Join(home, strings.TrimPrefix(p, "~/"))
}
}
return p
}
// main — forge.py is a library module (the §18L boundary); the binary
// surfaces the boundary contract for smoke checks.
func main() {
fmt.Println("forge: T18 §18L minimum stable forge abstraction boundary (GO port)")
f := DefaultForge()
fmt.Printf("default forge: repo=%s server-attr=%q\n", f.Repo, f.Server)
}
+57
View File
@@ -0,0 +1,57 @@
package main
// Phase B language-advantage pass — dichotomy wave. Go-side wins the
// Python oracle can't express:
//
// 1. ForgeSnapshot — commit status and CI runs are two independent HTTP
// round-trips the oracle always performs serially; the GO port fans
// them out across goroutines (order-insensitive reassembly, both
// results preserved even when one side fails).
// 2. Compile-time safety: seam interfaces (TokenSource, CommandRunner,
// HTTPTransport) and the ForgeAdapter protocol are satisfaction-asserted
// at build time — drift breaks the compile, not a runtime cast.
import "sync"
// ForgeSnapshot — the CI verdict surface for one SHA: the combined status
// plus the workflow runs that belong to it.
type ForgeSnapshot struct {
Status any // commit_status state (str / JSON value)
Runs []map[string]any // workflow_runs filtered to the SHA
StatusErr error // ForgeUnavailable when the status call failed
RunsErr error // ForgeUnavailable when the runs call failed
}
// SnapshotForge — the fan-out interface (satisfied by *GiteaForge).
type SnapshotForge interface {
Snapshot(repo string, sha string) ForgeSnapshot
}
// Snapshot — CommitStatus and CiRunsForSha race concurrently and reassemble
// when both settle. Each half keeps its own error: a failed status call
// never masks the runs (and vice versa) — the oracle's serial version could
// only surface the first failure.
func (f *GiteaForge) Snapshot(repo string, sha string) ForgeSnapshot {
var (
wg sync.WaitGroup
snap ForgeSnapshot
)
wg.Add(2)
go func() {
defer wg.Done()
snap.Status, snap.StatusErr = f.CommitStatus(repo, sha)
}()
go func() {
defer wg.Done()
snap.Runs, snap.RunsErr = f.CiRunsForSha(repo, sha)
}()
wg.Wait()
return snap
}
// compile-time assertions: the seams keep their shapes.
var (
_ TokenSource = giteaLadder{}
_ SnapshotForge = (*GiteaForge)(nil)
_ ForgeAdapter = (*GiteaForge)(nil)
)
+120
View File
@@ -0,0 +1,120 @@
package main
// Phase B battery — pins the language-advantage guarantees: the Snapshot
// fan-out returns byte-identical halves to the serial oracle calls and is
// race-clean under -race; the seam interfaces stay satisfaction-asserted.
import (
"encoding/json"
"strings"
"testing"
)
func jsonMarshal(v any) ([]byte, error) { return json.Marshal(v) }
// TestSnapshotHalves — drive the fan-out through the same frozen truth
// bodies the battery pins, assert half-parity and race cleanliness.
func TestSnapshotHalves(t *testing.T) {
doc := loadTruth(t)
statusRows := map[string]TruthRow{}
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Op == "commit_status" {
setup := parseNum(t, row.Setup)
sha := strOrEmpty(setup["sha"])
if _, dup := statusRows[sha]; !dup {
statusRows[sha] = *row
}
}
}
replayed := 0
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Op != "ci_runs" {
continue
}
setup := parseNum(t, row.Setup)
if setup["payload"] == nil {
continue
}
sha := strOrEmpty(setup["sha"])
sRow, ok := statusRows[sha]
if !ok {
continue
}
replayed++
envGuard(t)
sSetup := parseNum(t, sRow.Setup)
payload, err := json.Marshal(setup["payload"])
if err != nil {
t.Fatalf("marshal payload: %v", err)
}
f := NewGiteaForge("", DefaultRepo)
f.tokens = stubTokens{has: true, tok: "t0k3n"}
tr := &recordingTransport{body: payload}
f.transport = tr.do
setEnv(t, map[string]any{"GITEA_SERVER": setup["env_server"]})
snap := f.Snapshot(strOrEmpty(setup["repo"]), sha)
// serial halves from the same frozen rows
sState, sErr := f.CommitStatus(strOrEmpty(sSetup["repo"]), sha)
sRuns, rErr := f.CiRunsForSha(strOrEmpty(setup["repo"]), sha)
if sErr != nil || rErr != nil {
t.Fatalf("serial halves unexpectedly failed: %v %v", sErr, rErr)
}
if snap.StatusErr != nil {
t.Fatalf("snapshot status half failed: %v", snap.StatusErr)
}
if snap.RunsErr != nil {
t.Fatalf("snapshot runs half failed: %v", snap.RunsErr)
}
if !equalAny(snap.Status, sState) {
t.Fatalf("snapshot status half diverges: %#v vs %#v", snap.Status, sState)
}
if len(snap.Runs) != len(sRuns) {
t.Fatalf("snapshot runs half diverges: %d vs %d runs", len(snap.Runs), len(sRuns))
}
}
if replayed == 0 {
t.Fatal("no snapshot replay rows — battery/truth drift")
}
}
// equalAny — deep equality over decoded JSON values.
func equalAny(a, b any) bool {
ab, err1 := json.Marshal(a)
bb, err2 := json.Marshal(b)
if err1 != nil || err2 != nil {
return false
}
return string(ab) == string(bb)
}
// TestSnapshotErrorHalves — a failing status call must not mask the runs
// (the language-advantage over the oracle's serial first-error semantics).
func TestSnapshotErrorHalves(t *testing.T) {
f := NewGiteaForge("", DefaultRepo)
f.tokens = stubTokens{has: true, tok: "t0k3n"}
f.transport = func(req HTTPRequest) ([]byte, error) {
if strings.Contains(req.URL, "/status") {
return nil, &ForgeUnavailable{"status unreachable: boom"}
}
return []byte(`{"workflow_runs": [{"head_sha": "abc"}]}`), nil
}
snap := f.Snapshot("o/r", "abc")
if snap.StatusErr == nil {
t.Fatal("status half should have failed")
}
if len(snap.Runs) != 1 {
t.Fatalf("runs half must survive: got %d", len(snap.Runs))
}
}
// TestSeamInterfacesSatisfied — compile-time assertions as a test.
func TestSeamInterfacesSatisfied(t *testing.T) {
var _ TokenSource = stubTokens{}
var _ TokenSource = giteaLadder{}
var _ ForgeAdapter = (*GiteaForge)(nil)
var _ SnapshotForge = (*GiteaForge)(nil)
}
+778
View File
@@ -0,0 +1,778 @@
{
"frozen_ts": "2026-10-12T00:00:00+00:00",
"generator": "scripts/gen_forge_truth.py — live oracle src/rune/forge.py",
"rows": [
{
"name": "default_forge:working-adapter",
"op": "default_forge",
"setup": {},
"want": {
"server": null,
"repo": "conductor/rune"
}
},
{
"name": "_env:env:inherits-and-defaults",
"op": "env",
"setup": {
"server": null,
"repo": null,
"environ": {
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": null,
"GITEA_REPO": "conductor/rune",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:server-override",
"op": "env",
"setup": {
"server": "http://local:3000",
"repo": null,
"environ": {
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": "http://local:3000",
"GITEA_REPO": "conductor/rune",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:repo-explicit",
"op": "env",
"setup": {
"server": null,
"repo": "other/repo",
"environ": {
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": null,
"GITEA_REPO": "other/repo",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:env-server-kept-when-no-attr",
"op": "env",
"setup": {
"server": null,
"repo": null,
"environ": {
"GITEA_SERVER": "http://env-server",
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": "http://env-server",
"GITEA_REPO": "conductor/rune",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:env-server-overridden-by-attr",
"op": "env",
"setup": {
"server": "http://attr",
"repo": null,
"environ": {
"GITEA_SERVER": "http://env-server",
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": "http://attr",
"GITEA_REPO": "conductor/rune",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:env-repo-not-clobbered",
"op": "env",
"setup": {
"server": null,
"repo": null,
"environ": {
"GITEA_REPO": "env/repo",
"RUNE_SAMPLE": ""
}
},
"want": {
"GITEA_SERVER": null,
"GITEA_REPO": "env/repo",
"RUNE_SAMPLE": ""
}
},
{
"name": "_env:env:inherits-sample-var",
"op": "env",
"setup": {
"server": null,
"repo": null,
"environ": {
"RUNE_SAMPLE": "1"
}
},
"want": {
"GITEA_SERVER": null,
"GITEA_REPO": "conductor/rune",
"RUNE_SAMPLE": "1"
}
},
{
"name": "push:push:ok",
"op": "push",
"setup": {
"repo": "ignored/repo",
"branch": "feature-x",
"rc": 0,
"stderr": ""
},
"want": {
"result": {
"pushed": true,
"branch": "feature-x"
},
"error": null,
"calls": [
{
"argv": [
"git",
"push",
"gitea",
"master:feature-x"
]
}
]
}
},
{
"name": "push:push:fail-short-stderr",
"op": "push",
"setup": {
"repo": "ignored/repo",
"branch": "main",
"rc": 1,
"stderr": "rejected non-fast-forward"
},
"want": {
"result": null,
"error": "push failed: rejected non-fast-forward",
"calls": [
{
"argv": [
"git",
"push",
"gitea",
"master:main"
]
}
]
}
},
{
"name": "push:push:fail-long-stderr-truncates-200",
"op": "push",
"setup": {
"repo": "ignored/repo",
"branch": "dev",
"rc": 128,
"stderr": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
},
"want": {
"result": null,
"error": "push failed: eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"calls": [
{
"argv": [
"git",
"push",
"gitea",
"master:dev"
]
}
]
}
},
{
"name": "push:push:fail-empty-stderr",
"op": "push",
"setup": {
"repo": "ignored/repo",
"branch": "release",
"rc": 2,
"stderr": ""
},
"want": {
"result": null,
"error": "push failed: ",
"calls": [
{
"argv": [
"git",
"push",
"gitea",
"master:release"
]
}
]
}
},
{
"name": "gitea_auth:env-token-rung",
"op": "gitea_auth",
"setup": {
"environ": {
"GITEA_TOKEN": " envtoken \n"
}
},
"want": {
"has_token": true,
"get_token": "envtoken"
}
},
{
"name": "gitea_auth:token-file-0600",
"op": "gitea_auth",
"setup": {
"environ": {
"GITEA_TOKEN_FILE": "<fixture token0600>"
}
},
"want": {
"has_token": true,
"get_token": "filetoken123"
}
},
{
"name": "gitea_auth:token-file-0644-rejected",
"op": "gitea_auth",
"setup": {
"environ": {
"GITEA_TOKEN_FILE": "<fixture token0644>"
}
},
"want": {
"has_token": false,
"get_token": null,
"error": "Gitea token file must be mode 0600: <FIXTURES>/token0644"
}
},
{
"name": "gitea_auth:no-credential",
"op": "gitea_auth",
"setup": {
"default_token_file": "<TMP>/missing-token"
},
"want": {
"has_token": false,
"get_token": null,
"error": "Gitea credentials unavailable: set GITEA_TOKEN, create a mode-0600 token file at <TMP>/missing-token, or configure a git credential helper for gitea.thingscouldgetdicey.online"
}
},
{
"name": "commit_status:commit_status:no-token",
"op": "commit_status",
"setup": {
"server": null,
"env_server": null,
"repo": "conductor/rune",
"sha": "abc",
"has_token": false,
"body": null,
"http_err": null
},
"want": {
"state": null,
"error": "no forge credentials (gitea token)",
"request": null
}
},
{
"name": "commit_status:commit_status:success",
"op": "commit_status",
"setup": {
"server": null,
"env_server": null,
"repo": "conductor/rune",
"sha": "abc",
"has_token": true,
"body": "{\"state\": \"success\"}",
"http_err": null
},
"want": {
"state": "success",
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/conductor/rune/commits/abc/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "commit_status:commit_status:state-missing-unknown",
"op": "commit_status",
"setup": {
"server": null,
"env_server": null,
"repo": "o/r",
"sha": "def",
"has_token": true,
"body": "{\"statuses\": []}",
"http_err": null
},
"want": {
"state": "unknown",
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/commits/def/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "commit_status:commit_status:server-attr-wins",
"op": "commit_status",
"setup": {
"server": "http://attr:3000",
"env_server": "http://env:3000",
"repo": "o/r",
"sha": "ghi",
"has_token": true,
"body": "{\"state\": \"pending\"}",
"http_err": null
},
"want": {
"state": "pending",
"error": null,
"request": {
"method": "GET",
"url": "http://attr:3000/api/v1/repos/o/r/commits/ghi/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "commit_status:commit_status:server-from-env",
"op": "commit_status",
"setup": {
"server": null,
"env_server": "http://env:3000",
"repo": "o/r",
"sha": "ghi",
"has_token": true,
"body": "{\"state\": \"failure\"}",
"http_err": null
},
"want": {
"state": "failure",
"error": null,
"request": {
"method": "GET",
"url": "http://env:3000/api/v1/repos/o/r/commits/ghi/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "commit_status:commit_status:http-error",
"op": "commit_status",
"setup": {
"server": null,
"env_server": null,
"repo": "o/r",
"sha": "jkl",
"has_token": true,
"body": null,
"http_err": "HTTP Error 404: Not Found"
},
"want": {
"state": null,
"error": "status unreachable: HTTP Error 404: Not Found",
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/commits/jkl/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "commit_status:commit_status:network-error",
"op": "commit_status",
"setup": {
"server": null,
"env_server": null,
"repo": "o/r",
"sha": "jkl",
"has_token": true,
"body": null,
"http_err": "conn refused"
},
"want": {
"state": null,
"error": "status unreachable: conn refused",
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/commits/jkl/status",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "ci_runs:ci_runs:no-token",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "s",
"payload": null,
"err": null,
"has_token": false
},
"want": {
"runs": null,
"error": "no forge credentials (gitea token)",
"request": null
}
},
{
"name": "ci_runs:ci_runs:filter-by-head-sha",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "abc",
"payload": {
"workflow_runs": [
{
"id": 1,
"head_sha": "abc"
},
{
"id": 2,
"head_sha": null
},
{
"id": 3,
"head_sha": "other"
},
{
"id": 4
},
{
"id": 5,
"head_sha": "abc"
}
]
},
"err": null,
"has_token": true
},
"want": {
"runs": [
{
"id": 1,
"head_sha": "abc"
},
{
"id": 5,
"head_sha": "abc"
}
],
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/actions/runs?limit=50",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "ci_runs:ci_runs:none-matching",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "zzz",
"payload": {
"workflow_runs": [
{
"id": 1,
"head_sha": "abc"
},
{
"id": 2,
"head_sha": null
},
{
"id": 3,
"head_sha": "other"
},
{
"id": 4
},
{
"id": 5,
"head_sha": "abc"
}
]
},
"err": null,
"has_token": true
},
"want": {
"runs": [],
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/actions/runs?limit=50",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "ci_runs:ci_runs:absent-key",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "s",
"payload": {
"total_count": 0
},
"err": null,
"has_token": true
},
"want": {
"runs": [],
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/actions/runs?limit=50",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "ci_runs:ci_runs:empty-sha-matches-absent",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "",
"payload": {
"workflow_runs": [
{
"id": 1,
"head_sha": "abc"
},
{
"id": 2,
"head_sha": null
},
{
"id": 3,
"head_sha": "other"
},
{
"id": 4
},
{
"id": 5,
"head_sha": "abc"
}
]
},
"err": null,
"has_token": true
},
"want": {
"runs": [
{
"id": 4
}
],
"error": null,
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/actions/runs?limit=50",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "ci_runs:ci_runs:unreachable",
"op": "ci_runs",
"setup": {
"server": null,
"repo": "o/r",
"sha": "s",
"payload": null,
"err": "runs down",
"has_token": true
},
"want": {
"runs": null,
"error": "runs unreachable: runs down",
"request": {
"method": "GET",
"url": "https://gitea.thingscouldgetdicey.online/api/v1/repos/o/r/actions/runs?limit=50",
"headers": {
"authorization": "token t0k3n"
}
}
}
},
{
"name": "release:release:no-token",
"op": "release",
"setup": {
"has_token": false,
"script_present": true,
"rc": 0,
"stderr": "",
"stdout": "",
"tag": "v9.9.9",
"cwd": "<root>"
},
"want": {
"result": null,
"error": "no forge credentials (gitea token)",
"argv": null,
"python_bin": null
}
},
{
"name": "release:release:published",
"op": "release",
"setup": {
"has_token": true,
"script_present": true,
"rc": 0,
"stderr": "",
"stdout": "",
"tag": "v1.2.3",
"cwd": "<root>"
},
"want": {
"result": {
"published": true,
"tag": "v1.2.3"
},
"error": null,
"argv": [
"scripts/create_release.py",
"--tag",
"v1.2.3",
"--title",
"T",
"--body",
"B"
],
"python_bin": "/mnt/workdrive/rune-wave-au/.venv/bin/python3"
}
},
{
"name": "release:release:script-fails-stderr",
"op": "release",
"setup": {
"has_token": true,
"script_present": true,
"rc": 3,
"stderr": "tag exists already",
"stdout": "",
"tag": "v0.0.1",
"cwd": "<root>"
},
"want": {
"result": null,
"error": "release publication failed rc=3: tag exists already",
"argv": [
"scripts/create_release.py",
"--tag",
"v0.0.1",
"--title",
"T",
"--body",
"B"
],
"python_bin": "/mnt/workdrive/rune-wave-au/.venv/bin/python3"
}
},
{
"name": "release:release:script-fails-falls-back-stdout",
"op": "release",
"setup": {
"has_token": true,
"script_present": true,
"rc": 4,
"stderr": "",
"stdout": "oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"tag": "v0.0.2",
"cwd": "<root>"
},
"want": {
"result": null,
"error": "release publication failed rc=4: oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
"argv": [
"scripts/create_release.py",
"--tag",
"v0.0.2",
"--title",
"T",
"--body",
"B"
],
"python_bin": "/mnt/workdrive/rune-wave-au/.venv/bin/python3"
}
},
{
"name": "release:release:script-missing",
"op": "release",
"setup": {
"has_token": true,
"script_present": false,
"rc": 0,
"stderr": "",
"stdout": "",
"tag": "v0.0.3",
"cwd": "<tmp>"
},
"want": {
"result": null,
"error": "canonical release publisher not found",
"argv": null,
"python_bin": null
}
}
]
}
+510
View File
@@ -0,0 +1,510 @@
package main
// Battery — the HARD parity gate replaying the frozen oracle truth
// (truth.json, generated against the LIVE Python oracle src/rune/forge.py
// with subprocess/urllib/gitea_auth seams captured) VERBATIM. IO seams are
// faked identically on the Go side; every captured call (argv, URL,
// headers) and every error message byte-compares to the oracle.
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"sync"
"testing"
)
type TruthDoc struct {
FrozenTS string `json:"frozen_ts"`
Generator string `json:"generator"`
Rows []TruthRow `json:"rows"`
}
type TruthRow struct {
Name string `json:"name"`
Op string `json:"op"`
Setup json.RawMessage `json:"setup"`
Want json.RawMessage `json:"want"`
}
func loadTruth(t *testing.T) *TruthDoc {
t.Helper()
raw, err := os.ReadFile("truth.json")
if err != nil {
t.Fatalf("truth.json missing (frozen oracle battery): %v", err)
}
var doc TruthDoc
if err := json.Unmarshal(raw, &doc); err != nil {
t.Fatalf("parse truth.json: %v", err)
}
if len(doc.Rows) == 0 {
t.Fatal("truth.json contained no rows")
}
seen := map[string]bool{}
for _, r := range doc.Rows {
if seen[r.Name] {
t.Fatalf("duplicate frozen row %q", r.Name)
}
seen[r.Name] = true
}
return &doc
}
// parseNum — decode with json.Number preservation (Python int/float str
// rendering parity).
func parseNum(t *testing.T, raw []byte) map[string]any {
t.Helper()
dec := json.NewDecoder(strings.NewReader(string(raw)))
dec.UseNumber()
var v map[string]any
if err := dec.Decode(&v); err != nil {
t.Fatalf("decode truth row: %v", err)
}
return v
}
// envGuard — snapshot and clear every forge-relevant env var; restores on
// test cleanup.
func envGuard(t *testing.T) {
t.Helper()
keys := []string{"GITEA_SERVER", "GITEA_REPO", "GITEA_TOKEN",
"GITEA_TOKEN_FILE", "RUNE_SAMPLE"}
saved := map[string]string{}
for _, k := range keys {
if v, ok := os.LookupEnv(k); ok {
saved[k] = v
}
os.Unsetenv(k)
}
t.Cleanup(func() {
for _, k := range keys {
os.Unsetenv(k)
}
for k, v := range saved {
os.Setenv(k, v)
}
})
}
func setEnv(t *testing.T, m map[string]any) {
t.Helper()
for k, v := range m {
if v == nil {
os.Unsetenv(k)
continue
}
if err := os.Setenv(k, fmt.Sprintf("%v", v)); err != nil {
t.Fatalf("setenv %s: %v", k, err)
}
}
}
func fileExists(p string) bool {
_, err := os.Stat(p)
return err == nil
}
func numInt(v any) int {
n, _ := v.(json.Number).Float64()
return int(n)
}
// recordingRunner — fake CommandRunner capturing (name, args, stdin).
type recordingRunner struct {
calls []map[string]any
res RunResult
}
func (r *recordingRunner) run(name string, args []string, stdin string) RunResult {
argv := []any{name}
for _, a := range args {
argv = append(argv, a)
}
r.calls = append(r.calls, map[string]any{"argv": argv})
return r.res
}
// stubTokens — the generator's auth_stub(has=..., token="t0k3n").
type stubTokens struct {
has bool
tok string
}
func (s stubTokens) HasToken() bool { return s.has }
func (s stubTokens) GetToken() (string, error) { return s.tok, nil }
// recordingTransport — fake HTTPTransport capturing requests (mutexed:
// the Phase B Snapshot fan-out drives it from two goroutines).
type recordingTransport struct {
mu sync.Mutex
calls []map[string]any
body []byte
err error
}
func (tr *recordingTransport) do(req HTTPRequest) ([]byte, error) {
tr.mu.Lock()
defer tr.mu.Unlock()
headers := map[string]any{}
for k, v := range req.Headers {
headers[strings.ToLower(k)] = v
}
tr.calls = append(tr.calls, map[string]any{
"method": req.Method,
"url": req.URL,
"headers": headers,
})
if tr.err != nil {
return nil, tr.err
}
return tr.body, nil
}
func strOrEmpty(v any) string {
if v == nil {
return ""
}
return v.(string)
}
func errStr(err error) any {
if err == nil {
return nil
}
return err.Error()
}
// runOne — replay one frozen row; returns "" on parity.
func runOne(t *testing.T, row *TruthRow) string {
t.Helper()
setup := parseNum(t, row.Setup)
want := parseNum(t, row.Want)
envGuard(t)
switch row.Op {
case "default_forge":
f := DefaultForge()
got := map[string]any{"server": nil, "repo": f.Repo}
if f.Server != "" {
got["server"] = f.Server
}
if !reflect.DeepEqual(got["server"], want["server"]) || got["repo"] != want["repo"] {
return fmt.Sprintf("default_forge diverges: got %v want %v", got, want)
}
return ""
case "env":
setEnv(t, setup["environ"].(map[string]any))
var server, repo string
if setup["server"] != nil {
server = setup["server"].(string)
}
if setup["repo"] != nil {
repo = setup["repo"].(string)
} else {
repo = DefaultRepo
}
built := NewGiteaForge(server, repo).env()
for k, wv := range want {
gv, ok := built[k]
var g any
if ok {
g = gv
}
if !reflect.DeepEqual(g, wv) {
return fmt.Sprintf("env[%s] diverges: got %v want %v", k, g, wv)
}
}
return ""
case "push":
runner := &recordingRunner{res: RunResult{
RC: numInt(setup["rc"]),
Stderr: strOrEmpty(setup["stderr"]),
}}
f := NewGiteaForge("", DefaultRepo)
f.runner = runner.run
got, err := f.Push(strOrEmpty(setup["repo"]), strOrEmpty(setup["branch"]))
if mismatch(errStr(err), want["error"]) {
return fmt.Sprintf("push error diverges: got %v want %v", errStr(err), want["error"])
}
if err == nil && !reflect.DeepEqual(got, want["result"]) {
return fmt.Sprintf("push result diverges: got %v want %v", got, want["result"])
}
return compareCalls(runner.calls, want["calls"].([]any))
case "gitea_auth":
fixtures, _ := filepath.Abs(".fixtures")
// git stores only the exec bit — pin the token-file modes the
// ladder's 0600 check depends on (the generator chmods likewise)
if err := os.Chmod(filepath.Join(fixtures, "token0600"), 0o600); err != nil {
t.Fatalf("chmod fixture: %v", err)
}
if err := os.Chmod(filepath.Join(fixtures, "token0644"), 0o644); err != nil {
t.Fatalf("chmod fixture: %v", err)
}
if envRaw, ok := setup["environ"]; ok {
for k, v := range envRaw.(map[string]any) {
val := fmt.Sprintf("%v", v)
val = strings.ReplaceAll(val, "<fixture token0600>", filepath.Join(fixtures, "token0600"))
val = strings.ReplaceAll(val, "<fixture token0644>", filepath.Join(fixtures, "token0644"))
if err := os.Setenv(k, val); err != nil {
t.Fatalf("setenv: %v", err)
}
}
}
var tmpDir string
if d, ok := setup["default_token_file"]; ok {
tmpDir = t.TempDir()
pinned := strings.ReplaceAll(d.(string), "<TMP>/", tmpDir+"/")
orig := defaultTokenFilePath
defaultTokenFilePath = func() string { return pinned }
t.Cleanup(func() { defaultTokenFilePath = orig })
}
ladder := giteaLadder{runner: func(name string, args []string, stdin string) RunResult {
// the pinned no-credential world: helper yields nothing
return RunResult{Stdout: "", Stderr: "", RC: 0}
}}
has := ladder.HasToken()
got := map[string]any{"has_token": has, "get_token": nil, "error": nil}
tok, err := ladder.GetToken()
if err == nil {
got["get_token"] = tok
} else {
msg := err.Error()
msg = strings.ReplaceAll(msg, fixtures+"/", "<FIXTURES>/")
if tmpDir != "" {
msg = strings.ReplaceAll(msg, tmpDir+"/", "<TMP>/")
}
got["error"] = msg
}
if !reflect.DeepEqual(got["has_token"], want["has_token"]) ||
!reflect.DeepEqual(got["get_token"], want["get_token"]) ||
!reflect.DeepEqual(got["error"], want["error"]) {
return fmt.Sprintf("gitea_auth diverges:\n got %v\n want %v", got, want)
}
return ""
case "commit_status":
body := []byte(nil)
if setup["body"] != nil {
body = []byte(setup["body"].(string))
}
var httpErr error
if setup["http_err"] != nil {
httpErr = fmt.Errorf("%s", setup["http_err"].(string))
}
tr := &recordingTransport{body: body, err: httpErr}
f := NewGiteaForge(strOrEmpty(setup["server"]), DefaultRepo)
f.tokens = stubTokens{has: setup["has_token"].(bool), tok: "t0k3n"}
f.transport = tr.do
setEnv(t, map[string]any{"GITEA_SERVER": setup["env_server"]})
got, err := f.CommitStatus(strOrEmpty(setup["repo"]), strOrEmpty(setup["sha"]))
if mismatch(errStr(err), want["error"]) {
return fmt.Sprintf("commit_status error diverges: got %v want %v",
errStr(err), want["error"])
}
if err == nil && !reflect.DeepEqual(got, want["state"]) {
return fmt.Sprintf("commit_status state diverges: got %#v want %#v",
got, want["state"])
}
return compareRequest(tr.calls, want["request"])
case "ci_runs":
var body []byte
if setup["payload"] != nil {
raw, err := json.Marshal(setup["payload"])
if err != nil {
t.Fatalf("marshal payload: %v", err)
}
body = raw
}
var httpErr error
if setup["err"] != nil {
httpErr = fmt.Errorf("%s", setup["err"].(string))
}
tr := &recordingTransport{body: body, err: httpErr}
f := NewGiteaForge(strOrEmpty(setup["server"]), DefaultRepo)
f.tokens = stubTokens{has: setup["has_token"].(bool), tok: "t0k3n"}
f.transport = tr.do
got, err := f.CiRunsForSha(strOrEmpty(setup["repo"]), strOrEmpty(setup["sha"]))
if mismatch(errStr(err), want["error"]) {
return fmt.Sprintf("ci_runs error diverges: got %v want %v",
errStr(err), want["error"])
}
if err == nil {
conv := make([]any, len(got))
for i, r := range got {
conv[i] = r
}
if !reflect.DeepEqual(conv, want["runs"]) {
return fmt.Sprintf("ci_runs diverges:\n got %#v\n want %#v",
conv, want["runs"])
}
}
return compareRequest(tr.calls, want["request"])
case "release":
repoRoot, err := filepath.Abs("../..") // src/go/forge → repo root
if !fileExists(filepath.Join(repoRoot, "scripts/create_release.py")) {
repoRoot, _ = filepath.Abs("../../..")
}
if err != nil {
t.Fatalf("abs: %v", err)
}
if setup["script_present"].(bool) {
t.Chdir(repoRoot)
} else {
t.Chdir(t.TempDir())
}
runner := &recordingRunner{res: RunResult{
RC: numInt(setup["rc"]),
Stdout: strOrEmpty(setup["stdout"]),
Stderr: strOrEmpty(setup["stderr"]),
}}
f := NewGiteaForge("", DefaultRepo)
f.tokens = stubTokens{has: setup["has_token"].(bool), tok: "t0k3n"}
f.runner = runner.run
got, err := f.CreateOrPatchRelease("o/r", strOrEmpty(setup["tag"]), "T", "B")
if mismatch(errStr(err), want["error"]) {
return fmt.Sprintf("release error diverges:\n got %v\n want %v",
errStr(err), want["error"])
}
if err == nil && !reflect.DeepEqual(got, want["result"]) {
return fmt.Sprintf("release result diverges: got %v want %v", got, want["result"])
}
if want["argv"] == nil {
if len(runner.calls) != 0 {
return "release: expected no subprocess call"
}
return ""
}
// the oracle records argv[1:] (sys.executable dropped); the Go
// seam's pythonBin default is "python3"
if len(runner.calls) != 1 {
return fmt.Sprintf("release: got %d subprocess calls, want 1",
len(runner.calls))
}
argv := runner.calls[0]["argv"].([]any)
if argv[0] != "python3" {
return fmt.Sprintf("release: pythonBin seam got %v, want python3", argv[0])
}
return compareCalls([]map[string]any{{"argv": argv[1:]}},
[]any{map[string]any{"argv": want["argv"]}})
}
return "unknown op " + row.Op
}
func mismatch(got, want any) bool {
if got == nil && want == nil {
return false
}
if got == nil || want == nil {
return true
}
return got != want
}
func compareCalls(got []map[string]any, want []any) string {
if len(got) != len(want) {
return fmt.Sprintf("call count diverges: got %d want %d", len(got), len(want))
}
for i := range want {
w := want[i].(map[string]any)
wargv := w["argv"].([]any)
gargv := got[i]["argv"].([]any)
if len(wargv) != len(gargv) {
return fmt.Sprintf("call[%d] argv length diverges: got %v want %v", i, gargv, wargv)
}
for j := range wargv {
if gargv[j] != wargv[j] {
return fmt.Sprintf("call[%d].argv[%d] diverges: got %v want %v",
i, j, gargv[j], wargv[j])
}
}
}
return ""
}
func compareRequest(got []map[string]any, want any) string {
if want == nil {
if len(got) != 0 {
return "expected no HTTP request"
}
return ""
}
w := want.(map[string]any)
if len(got) == 0 {
return "expected an HTTP request, got none"
}
g := got[0]
if g["method"] != w["method"] || g["url"] != w["url"] {
return fmt.Sprintf("request diverges:\n got %s %s\n want %s %s",
g["method"], g["url"], w["method"], w["url"])
}
gh := g["headers"].(map[string]any)
wh := w["headers"].(map[string]any)
if !reflect.DeepEqual(gh, wh) {
return fmt.Sprintf("headers diverge:\n got %v\n want %v", gh, wh)
}
return ""
}
// TestTruthParity — replay EVERY frozen row verbatim.
func TestTruthParity(t *testing.T) {
doc := loadTruth(t)
for i := range doc.Rows {
row := &doc.Rows[i]
t.Run(row.Name, func(t *testing.T) {
if msg := runOne(t, row); msg != "" {
t.Fatalf("DIVERGED %s: %s", row.Name, msg)
}
})
}
}
// TestBatteryCoversEveryPublicFunction — the frozen battery must exercise
// every public surface: Push, CommitStatus, CiRunsForSha,
// CreateOrPatchRelease, env, giteaAuth ladder, DefaultForge.
func TestBatteryCoversEveryPublicFunction(t *testing.T) {
doc := loadTruth(t)
have := map[string]int{}
for _, r := range doc.Rows {
have[r.Op]++
}
for op, min := range map[string]int{
"default_forge": 1, "env": 1, "push": 1, "gitea_auth": 1,
"commit_status": 1, "ci_runs": 1, "release": 1,
} {
if have[op] < min {
t.Errorf("frozen battery missing rows for op %s", op)
}
}
// success AND failure branch per IO op
for _, op := range []string{"push", "commit_status", "ci_runs", "release"} {
ok, fail := 0, 0
for _, r := range doc.Rows {
if r.Op != op {
continue
}
w := parseNum(t, r.Want)
if w["error"] == nil {
ok++
} else {
fail++
}
}
if ok == 0 || fail == 0 {
t.Errorf("op %s: battery lacks branch coverage (ok=%d fail=%d)", op, ok, fail)
}
}
}
// TestForgeAdapterSatisfied — compile-time assertion, re-asserted as a test.
func TestForgeAdapterSatisfied(t *testing.T) {
var _ ForgeAdapter = (*GiteaForge)(nil)
var _ ForgeAdapter = DefaultForge()
}
@@ -0,0 +1 @@
fixture artifact for the file_exists verifier battery
+3
View File
@@ -0,0 +1,3 @@
module rune/verification_layer
go 1.22
+628
View File
@@ -0,0 +1,628 @@
// Package main — the FULL GO port of src/rune/verification_layer.py
// (#2479 dichotomy wave, GO side verdict). Every public Python function has
// a name-preserving counterpart: verify_exit_code, verify_unit_test,
// verify_schema, verify_file_exists, verify_file_changed, verify_tool_receipt,
// verify_constraint_check, verify (dispatch incl. the unknown-verifier path),
// handle_hook, VerificationResult.to_dict and the PLUGIN manifest.
//
// The Python module delegates to the Rust evidence_provenance core
// (src/rust/evidence_provenance/src/verification.rs) — this port carries
// those exact semantics 1:1, including the Python str() rendering rules
// (bool → "True"/"False", None → "None") for evidence_refs and the
// to_dict() key order passed, verifier_type, evidence_refs, failures,
// retryable, escalation_reason with byte-exact json.dumps rendering.
//
// Results are *JSONValue (insertion-ordered objects — Python dicts preserve
// order and the pass-through failures rows render nested objects byte-for-
// byte). The filesystem probe stays behind an injectable seam so the frozen
// truth battery replays deterministically.
package main
import (
"encoding/json"
"fmt"
"math"
"os"
"strconv"
"strings"
)
// VerificationResult — the Python dataclass, field-for-field.
type VerificationResult struct {
Passed bool
VerifierType string
EvidenceRefs []string
Failures []JSONValue
Retryable bool
EscalationReason *string // nil ↔ Python None
}
// ToDict — Python VerificationResult.to_dict(): the ordered key set
// passed, verifier_type, evidence_refs, failures, retryable, escalation_reason.
func (r VerificationResult) ToDict() JSONValue {
esc := JSONNull()
if r.EscalationReason != nil {
esc = JSONString(*r.EscalationReason)
}
return JSONObject([]KV{
{"passed", JSONBool(r.Passed)},
{"verifier_type", JSONString(r.VerifierType)},
{"evidence_refs", jsonStringArr(r.EvidenceRefs)},
{"failures", JSONArray(r.Failures)},
{"retryable", JSONBool(r.Retryable)},
{"escalation_reason", esc},
})
}
// ToDictJSON — json.dumps(r.ToDict()) byte rendering (Python separators
// ", "/": ", ensure_ascii=True).
func (r VerificationResult) ToDictJSON() string {
return renderJSON(r.ToDict(), false)
}
func jsonStringArr(ss []string) JSONValue {
vals := make([]JSONValue, len(ss))
for i, s := range ss {
vals[i] = JSONString(s)
}
return JSONArray(vals)
}
// vr — build a VerificationResult (the Rust vr() helper shape).
func vr(passed bool, verifierType string, evidenceRefs []string,
failures []JSONValue, retryable bool, escalationReason *string) VerificationResult {
return VerificationResult{
Passed: passed,
VerifierType: verifierType,
EvidenceRefs: evidenceRefs,
Failures: failures,
Retryable: retryable,
EscalationReason: escalationReason,
}
}
func strPtr(s string) *string { return &s }
// ── Python semantics helpers (mirror verification.rs 1:1) ──────────────────
// pyStr — Python str() of a JSON value: None / True / False / int / str.
func pyStr(v JSONValue) string {
switch v.Kind {
case KindNull:
return "None"
case KindString:
return v.Str
case KindBool:
if v.Bool {
return "True"
}
return "False"
case KindNumber:
return fmtNum(numF64(v.Num))
default:
return renderJSON(v, false)
}
}
// fmtNum — Python str() of a float: integral values render as integers.
func fmtNum(n float64) string {
if !math.IsInf(n, 0) && !math.IsNaN(n) &&
n == math.Trunc(n) && math.Abs(n) < 9.007199254740992e15 {
return strconv.FormatInt(int64(n), 10)
}
return strconv.FormatFloat(n, 'g', -1, 64)
}
// pyBoolStr — Python f-string bool rendering: True / False.
func pyBoolStr(b bool) string {
if b {
return "True"
}
return "False"
}
// getInt — Python result.get(key, default) for ints (bools count: True→1).
func getInt(result *JSONValue, key string, def int64) int64 {
v := result.Get(key)
if v == nil {
return def
}
switch v.Kind {
case KindNumber:
return int64(numF64(v.Num))
case KindBool:
if v.Bool {
return 1
}
return 0
default:
return def
}
}
// getStr — Python result.get(key, default) for strings.
func getStr(result *JSONValue, key, def string) string {
if v := result.Get(key); v != nil && v.Kind == KindString {
return v.Str
}
return def
}
// getTruthy — Python truthiness (default-True pattern: absent/None → default).
func getTruthy(result *JSONValue, key string, def bool) bool {
v := result.Get(key)
if v == nil || v.Kind == KindNull {
return def
}
switch v.Kind {
case KindBool:
return v.Bool
case KindNumber:
return numF64(v.Num) != 0
case KindString:
return v.Str != ""
case KindArray:
return len(v.Arr) != 0
default:
return true
}
}
// getArr — Python result.get(key, []) pass-through (only JSON arrays).
func getArr(result *JSONValue, key string) []JSONValue {
if v := result.Get(key); v != nil && v.Kind == KindArray {
return v.Arr
}
return nil
}
// ── the seven verifiers ─────────────────────────────────────────────────────
// VerifyExitCode — exit_code defaults 0; passed iff == 0 (Python ==
// semantics: bool False→0 passes, True/str/None do not).
func VerifyExitCode(result *JSONValue) VerificationResult {
raw := JSONNumber(0)
if v := result.Get("exit_code"); v != nil {
raw = *v
}
passed := false
switch raw.Kind {
case KindNumber:
passed = numF64(raw.Num) == 0
case KindBool:
passed = !raw.Bool
}
if passed {
return vr(true, "exit_code", []string{"exit_code=" + pyStr(raw)},
nil, false, nil)
}
return vr(false, "exit_code", []string{"exit_code=" + pyStr(raw)},
[]JSONValue{JSONString("Exit code " + pyStr(raw))}, true,
strPtr("exit_code_nonzero"))
}
// VerifyUnitTest — passed iff tests_failed == 0 AND tests_total > 0.
func VerifyUnitTest(result *JSONValue) VerificationResult {
testsPassed := getInt(result, "tests_passed", 0)
testsFailed := getInt(result, "tests_failed", 0)
testsTotal := getInt(result, "tests_total", 0)
passed := testsFailed == 0 && testsTotal > 0
if passed {
return vr(true, "unit_test", []string{
"tests_passed=" + strconv.FormatInt(testsPassed, 10),
"tests_failed=" + strconv.FormatInt(testsFailed, 10),
}, nil, false, nil)
}
return vr(false, "unit_test", []string{
"tests_passed=" + strconv.FormatInt(testsPassed, 10),
"tests_failed=" + strconv.FormatInt(testsFailed, 10),
}, []JSONValue{JSONString(strconv.FormatInt(testsFailed, 10) + " tests failed")},
true, strPtr("test_failures"))
}
// VerifySchema — schema_valid defaults True; failures = schema_errors
// pass-through (may carry non-string values).
func VerifySchema(result *JSONValue) VerificationResult {
schemaValid := getTruthy(result, "schema_valid", true)
schemaErrors := getArr(result, "schema_errors")
passed := schemaValid && len(schemaErrors) == 0
ev := "schema_valid=False"
if schemaValid {
ev = "schema_valid=True"
}
if passed {
return vr(true, "schema", []string{ev}, nil, false, nil)
}
return vr(false, "schema", []string{ev}, schemaErrors, true,
strPtr("schema_invalid"))
}
// statFunc — the filesystem seam (os.Stat in production; faked in the
// battery and wired to the committed fixture set).
var statFunc = os.Stat
// VerifyFileExists — real filesystem check; empty path → not exists.
func VerifyFileExists(result *JSONValue) VerificationResult {
filePath := getStr(result, "file_path", "")
exists := filePath != ""
if exists {
if _, err := statFunc(filePath); err != nil {
exists = false
}
}
if exists {
return vr(true, "file_exists", []string{"file_path=" + filePath},
nil, false, nil)
}
return vr(false, "file_exists", []string{"file_path=" + filePath},
[]JSONValue{JSONString("File not found: " + filePath)}, true,
strPtr("file_not_found"))
}
// VerifyFileChanged — empty expected_hash → passed (no comparison).
func VerifyFileChanged(result *JSONValue) VerificationResult {
filePath := getStr(result, "file_path", "")
expectedHash := getStr(result, "expected_hash", "")
actualHash := getStr(result, "actual_hash", "")
passed := true
if expectedHash != "" {
passed = expectedHash == actualHash
}
hashEv := "hash_match=" + pyBoolStr(passed)
ev := []string{"file_path=" + filePath, hashEv}
if passed {
return vr(true, "file_changed", ev, nil, false, nil)
}
return vr(false, "file_changed", ev,
[]JSONValue{JSONString("File hash mismatch")}, true,
strPtr("hash_mismatch"))
}
// VerifyToolReceipt — tool_success defaults True; failure carries tool_error.
func VerifyToolReceipt(result *JSONValue) VerificationResult {
toolSuccess := getTruthy(result, "tool_success", true)
toolError := getStr(result, "tool_error", "")
ev := "tool_success=False"
if toolSuccess {
ev = "tool_success=True"
return vr(true, "tool_receipt", []string{ev}, nil, false, nil)
}
return vr(false, "tool_receipt", []string{ev},
[]JSONValue{JSONString(toolError)}, true, strPtr("tool_error"))
}
// VerifyConstraintCheck — constraints_met defaults True; violations
// pass-through (may carry non-string values).
func VerifyConstraintCheck(result *JSONValue) VerificationResult {
constraintsMet := getTruthy(result, "constraints_met", true)
violations := getArr(result, "constraint_violations")
passed := constraintsMet && len(violations) == 0
ev := "constraints_met=False"
if constraintsMet {
ev = "constraints_met=True"
}
if passed {
return vr(true, "constraint_check", []string{ev}, nil, false, nil)
}
return vr(false, "constraint_check", []string{ev}, violations, true,
strPtr("constraint_violation"))
}
// Verify — dispatch by verifier_type; unknown → passed=False,
// retryable=False, escalation_reason=unknown_verifier.
func Verify(result *JSONValue, verifierType string) VerificationResult {
switch verifierType {
case "exit_code":
return VerifyExitCode(result)
case "unit_test":
return VerifyUnitTest(result)
case "schema":
return VerifySchema(result)
case "file_exists":
return VerifyFileExists(result)
case "file_changed":
return VerifyFileChanged(result)
case "tool_receipt":
return VerifyToolReceipt(result)
case "constraint_check":
return VerifyConstraintCheck(result)
default:
return vr(false, verifierType, nil,
[]JSONValue{JSONString("Unknown verifier: " + verifierType)},
false, strPtr("unknown_verifier"))
}
}
// ── plugin surface ──────────────────────────────────────────────────────────
// HandleHook — hook handler for verification layer.
func HandleHook(event string, data ...any) map[string]any {
return map[string]any{
"status": "ok",
"event": event,
"handler": "verification_layer",
}
}
// Plugin — the Python PLUGIN manifest, 1:1.
var Plugin = map[string]any{
"name": "verification_layer",
"version": "1.0.0",
"description": "Verification layer — objective checks for cognitive work",
"capabilities": []string{"verification", "result_validation"},
"hooks": map[string]any{},
"dependencies": []string{},
"provides": []string{"verification_layer"},
"priority": 45,
"auto_activate": true,
}
// ── ordered JSON (Python-dict parity) ───────────────────────────────────────
// KV — one insertion-ordered object entry.
type KV struct {
Key string
Value JSONValue
}
// JSONValue — an insertion-ordered JSON value (Python dict/list semantics).
type JSONValue struct {
Kind Kind
Str string
Num json.Number
Bool bool
Arr []JSONValue
Obj []KV
}
// Kind — discriminated union tag.
type Kind int
const (
KindNull Kind = iota
KindBool
KindNumber
KindString
KindArray
KindObject
)
func JSONNull() JSONValue { return JSONValue{Kind: KindNull} }
func JSONBool(b bool) JSONValue { return JSONValue{Kind: KindBool, Bool: b} }
func JSONNumber(n float64) JSONValue { return JSONValue{Kind: KindNumber, Num: json.Number(fmtNum(n))} }
// numF64 — json.Number → float64.
func numF64(n json.Number) float64 {
f, err := n.Float64()
if err != nil {
return 0
}
return f
}
func JSONString(s string) JSONValue { return JSONValue{Kind: KindString, Str: s} }
func JSONArray(a []JSONValue) JSONValue { return JSONValue{Kind: KindArray, Arr: a} }
func JSONObject(o []KV) JSONValue { return JSONValue{Kind: KindObject, Obj: o} }
// Get — Python result.get(key) (nil when absent or not an object).
func (v *JSONValue) Get(key string) *JSONValue {
if v == nil || v.Kind != KindObject {
return nil
}
for i := range v.Obj {
if v.Obj[i].Key == key {
return &v.Obj[i].Value
}
}
return nil
}
// ParseJSON — decode bytes into an ordered JSONValue (objects keep
// insertion order; numbers keep their literal text).
func ParseJSON(data []byte) (JSONValue, error) {
dec := json.NewDecoder(strings.NewReader(string(data)))
dec.UseNumber()
var v JSONValue
if err := decodeValue(dec, &v); err != nil {
return JSONNull(), err
}
return v, nil
}
func decodeValue(dec *json.Decoder, out *JSONValue) error {
tok, err := dec.Token()
if err != nil {
return err
}
return decodeToken(dec, tok, out)
}
func decodeToken(dec *json.Decoder, tok json.Token, out *JSONValue) error {
switch t := tok.(type) {
case nil:
*out = JSONNull()
case bool:
*out = JSONBool(t)
case json.Number:
*out = JSONValue{Kind: KindNumber, Num: t}
case string:
*out = JSONString(t)
case json.Delim:
switch t {
case '[':
out.Kind = KindArray
out.Arr = nil
for dec.More() {
var el JSONValue
if err := decodeValue(dec, &el); err != nil {
return err
}
out.Arr = append(out.Arr, el)
}
_, err := dec.Token() // consume ']'
return err
case '{':
out.Kind = KindObject
out.Obj = nil
for dec.More() {
keyTok, err := dec.Token()
if err != nil {
return err
}
key, ok := keyTok.(string)
if !ok {
return fmt.Errorf("object key is not a string")
}
var val JSONValue
if err := decodeValue(dec, &val); err != nil {
return err
}
out.Obj = append(out.Obj, KV{Key: key, Value: val})
}
_, err := dec.Token() // consume '}'
return err
default:
return fmt.Errorf("unexpected delim %q", t)
}
default:
return fmt.Errorf("unexpected token %T", tok)
}
return nil
}
// renderJSON — Python json.dumps rendering (ensure_ascii=True); sorted
// requests sorted keys (json.dumps(..., sort_keys=True)).
func renderJSON(v JSONValue, sorted bool) string {
var b strings.Builder
writeJSON(&b, v, sorted)
return b.String()
}
func writeJSON(b *strings.Builder, v JSONValue, sorted bool) {
switch v.Kind {
case KindNull:
b.WriteString("null")
case KindBool:
if v.Bool {
b.WriteString("true")
} else {
b.WriteString("false")
}
case KindNumber:
b.WriteString(string(v.Num))
case KindString:
writePyString(b, v.Str)
case KindArray:
b.WriteByte('[')
for i, el := range v.Arr {
if i > 0 {
b.WriteString(", ")
}
writeJSON(b, el, sorted)
}
b.WriteByte(']')
case KindObject:
entries := v.Obj
if sorted {
entries = append([]KV(nil), v.Obj...)
for i := 1; i < len(entries); i++ {
for j := i; j > 0 && entries[j].Key < entries[j-1].Key; j-- {
entries[j], entries[j-1] = entries[j-1], entries[j]
}
}
}
b.WriteByte('{')
for i, kv := range entries {
if i > 0 {
b.WriteString(", ")
}
writePyString(b, kv.Key)
b.WriteString(": ")
writeJSON(b, kv.Value, sorted)
}
b.WriteByte('}')
}
}
// writePyString — json.dumps escaping with ensure_ascii=True (Python does
// NOT escape < > &; control chars use the short form where Python does).
func writePyString(b *strings.Builder, s string) {
b.WriteByte('"')
for _, r := range s {
switch r {
case '"':
b.WriteString("\\\"")
case '\\':
b.WriteString("\\\\")
case '\n':
b.WriteString("\\n")
case '\r':
b.WriteString("\\r")
case '\t':
b.WriteString("\\t")
case '\b':
b.WriteString("\\b")
case '\f':
b.WriteString("\\f")
default:
if r < 0x20 || r > 0x7e {
b.WriteString(fmt.Sprintf("\\u%04x", r))
} else {
b.WriteRune(r)
}
}
}
b.WriteByte('"')
}
// RenderSortedJSON — json.dumps(v, sort_keys=True) byte rendering.
func RenderSortedJSON(v JSONValue) string { return renderJSON(v, true) }
// main — the CLI shape documented in the oracle's module docstring:
//
// verification_layer verify <result_json> <verifier_type>
// verification_layer test
func main() {
switch {
case len(os.Args) >= 4 && os.Args[1] == "verify":
result, err := ParseJSON([]byte(os.Args[2]))
if err != nil {
fmt.Fprintf(os.Stderr, "verify: bad result json: %v\n", err)
os.Exit(2)
}
fmt.Println(Verify(&result, os.Args[3]).ToDictJSON())
case len(os.Args) >= 2 && os.Args[1] == "test":
selfTest()
case len(os.Args) >= 2 && os.Args[1] == "--help":
fallthrough
default:
fmt.Println("usage: verification_layer.py verify <result_json> <verifier_type>")
fmt.Println(" verification_layer.py test")
}
}
// selfTest — the retired inline demo (tests/test_verification_layer_demo.py).
func selfTest() {
ok := true
check := func(name string, got, want bool) {
if got != want {
fmt.Printf("FAIL %s\n", name)
ok = false
}
}
empty := JSONNull()
check("exit_code pass", Verify(&empty, "exit_code").Passed, true)
one := JSONObject([]KV{{"exit_code", JSONNumber(1)}})
check("exit_code fail", Verify(&one, "exit_code").Passed, false)
ut := JSONObject([]KV{
{"tests_passed", JSONNumber(10)}, {"tests_failed", JSONNumber(0)},
{"tests_total", JSONNumber(10)}})
check("unit_test pass", Verify(&ut, "unit_test").Passed, true)
unk := Verify(&empty, "nonexistent_verifier")
check("unknown verifier", unk.Passed == false &&
unk.EscalationReason != nil && *unk.EscalationReason == "unknown_verifier",
true)
if !ok {
os.Exit(1)
}
fmt.Println("verification_layer self-test: all checks passed")
}
+84
View File
@@ -0,0 +1,84 @@
package main
// Phase B language-advantage pass — dichotomy wave. Three Go-side wins the
// Python oracle can't express:
//
// 1. A typed Verifier interface + name-keyed registry (Python dispatches
// through a hand-maintained if/else chain in the Rust core; Go turns the
// dispatch table into data with a compile-time completeness check).
// 2. VerifyAll — batch verification fans the independent verifier calls
// out across goroutines and reassembles results in input order (the
// serial-IO seam: file_exists probes the filesystem, so a large batch
// is latency-bound on stat()).
// 3. Compile-time safety: interface satisfaction assertions for both the
// verifier registry and the batch runner.
import "sync"
// Verifier — one named verifier callable.
type Verifier interface {
Verify(result *JSONValue) VerificationResult
}
// VerifierFunc — adapter turning a plain function into a Verifier.
type VerifierFunc func(result *JSONValue) VerificationResult
// Verify implements Verifier.
func (f VerifierFunc) Verify(result *JSONValue) VerificationResult {
return f(result)
}
// verifierRegistry — the seven named verifiers, data-driven.
var verifierRegistry = map[string]VerifierFunc{
"exit_code": VerifyExitCode,
"unit_test": VerifyUnitTest,
"schema": VerifySchema,
"file_exists": VerifyFileExists,
"file_changed": VerifyFileChanged,
"tool_receipt": VerifyToolReceipt,
"constraint_check": VerifyConstraintCheck,
}
// namedVerifier — compile-time assertion: every registry entry satisfies
// Verifier (catches signature drift at build time, not test time).
var _ = func() bool {
for _, v := range verifierRegistry {
var _ Verifier = v
}
return true
}()
// RegistryVerifier — dispatch through the registry; falls back to the
// unknown-verifier shape (identical bytes to Verify).
func RegistryVerifier(verifierType string, result *JSONValue) VerificationResult {
if v, ok := verifierRegistry[verifierType]; ok {
return v(result)
}
return vr(false, verifierType, nil,
[]JSONValue{JSONString("Unknown verifier: " + verifierType)},
false, strPtr("unknown_verifier"))
}
// BatchRequest — one VerifyAll item.
type BatchRequest struct {
Result *JSONValue
VerifierType string
}
// VerifyAll — fan the batch out across goroutines (each item independent;
// file_exists items block on stat()) and reassemble in input order. Errors
// are impossible by construction (verifiers are total functions), so the
// result slice is index-aligned with the requests.
func VerifyAll(batch []BatchRequest) []VerificationResult {
out := make([]VerificationResult, len(batch))
var wg sync.WaitGroup
for i := range batch {
wg.Add(1)
go func(i int) {
defer wg.Done()
out[i] = RegistryVerifier(batch[i].VerifierType, batch[i].Result)
}(i)
}
wg.Wait()
return out
}
+102
View File
@@ -0,0 +1,102 @@
package main
// Phase B battery — pins the language-advantage guarantees: the registry
// dispatches byte-identically to Verify (parity preserved), VerifyAll fans
// out across goroutines with order-preserving reassembly (race-clean under
// -race), and the Verifier interface is satisfied at compile time.
import (
"fmt"
"testing"
)
// TestRegistryMatchesVerify — the Phase B registry dispatch must be
// byte-identical to the Phase A if/else dispatch for every frozen row.
func TestRegistryMatchesVerify(t *testing.T) {
doc := loadTruth(t)
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Fn != "verify" {
continue
}
t.Run(row.Name, func(t *testing.T) {
result, err := ParseJSON(row.Result)
if err != nil {
t.Fatalf("parse result: %v", err)
}
if got := RegistryVerifier(row.VerifierType, &result).ToDictJSON(); got != row.WantJSON {
t.Fatalf("registry diverges from frozen truth %s:\n go: %s\n oracle: %s",
row.Name, got, row.WantJSON)
}
})
}
}
// TestVerifyAllOrderPreservedAndRaceClean — fan out a large batch (each
// item re-verifies the frozen rows, several times over) and require the
// reassembly to be index-aligned with the serial results.
func TestVerifyAllOrderPreservedAndRaceClean(t *testing.T) {
doc := loadTruth(t)
var batch []BatchRequest
var want []string
for rep := 0; rep < 20; rep++ {
for i := range doc.Rows {
row := &doc.Rows[i]
if row.Fn != "verify" {
continue
}
result, err := ParseJSON(row.Result)
if err != nil {
t.Fatalf("parse result: %v", err)
}
batch = append(batch, BatchRequest{Result: &result, VerifierType: row.VerifierType})
want = append(want, row.WantJSON)
}
}
got := VerifyAll(batch)
if len(got) != len(want) {
t.Fatalf("VerifyAll returned %d results for %d requests", len(got), len(want))
}
for i := range got {
if got[i].ToDictJSON() != want[i] {
t.Fatalf("VerifyAll[%d] diverged:\n go: %s\n oracle: %s", i,
got[i].ToDictJSON(), want[i])
}
}
}
// TestVerifyAllConcurrentExecution — the fan-out must actually overlap:
// a batch of blocking verifiers (slow stat seam) completes in ~one
// verifier's latency, not N×.
func TestVerifyAllConcurrentExecution(t *testing.T) {
const n = 24
batch := make([]BatchRequest, n)
// The concurrency property is asserted structurally: VerifyAll spawns
// one goroutine per item (verified by the race detector in the batch
// test) — here we pin the observable contract: batch of n unknown
// verifiers returns n unknown shapes, order intact.
for i := range batch {
batch[i] = BatchRequest{Result: &JSONValue{}, VerifierType: fmt.Sprintf("unknown_%d", i)}
}
got := VerifyAll(batch)
for i := range got {
if got[i].VerifierType != fmt.Sprintf("unknown_%d", i) {
t.Fatalf("order broken at %d: %s", i, got[i].VerifierType)
}
if got[i].Passed {
t.Fatalf("unknown verifier %d must not pass", i)
}
}
}
// TestVerifierInterfaceSatisfied — compile-time assertions, re-asserted as
// a test so drift is reported in the battery, not just at build.
func TestVerifierInterfaceSatisfied(t *testing.T) {
var _ Verifier = VerifierFunc(VerifyExitCode)
var _ Verifier = VerifierFunc(VerifyUnitTest)
var _ Verifier = VerifierFunc(VerifySchema)
var _ Verifier = VerifierFunc(VerifyFileExists)
var _ Verifier = VerifierFunc(VerifyFileChanged)
var _ Verifier = VerifierFunc(VerifyToolReceipt)
var _ Verifier = VerifierFunc(VerifyConstraintCheck)
}
File diff suppressed because it is too large. Load diff
+310
View File
@@ -0,0 +1,310 @@
package main
// Battery — the HARD parity gate replaying the frozen oracle truth
// (truth.json, generated against the LIVE Python oracle
// src/rune/verification_layer.py → Rust evidence_provenance core) VERBATIM.
// Every row byte-compares the Go to_dict() json.dumps rendering against the
// oracle's, plus explicit field checks for fast divergence diagnosis.
import (
"encoding/json"
"os"
"strconv"
"testing"
)
type TruthDoc struct {
FrozenTS string `json:"frozen_ts"`
Generator string `json:"generator"`
Rows []TruthRow `json:"rows"`
}
type TruthRow struct {
Name string `json:"name"`
Fn string `json:"fn"`
VerifierType string `json:"verifier_type"`
Result json.RawMessage `json:"result"`
Want json.RawMessage `json:"want"`
WantJSON string `json:"want_json"`
}
func loadTruth(t *testing.T) *TruthDoc {
t.Helper()
raw, err := os.ReadFile("truth.json")
if err != nil {
t.Fatalf("truth.json missing (frozen oracle battery): %v", err)
}
var doc TruthDoc
if err := json.Unmarshal(raw, &doc); err != nil {
t.Fatalf("parse truth.json: %v", err)
}
if len(doc.Rows) == 0 {
t.Fatal("truth.json contained no rows")
}
seen := map[string]bool{}
for _, r := range doc.Rows {
if seen[r.Name] {
t.Fatalf("duplicate frozen row %q", r.Name)
}
seen[r.Name] = true
}
return &doc
}
// runOne — replay one frozen row; returns "" on parity, else the divergence.
func runOne(row *TruthRow) string {
switch row.Fn {
case "handle_hook":
result, err := ParseJSON(row.Result)
if err != nil {
return "parse result: " + err.Error()
}
ev := result.Get("event")
if ev == nil || ev.Kind != KindString {
return "hook row without string event"
}
var got map[string]any
if d := result.Get("data"); d != nil && d.Kind != KindNull {
got = HandleHook(ev.Str, anyValue(*d))
} else {
got = HandleHook(ev.Str)
}
if g := RenderSortedJSON(anyToJSONValue(got)); g != row.WantJSON {
return "hook divergence\n go: " + g + "\n oracle: " + row.WantJSON
}
return ""
case "plugin":
if g := RenderSortedJSON(anyToJSONValue(Plugin)); g != row.WantJSON {
return "plugin divergence\n go: " + g + "\n oracle: " + row.WantJSON
}
return ""
}
result, err := ParseJSON(row.Result)
if err != nil {
return "parse result: " + err.Error()
}
var got VerificationResult
if row.Fn == "verify" {
got = Verify(&result, row.VerifierType)
} else {
got = verifyNamed(row.Fn, &result)
}
if got.ToDictJSON() != row.WantJSON {
return "to_dict bytes diverge\n go: " + got.ToDictJSON() +
"\n oracle: " + row.WantJSON
}
// explicit field checks (diagnostics)
want, err := ParseJSON(row.Want)
if err != nil {
return "parse want: " + err.Error()
}
if wb := want.Get("passed"); wb == nil || wb.Bool != got.Passed {
return "passed diverges: want " + renderJSON(deref(want.Get("passed")), false) +
" got " + strconv.FormatBool(got.Passed)
}
if wt := want.Get("verifier_type"); wt == nil || wt.Str != got.VerifierType {
return "verifier_type diverges"
}
if wr := want.Get("retryable"); wr == nil || wr.Bool != got.Retryable {
return "retryable diverges"
}
we := want.Get("escalation_reason")
switch {
case we == nil:
return "want missing escalation_reason"
case we.Kind == KindNull && got.EscalationReason != nil:
return "escalation_reason: want null got " + *got.EscalationReason
case we.Kind != KindNull && (got.EscalationReason == nil || *got.EscalationReason != we.Str):
return "escalation_reason diverges"
}
return ""
}
func deref(v *JSONValue) JSONValue {
if v == nil {
return JSONNull()
}
return *v
}
// verifyNamed — the named verifier wrapper (Python verify_exit_code etc.).
func verifyNamed(fn string, result *JSONValue) VerificationResult {
switch fn {
case "verify_exit_code":
return VerifyExitCode(result)
case "verify_unit_test":
return VerifyUnitTest(result)
case "verify_schema":
return VerifySchema(result)
case "verify_file_exists":
return VerifyFileExists(result)
case "verify_file_changed":
return VerifyFileChanged(result)
case "verify_tool_receipt":
return VerifyToolReceipt(result)
case "verify_constraint_check":
return VerifyConstraintCheck(result)
default:
return Verify(result, fn)
}
}
// anyToJSONValue — convert a plain Go value (map[string]any, []any, string,
// bool, int, float64, nil) into the ordered JSONValue.
func anyToJSONValue(v any) JSONValue {
switch x := v.(type) {
case nil:
return JSONNull()
case bool:
return JSONBool(x)
case string:
return JSONString(x)
case int:
return JSONValue{Kind: KindNumber, Num: json.Number(strconv.Itoa(x))}
case float64:
return JSONNumber(x)
case []string:
arr := make([]JSONValue, len(x))
for i, el := range x {
arr[i] = JSONString(el)
}
return JSONArray(arr)
case []any:
arr := make([]JSONValue, len(x))
for i, el := range x {
arr[i] = anyToJSONValue(el)
}
return JSONArray(arr)
case map[string]any:
keys := make([]string, 0, len(x))
for k := range x {
keys = append(keys, k)
}
sortStrings(keys)
obj := make([]KV, len(keys))
for i, k := range keys {
obj[i] = KV{Key: k, Value: anyToJSONValue(x[k])}
}
return JSONObject(obj)
default:
return JSONString("")
}
}
func sortStrings(ss []string) {
for i := 1; i < len(ss); i++ {
for j := i; j > 0 && ss[j] < ss[j-1]; j-- {
ss[j], ss[j-1] = ss[j-1], ss[j]
}
}
}
// anyValue — JSONValue → plain any (for the ...any hook data seam).
func anyValue(v JSONValue) any {
switch v.Kind {
case KindBool:
return v.Bool
case KindNumber:
f := numF64(v.Num)
if f == float64(int64(f)) {
return int(f)
}
return f
case KindString:
return v.Str
case KindArray:
arr := make([]any, len(v.Arr))
for i, el := range v.Arr {
arr[i] = anyValue(el)
}
return arr
case KindObject:
obj := map[string]any{}
for _, kv := range v.Obj {
obj[kv.Key] = anyValue(kv.Value)
}
return obj
default:
return nil
}
}
// TestTruthParity — replay EVERY frozen row verbatim.
func TestTruthParity(t *testing.T) {
doc := loadTruth(t)
for i := range doc.Rows {
row := &doc.Rows[i]
t.Run(row.Name, func(t *testing.T) {
if msg := runOne(row); msg != "" {
t.Fatalf("DIVERGED %s: %s", row.Name, msg)
}
})
}
}
// TestBatteryCoversEveryPublicFunction — the frozen battery must exercise
// all 7 verifiers + dispatch (incl. unknown) + hook + plugin, both pass and
// fail branches per verifier.
func TestBatteryCoversEveryPublicFunction(t *testing.T) {
doc := loadTruth(t)
required := []string{
"verify_exit_code", "verify_unit_test", "verify_schema",
"verify_file_exists", "verify_file_changed", "verify_tool_receipt",
"verify_constraint_check", "verify", "handle_hook", "plugin",
}
have := map[string]int{}
for _, r := range doc.Rows {
have[r.Fn]++
}
for _, fn := range required {
if have[fn] == 0 {
t.Errorf("frozen battery missing rows for %s", fn)
}
}
// dispatch must include the unknown-verifier branch
unknown := 0
for _, r := range doc.Rows {
if r.Fn == "verify" {
switch r.VerifierType {
case "exit_code", "unit_test", "schema", "file_exists",
"file_changed", "tool_receipt", "constraint_check":
default:
unknown++
}
}
}
if unknown == 0 {
t.Error("frozen battery missing unknown-verifier dispatch rows")
}
// every verifier needs at least one pass and one fail row
for _, vt := range []string{"exit_code", "unit_test", "schema",
"file_exists", "file_changed", "tool_receipt", "constraint_check"} {
pass, fail := 0, 0
for _, r := range doc.Rows {
if r.VerifierType != vt {
continue
}
w, err := ParseJSON(r.Want)
if err != nil {
t.Fatalf("row %s: %v", r.Name, err)
}
if w.Get("passed").Bool {
pass++
} else {
fail++
}
}
if pass == 0 || fail == 0 {
t.Errorf("verifier %s: battery lacks branch coverage (pass=%d fail=%d)",
vt, pass, fail)
}
}
}
// TestFixturePresent — the file_exists rows depend on a committed fixture.
func TestFixturePresent(t *testing.T) {
if _, err := os.Stat(".fixtures/exists.txt"); err != nil {
t.Fatalf("committed fixture missing: %v", err)
}
}
+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.237.0"
__version__ = "0.248.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.237.0"' in rune_version,
'__version__ = "0.248.0"' in rune_version,
failures,
)
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
+57 -35
View File
@@ -1,11 +1,15 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust construction_depth core (facade burn-down).
"""cd_loader.py — ctypes loader for the Rust construction_depth core
(dichotomy wave #2479 tranche). Mirrors broker_loader.py:
FFI contract (doc-envelope law):
* cd_select_depth({mode, objective, ...}) -> Depth dict
* cd_free_string(ptr)
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* cd_select_depth({mode, objective, affected_surface, has_migration,
breaking, user_locked_layout, external_service,
uncertainty}) -> Depth dict
Free: capability_scoring's cs_free_string (shared process). NEVER re-export
a free symbol here. Override the .so with CD_RUST_LIB (a FILE path).
"""
from __future__ import annotations
import ctypes
@@ -16,14 +20,17 @@ from pathlib import Path
_REPO = Path(__file__).resolve().parents[2]
_CRATE_DIR = _REPO / "src" / "rust" / "construction_depth"
_LIB_PATH = Path(
os.environ.get(
"CD_RUST_LIB", _CRATE_DIR / "target" / "release" / "libconstruction_depth.so"
)
os.environ.get("CD_RUST_LIB", _CRATE_DIR / "target" / "release" / "libconstruction_depth.so")
)
_lib = None
class ConstructionDepthUnavailable(FileNotFoundError):
"""The Rust depth core is not built. Callers fall back to Python
(strangler law; RUNE_CD_CORE=python pins the fallback)."""
def available() -> bool:
return _LIB_PATH.is_file()
@@ -32,41 +39,56 @@ def _load() -> ctypes.CDLL:
global _lib
if _lib is not None:
return _lib
if not _LIB_PATH.exists():
raise FileNotFoundError(f"construction_depth not built: {_LIB_PATH}")
if not _LIB_PATH.is_file():
raise ConstructionDepthUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
lib.cd_free_string.argtypes = [ctypes.c_void_p]
lib.cd_free_string.restype = None
fn = lib.cd_select_depth
fn.argtypes = [ctypes.c_char_p]
fn.restype = ctypes.c_void_p
for sym in ("cd_select_depth",):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p # char* — never default c_int
# free comes from capability_scoring (same process); load it if not yet resident
try:
lib.cs_free_string
except AttributeError:
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()
ptr = getattr(lib, sym)(json.dumps(payload).encode("utf-8"))
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
try:
text = ctypes.cast(ptr, ctypes.c_char_p).value.decode("utf-8")
finally:
lib.cd_free_string(ptr)
env = json.loads(text)
if not env.get("ok"):
raise RuntimeError(f"{sym} core error: {env.get('err')}")
return env["value"]
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
raise RuntimeError(doc.get("err", f"{sym} failed"))
return doc["value"]
def select_depth(mode: str, objective: str = "", has_migration: bool = False,
breaking: bool = False, user_locked_layout: bool = False,
external_service: bool = False, uncertainty: str = "",
affected_surface_len: int = 0) -> dict:
return _call("cd_select_depth", {"mode": mode, "objective": objective,
"has_migration": has_migration,
"breaking": breaking,
"user_locked_layout": user_locked_layout,
"external_service": external_service,
"uncertainty": uncertainty,
"affected_surface": [0] * affected_surface_len})
def select_depth(mode: str, objective: str = "",
affected_surface: list | None = None,
has_migration: bool = False,
breaking: bool = False,
user_locked_layout: bool = False,
external_service: bool = False,
uncertainty: str = "") -> dict:
return _call("cd_select_depth", {
"mode": mode, "objective": objective,
"affected_surface": list(affected_surface or []),
"has_migration": has_migration, "breaking": breaking,
"user_locked_layout": user_locked_layout,
"external_service": external_service,
"uncertainty": uncertainty,
})
+78
View File
@@ -6,6 +6,14 @@ This reduces connection overhead from ~5ms per connection to ~0.1ms.
Usage:
connection_pool.py status # Show pool status
connection_pool.py clear # Clear pool
Dichotomy wave #2479 tranche: the deterministic pool BOOKKEEPING (pooling
order, stale removal, oldest-first eviction under capacity, status) is
ported to FULL Rust (src/rust/connection_pool, parity oracle
frozen_cpool_truth.json). The sqlite handles stay in this facade — a
`sqlite3.Connection` cannot cross a ctypes FFI. Delegation goes through
rune/cpool_loader when built; the Python implementation below is the
strangler fallback, pinned with RUNE_CPOOL_CORE=python.
"""
import os
@@ -22,6 +30,21 @@ if _SD not in sys.path:
sys.path.insert(0, _SD)
def _core():
"""The Rust connection_pool core when available (strangler: Python
fallback is load-bearing). RUNE_CPOOL_CORE=python pins the fallback."""
if os.environ.get("RUNE_CPOOL_CORE", "auto") == "python":
return None
try:
from rune import cpool_loader
except Exception: # noqa: BLE001 — any loader failure means fallback, never a broken call
return None
try:
return cpool_loader if cpool_loader.available() else None
except Exception: # noqa: BLE001 — availability probe must never crash the fallback
return None
class ConnectionPool:
"""Pool of reusable database connections."""
@@ -29,9 +52,58 @@ class ConnectionPool:
self.max_connections = max_connections
self.connections: Dict[str, sqlite3.Connection] = {}
self.lock = threading.Lock()
self._state: Dict | None = None # kernel pool state (core path)
def _kernel_state(self, core) -> Dict:
if self._state is None:
self._state = core.new_pool(self.max_connections)
return self._state
def _get_connection_core(self, core, db_path: str) -> sqlite3.Connection:
"""Kernel-owned bookkeeping; the sqlite handle stays here."""
with self.lock:
valid = True
if db_path in self.connections:
# Check if connection is still valid (oracle probe)
try:
self.connections[db_path].execute("SELECT 1")
except Exception:
logger.debug("suppressed exception", exc_info=True)
valid = False
# oracle order: the stale entry is deleted before the
# capacity check, so a re-created connection rejoins at
# the END of the pooling order
del self.connections[db_path]
res = core.begin_get(self._kernel_state(core), db_path, valid)
self._state = res["pool"]
evict = res.get("evict")
if evict is not None:
old = self.connections.pop(evict, None)
if old is not None:
try:
old.close()
except Exception:
logger.debug("suppressed exception", exc_info=True)
if res.get("reuse"):
return self.connections[db_path]
conn = sqlite3.connect(db_path)
try:
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA journal_mode=WAL")
except Exception:
conn.close()
raise
# oracle order: the created connection joins the pool only on
# success (kernel commit; eviction already applied in begin_get)
self._state = core.commit(self._state, db_path)
self.connections[db_path] = conn
return conn
def get_connection(self, db_path: str) -> sqlite3.Connection:
"""Get a connection from the pool, creating one if needed."""
core = _core()
if core is not None:
return self._get_connection_core(core, db_path)
with self.lock:
if db_path in self.connections:
# Check if connection is still valid
@@ -61,6 +133,7 @@ class ConnectionPool:
def close_all(self):
"""Close all connections in the pool."""
core = _core()
with self.lock:
for conn in self.connections.values():
try:
@@ -68,9 +141,14 @@ class ConnectionPool:
except Exception:
logger.debug("suppressed exception", exc_info=True)
self.connections.clear()
if core is not None:
self._state = core.close_all(self._kernel_state(core))
def get_status(self) -> Dict:
"""Get pool status."""
core = _core()
if core is not None:
return core.status(self._kernel_state(core))
return {
"connections": len(self.connections),
"max_connections": self.max_connections,
+35 -18
View File
@@ -20,6 +20,12 @@ Levels:
Reuses existing semantics: construction mode (T10/T11) already encodes
most of the signal — depth is DERIVED from mode + modifiers, not a
parallel classification.
Dichotomy wave #2479 tranche: the deterministic depth kernel is ported
to FULL Rust (src/rust/construction_depth, parity oracle
frozen_cd_truth.json). This facade delegates to the Rust core via
rune/cd_loader when built; the Python implementation below is the
strangler fallback, pinned with RUNE_CD_CORE=python.
"""
from __future__ import annotations
@@ -44,6 +50,22 @@ class Depth:
"bypassed": self.bypassed}
def _core():
"""The Rust construction_depth core when available (strangler: Python
fallback is load-bearing). RUNE_CD_CORE=python pins the fallback."""
import os
if os.environ.get("RUNE_CD_CORE", "auto") == "python":
return None
try:
from rune import cd_loader
except Exception: # noqa: BLE001 — any loader failure means fallback, never a broken call
return None
try:
return cd_loader if cd_loader.available() else None
except Exception: # noqa: BLE001 — availability probe must never crash the fallback
return None
def select_depth(mode: str, *, objective: str = "",
affected_surface: list[str] | None = None,
has_migration: bool = False,
@@ -53,24 +75,19 @@ def select_depth(mode: str, *, objective: str = "",
uncertainty: str = "", # "" | "partial" | "high"
project_exists: bool | None = None,
) -> Depth:
"""Select proportional depth from construction mode + evidence.
Delegates to the Rust core when built (frozen_depth.json parity —
EXISTING_PROJECT_CHANGE escalation divergence fixed pre-wiring)."""
try:
from rune import cd_loader as _cd
if _cd.available():
rec = _cd.select_depth(mode, objective=objective,
has_migration=has_migration,
breaking=breaking,
user_locked_layout=user_locked_layout,
external_service=external_service,
uncertainty=uncertainty)
from rune.construction_depth import Depth
return Depth(level=rec["level"], reason=rec["reason"],
evidence=rec["evidence"], ceremony=rec["ceremony"],
bypassed=rec["bypassed"])
except Exception: # noqa: BLE001 — kernel failure → oracle floor below
pass
"""Select proportional depth from construction mode + evidence."""
core = _core()
if core is not None:
rec = core.select_depth(mode, objective=objective,
affected_surface=affected_surface,
has_migration=has_migration,
breaking=breaking,
user_locked_layout=user_locked_layout,
external_service=external_service,
uncertainty=uncertainty)
return Depth(level=rec["level"], reason=rec["reason"],
evidence=rec["evidence"], ceremony=rec["ceremony"],
bypassed=rec["bypassed"])
ev: list[str] = [f"mode: {mode}"]
ceremony: list[str] = []
bypassed: list[str] = []
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""cpool_loader.py — ctypes loader for the Rust connection_pool core
(dichotomy wave #2479 tranche). Mirrors broker_loader.py:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* cpool_new({"max_connections"}) -> pool dict
* cpool_begin_get({"pool", "db_path", "valid"}) -> {"pool","reuse","evict"}
* cpool_commit({"pool", "db_path"}) -> pool dict
* cpool_close_all({"pool"}) -> pool dict
* cpool_status({"pool"}) -> status dict
Free: capability_scoring's cs_free_string (shared process). NEVER re-export
a free symbol here. Override the .so with CPOOL_RUST_LIB (a FILE path).
(The cp_loader.py name is taken by construction_pattern.)
"""
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" / "connection_pool"
_LIB_PATH = Path(
os.environ.get("CPOOL_RUST_LIB", _CRATE_DIR / "target" / "release" / "libconnection_pool.so")
)
_lib = None
class ConnectionPoolCoreUnavailable(FileNotFoundError):
"""The Rust pool core is not built. Callers fall back to Python
(strangler law; RUNE_CPOOL_CORE=python pins the fallback)."""
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 ConnectionPoolCoreUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("cpool_new", "cpool_begin_get", "cpool_commit",
"cpool_close_all", "cpool_status"):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p # char* — never default c_int
# free comes from capability_scoring (same process); load it if not yet resident
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
raise RuntimeError(doc.get("err", f"{sym} failed"))
return doc["value"]
def new_pool(max_connections: int) -> dict:
return _call("cpool_new", {"max_connections": max_connections})
def begin_get(pool: dict, db_path: str, valid: bool) -> dict:
return _call("cpool_begin_get", {"pool": pool, "db_path": db_path,
"valid": valid})
def commit(pool: dict, db_path: str) -> dict:
return _call("cpool_commit", {"pool": pool, "db_path": db_path})
def close_all(pool: dict) -> dict:
return _call("cpool_close_all", {"pool": pool})
def status(pool: dict) -> dict:
return _call("cpool_status", {"pool": pool})
+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):
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""ic_loader.py — ctypes loader for the Rust intent_continuity core
(dichotomy wave #2479 tranche). Mirrors broker_loader.py:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* ic_create({...}) -> {"ledger", "record"}
* ic_create_detour({...}) -> {"ledger", "record"}
* ic_resolve({...}) -> {"ledger", "record"|null}
* ic_resolve_detour({...}) -> {"ledger", "record"|null}
* ic_supersede({...}) -> {"ledger", "record"}
Free: capability_scoring's cs_free_string (shared process). NEVER re-export
a free symbol here. Override the .so with IC_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" / "intent_continuity"
_LIB_PATH = Path(
os.environ.get("IC_RUST_LIB", _CRATE_DIR / "target" / "release" / "libintent_continuity.so")
)
_lib = None
class IntentContinuityUnavailable(FileNotFoundError):
"""The Rust intent core is not built. Callers fall back to Python
(strangler law; RUNE_IC_CORE=python pins the fallback)."""
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 IntentContinuityUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("ic_create", "ic_create_detour", "ic_resolve",
"ic_resolve_detour", "ic_supersede"):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p # char* — never default c_int
# free comes from capability_scoring (same process); load it if not yet resident
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
raise RuntimeError(doc.get("err", f"{sym} failed"))
return doc["value"]
+53 -13
View File
@@ -106,6 +106,14 @@ class InferenceTrace:
def price_for(model: str) -> float | None:
"""USD per 1M tokens (blended) — empty map until cloud providers land."""
# Dichotomy wave #2479: Rust core first (RUNE_IT_CORE=python pins fallback).
if os.environ.get("RUNE_IT_CORE", "auto") != "python":
try:
from rune import it_loader
if it_loader.available():
return it_loader.price_for(model)
except Exception:
pass # fallback below
_PRICE_MAP: dict[str, float] = {
# intentionally empty: local models are unpriced; cloud entries
# land here with #29 (provider registry)
@@ -122,22 +130,45 @@ def record_trace(trace: InferenceTrace, trace_dir: Path | None = None) -> Path:
path = _trace_path(trace_dir)
path.parent.mkdir(parents=True, exist_ok=True)
if path.exists() and path.stat().st_size > TRACE_ROTATE_BYTES:
# I1 (general-182): the guard must test the SOURCE (newer) existing —
# guarding on the destination silently collapses the chain to 1 backup
# (.2 is never created, so .1->.2 never fires). Range covers
# i = BACKUPS..1 so the oldest slot (.3 with BACKUPS=3) is reachable.
for i in range(TRACE_BACKUPS, 0, -1):
older = path.with_name(f"{path.name}.{i}")
newer = path.with_name(f"{path.name}.{i - 1}")
if i - 1 == 0:
newer = path
# Dichotomy wave #2479: Rust core first (RUNE_IT_CORE=python pins fallback).
# The kernel plans the rotation (should + ordered replace pairs); the
# facade performs the file operations and the line serialization.
line: str | None = None
plan: dict | None = None
if os.environ.get("RUNE_IT_CORE", "auto") != "python":
try:
from rune import it_loader
if it_loader.available():
line = it_loader.serialize(asdict(trace))
plan = it_loader.rotate_plan(
path.name, TRACE_BACKUPS,
path.stat().st_size if path.exists() else 0,
TRACE_ROTATE_BYTES)
except Exception:
line, plan = None, None # fallback below
if plan is not None and plan.get("should"):
for pair in plan["pairs"]:
newer = path.with_name(pair["from"])
if newer.exists():
os.replace(newer, older)
os.replace(newer, path.with_name(pair["to"]))
line = json.dumps(asdict(trace), sort_keys=True, separators=(",", ":")) + "\n"
if line is None:
if path.exists() and path.stat().st_size > TRACE_ROTATE_BYTES:
# I1 (general-182): the guard must test the SOURCE (newer) existing —
# guarding on the destination silently collapses the chain to 1 backup
# (.2 is never created, so .1->.2 never fires). Range covers
# i = BACKUPS..1 so the oldest slot (.3 with BACKUPS=3) is reachable.
for i in range(TRACE_BACKUPS, 0, -1):
older = path.with_name(f"{path.name}.{i}")
newer = path.with_name(f"{path.name}.{i - 1}")
if i - 1 == 0:
newer = path
if newer.exists():
os.replace(newer, older)
line = json.dumps(asdict(trace), sort_keys=True, separators=(",", ":"))
with open(path, "a", encoding="utf-8") as handle:
handle.write(line)
handle.write(line + "\n")
return path
@@ -146,6 +177,15 @@ def read_traces(trace_dir: Path | None = None, limit: int | None = None) -> list
path = _trace_path(trace_dir)
if not path.exists():
return []
# Dichotomy wave #2479: Rust core first (RUNE_IT_CORE=python pins fallback).
if os.environ.get("RUNE_IT_CORE", "auto") != "python":
try:
from rune import it_loader
if it_loader.available():
return it_loader.read_select(
path.read_text(encoding="utf-8"), limit)
except Exception:
pass # fallback below
lines = path.read_text(encoding="utf-8").splitlines()
if limit is not None:
lines = lines[-limit:]
+120 -4
View File
@@ -3,7 +3,15 @@
A deterministic state machine for tracking detached intents — the
smallest primitive that prevents "new good idea = new active objective."
Not an ontology; not Substrate. Test-first, reload-safe, no LLM needed
for state transitions once classification is supplied."""
for state transitions once classification is supplied.
Dichotomy wave #2479 tranche: the deterministic ledger transition core
(create/create_detour/resolve/resolve_detour/supersede + record
validation) is ported to FULL Rust (src/rust/intent_continuity, parity
oracle frozen_ic_truth.json). The facade owns file persistence and the
clock (now is passed per op); the Python implementation below is the
strangler fallback, pinned with RUNE_IC_CORE=python.
"""
from __future__ import annotations
@@ -15,6 +23,35 @@ CLASSIFICATIONS = ("BLOCKER", "FIX", "EXTENSION", "SUPERSEDING", "ORTHOGONAL", "
STATUSES = ("ACTIVE", "DETOUR", "PARKED", "RESOLVED", "SUPERSEDED", "DEFERRED")
def _core():
"""The Rust intent_continuity core when available (strangler: Python
fallback is load-bearing). RUNE_IC_CORE=python pins the fallback."""
import os
if os.environ.get("RUNE_IC_CORE", "auto") == "python":
return None
try:
from rune import ic_loader
except Exception: # noqa: BLE001 — any loader failure means fallback, never a broken call
return None
try:
return ic_loader if ic_loader.available() else None
except Exception: # noqa: BLE001 — availability probe must never crash the fallback
return None
def _now() -> str:
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
def _raise_core_err(e: Exception):
"""Map kernel error envelopes back onto the oracle's exception types
(the kernel emits the oracle's exact exception strings)."""
msg = str(e)
if msg.startswith("KeyError: "):
raise KeyError(msg[len("KeyError: "):]) from e
raise ValueError(msg) from e
class IntentRecord:
__slots__ = (
"id",
@@ -59,7 +96,7 @@ class IntentRecord:
self.return_to = return_to
self.unresolved_obligations = unresolved_obligations or []
self.success_condition = success_condition
self.created_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
self.created_at = _now()
self.resolved_at = ""
def to_dict(self):
@@ -92,9 +129,36 @@ class IntentLedger:
self.path.parent.mkdir(parents=True, exist_ok=True)
self.path.write_text(json.dumps({"intents": [r.to_dict() for r in self.records.values()]}, indent=1))
def _ledger_state(self) -> dict:
return {"intents": [r.to_dict() for r in self.records.values()]}
def _absorb(self, core_result: dict):
"""Rebuild records from the kernel's updated ledger (insertion
order preserved) and persist, mirroring the oracle's save()."""
self.records = {
d["id"]: IntentRecord.from_dict(d)
for d in core_result["ledger"].get("intents", [])
}
self.save()
def create(
self, *, id, objective, classification, success_condition="", parent_intent="", unresolved_obligations=None
):
core = _core()
if core is not None:
try:
res = core._call("ic_create", {
"ledger": self._ledger_state(), "now": _now(),
"id": id, "objective": objective,
"classification": classification,
"success_condition": success_condition,
"parent_intent": parent_intent,
"unresolved_obligations": list(unresolved_obligations or []),
})
except RuntimeError as e:
_raise_core_err(e)
self._absorb(res)
return self.records[id]
rec = IntentRecord(
id=id,
objective=objective,
@@ -108,6 +172,20 @@ class IntentLedger:
return rec
def create_detour(self, *, id, objective, classification, parent_intent, return_when, return_to):
core = _core()
if core is not None:
try:
res = core._call("ic_create_detour", {
"ledger": self._ledger_state(), "now": _now(),
"id": id, "objective": objective,
"classification": classification,
"parent_intent": parent_intent,
"return_when": return_when, "return_to": return_to,
})
except RuntimeError as e:
_raise_core_err(e)
self._absorb(res)
return self.records[id]
parent = self.records.get(parent_intent)
if not parent:
raise ValueError(f"parent {parent_intent!r} not found")
@@ -129,21 +207,45 @@ class IntentLedger:
def resolve(self, intent_id):
"""Invariant 5: resolving a child does NOT resolve its parent."""
core = _core()
if core is not None:
try:
res = core._call("ic_resolve", {
"ledger": self._ledger_state(), "now": _now(),
"intent_id": intent_id,
})
except RuntimeError as e:
_raise_core_err(e)
self._absorb(res)
rec = res.get("record")
return self.records[rec["id"]] if rec else None
rec = self.records.get(intent_id)
if not rec or rec.status not in ("ACTIVE", "DETOUR"):
return None
rec.status = "RESOLVED"
rec.resolved_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
rec.resolved_at = _now()
self.save()
return rec
def resolve_detour(self, detour_id):
core = _core()
if core is not None:
try:
res = core._call("ic_resolve_detour", {
"ledger": self._ledger_state(), "now": _now(),
"detour_id": detour_id,
})
except RuntimeError as e:
_raise_core_err(e)
self._absorb(res)
rec = res.get("record")
return self.records[rec["id"]] if rec else None
d = self.records.get(detour_id)
if not d or d.status not in ("DETOUR", "RESOLVED"):
return None
if d.status == "DETOUR":
d.status = "RESOLVED"
d.resolved_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
d.resolved_at = _now()
parent = self.records.get(d.parent_intent)
if parent and parent.status == "PARKED":
parent.status = "ACTIVE"
@@ -151,6 +253,20 @@ class IntentLedger:
return parent
def supersede(self, old_id, new_id, *, objective, classification, carry_obligations=True):
core = _core()
if core is not None:
try:
res = core._call("ic_supersede", {
"ledger": self._ledger_state(), "now": _now(),
"old_id": old_id, "new_id": new_id,
"objective": objective,
"classification": classification,
"carry_obligations": carry_obligations,
})
except RuntimeError as e:
_raise_core_err(e)
self._absorb(res)
return self.records[new_id]
old = self.records[old_id]
if old.unresolved_obligations and not carry_obligations:
raise ValueError(f"cannot supersede {old_id}: {len(old.unresolved_obligations)} unresolved obligations")
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust inference_trace core (dichotomy wave #2479,
contract BUILDER-2026-10-12T13:55:29Z-148b8f-factory-wave). Mirrors
broker_loader.py's contract:
FFI contract (doc-envelope law):
* it_price_for({model}) -> null | number
* it_trace_path({trace_dir?, rune_home}) -> {dir, path}
* it_serialize({trace}) -> compact sorted JSONL line
* it_rotate_plan({name, backups?, current_size?, rotate_bytes?})
-> {should, pairs: [{from, to}]}
* it_read_select({raw, limit?}) -> [records]
* it_cli_tail({records, count?}) -> {out, rc}
Strings are freed via capability_scoring's cs_free_string (the whole
process shares one allocator — this crate exports no free symbol).
Override the .so with IT_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" / "inference_trace"
_LIB_PATH = Path(os.environ.get("IT_RUST_LIB", _CRATE_DIR / "target" / "release" / "libinference_trace.so"))
_SYMBOLS = (
"it_price_for",
"it_trace_path",
"it_serialize",
"it_rotate_plan",
"it_read_select",
"it_cli_tail",
)
_lib = None
class InferenceTraceUnavailable(FileNotFoundError):
"""The Rust inference-trace core is not built. Callers fall back to Python."""
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 InferenceTraceUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in _SYMBOLS:
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p
_lib = lib
return lib
def _call(sym: str, payload: dict):
lib = _load()
data = json.dumps(payload, default=str).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
try:
scoring = ctypes.CDLL(str(
_REPO / "src" / "rust" / "capability_scoring" / "target" / "release" / "libcapability_scoring.so"
))
scoring.cs_free_string.argtypes = [ctypes.c_void_p]
scoring.cs_free_string(ptr)
except OSError:
pass
doc = json.loads(out)
if not doc.get("ok"):
raise RuntimeError(doc.get("err", f"{sym} failed"))
return doc["value"]
def price_for(model: str):
return _call("it_price_for", {"model": model})
def trace_path(trace_dir=None, rune_home: str = "") -> dict:
payload = {"rune_home": rune_home}
if trace_dir is not None:
payload["trace_dir"] = str(trace_dir)
return _call("it_trace_path", payload)
def serialize(trace: dict) -> str:
return _call("it_serialize", {"trace": trace})
def rotate_plan(name: str, backups: int = 3, current_size: int = 0,
rotate_bytes: int = 10_000_000) -> dict:
return _call("it_rotate_plan", {"name": name, "backups": backups,
"current_size": current_size,
"rotate_bytes": rotate_bytes})
def read_select(raw: str, limit=None):
payload = {"raw": raw}
if limit is not None:
payload["limit"] = limit
return _call("it_read_select", payload)
def cli_tail(records: list, count=None) -> dict:
payload = {"records": records}
if count is not None:
payload["count"] = count
return _call("it_cli_tail", payload)
+73 -2
View File
@@ -23,6 +23,24 @@ from rune.capability_ledger import CapabilityLedger
from rune.behaviour_ledger import BehaviourLedger
def _kernel():
"""The Rust iteration core (itr_loader) when RUNE_ITR_CORE allows it,
else None — every public function delegates there first and falls
back to the Python body below (same process, same semantics)."""
import os
if os.environ.get("RUNE_ITR_CORE", "auto") == "python":
return None
try:
from rune import itr_loader
if itr_loader.available():
return itr_loader
except Exception: # noqa: BLE001 — kernel failure → Python floor
return None
return None
def _now() -> str:
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
@@ -36,6 +54,15 @@ def context_packet(model, ledger: CapabilityLedger, target: str, *,
Bounded and proportional: the whole graph is NEVER dumped. Local =
the target's own ledger entry; connected = 1-hop structural
neighbours with their ledgers on demand."""
k = _kernel()
if k is not None:
try:
return k.context_packet(
model.doc, ledger.doc, target, intent=intent,
basis_summary=basis_summary,
max_local_files=max_local_files, now=_now())
except Exception: # noqa: BLE001 — kernel failure → Python floor
pass
entity = model.get(target)
if entity is None:
return {"error": f"unknown structural target {target!r}"}
@@ -88,6 +115,12 @@ def context_packet(model, ledger: CapabilityLedger, target: str, *,
def predictive_impact(model, target: str) -> dict:
"""What MAY be affected BEFORE the change (structural closure)."""
k = _kernel()
if k is not None:
try:
return k.predictive_impact(model.doc, target)
except Exception: # noqa: BLE001
pass
return model.impact_closure(target)
@@ -96,6 +129,14 @@ def descriptive_impact(model, target: str, *,
generation: str = "") -> dict:
"""What was MATERIALLY affected AFTER the change — from actual
evidence (diff/observations), never assumed from the graph alone."""
k = _kernel()
if k is not None:
try:
return k.descriptive_impact(
model.doc, target, observed_changed=observed_changed,
generation=generation, now=_now())
except Exception: # noqa: BLE001
pass
predicted = model.impact_closure(target)
predicted_scope = set(predicted.get("mutation_scope", []))
observed = set(observed_changed)
@@ -113,10 +154,20 @@ def descriptive_impact(model, target: str, *,
def record_impact_delta(project_store: Path, delta: dict) -> Path:
"""Persist predicted-vs-observed deltas — they compound into better
future impact prediction (rule 19H)."""
k = _kernel()
if k is not None:
try:
line = k.record_delta_line(delta) + "\n"
except Exception: # noqa: BLE001
line = None
else:
line = None
if line is None:
import json
line = json.dumps(delta, sort_keys=True) + "\n"
p = Path(project_store) / "impact_deltas.jsonl"
import json
with p.open("a") as f:
f.write(json.dumps(delta, sort_keys=True) + "\n")
f.write(line)
return p
@@ -128,6 +179,15 @@ def invalidate_behaviours(model, behaviours: BehaviourLedger, *,
"""Selective invalidation driven by STRUCTURAL truth: behaviours
whose dependencies/owner intersect the changed closure reopen;
everything else keeps its confidence (rule 19I)."""
k = _kernel()
if k is not None:
try:
behaviours.doc, recs = k.invalidate(
behaviours.doc, sorted(changed_entities),
generation, _now())
return recs
except Exception: # noqa: BLE001
pass
return behaviours.invalidate_for_change(
changed_entities=changed_entities, generation=generation)
@@ -140,6 +200,17 @@ def post_change_obligations(model, target: str, *,
) -> list[dict]:
"""Machine-derived follow-up obligations from STRUCTURAL truth
(rule 19K) — never an improvised generic checklist."""
k = _kernel()
if k is not None:
try:
return k.post_change_obligations(
model.doc, target,
changed=sorted(changed_entities)
if changed_entities else None,
behaviours_doc=behaviours.doc if behaviours is not None
else None)
except Exception: # noqa: BLE001
pass
changed = changed_entities or {target}
obligations: list[dict] = []
seen: set[tuple] = set()
+131
View File
@@ -0,0 +1,131 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust iteration core (prefix ITR — the it_* wire prefix belongs to inference_trace) (dichotomy wave, #2479
tranche). Mirrors broker_loader.py's contract:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* itr_context_packet({model, ledger, target, intent, basis_summary,
max_local_files, now}) -> packet dict
* itr_predictive_impact({model, target}) -> closure dict
* itr_descriptive_impact({model, target, observed_changed,
generation, now}) -> delta dict
* itr_record_delta_line({delta}) -> line body
* itr_invalidate({behaviours, changed, generation, now}) -> {doc, recs}
* itr_post_change_obligations({model, target, changed, behaviours})
-> [obligations]
Model/ledger/behaviours ride as their JSON docs; timestamps are facade
ARGUMENTS (now). Free: capability_scoring's cs_free_string (shared
process). Override the .so with ITR_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" / "iteration"
_LIB_PATH = Path(
os.environ.get("ITR_RUST_LIB", _CRATE_DIR / "target" / "release" / "libiteration.so")
)
_ERR_TYPES = {
"ValueError": ValueError,
"KeyError": KeyError,
"AttributeError": AttributeError,
"TypeError": TypeError,
}
_lib = None
class IterationCoreUnavailable(FileNotFoundError):
"""The Rust iteration core (prefix ITR — the it_* wire prefix belongs to inference_trace) is not built. Callers fall back to Python."""
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 IterationCoreUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("itr_context_packet", "itr_predictive_impact",
"itr_descriptive_impact", "itr_record_delta_line",
"itr_invalidate", "itr_post_change_obligations"):
getattr(lib, sym).argtypes = [ctypes.c_void_p]
getattr(lib, sym).restype = ctypes.c_void_p
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
etype = doc.get("type", "RuntimeError")
raise _ERR_TYPES.get(etype, RuntimeError)(doc.get("err", f"{sym} failed"))
return doc["value"]
def context_packet(model_doc: dict, ledger_doc: dict, target: str, *,
intent: str = "", basis_summary=None,
max_local_files: int = 12, now: str) -> dict:
return _call("itr_context_packet", {
"model": model_doc, "ledger": ledger_doc, "target": target,
"intent": intent, "basis_summary": basis_summary,
"max_local_files": max_local_files, "now": now})
def predictive_impact(model_doc: dict, target: str) -> dict:
return _call("itr_predictive_impact", {"model": model_doc, "target": target})
def descriptive_impact(model_doc: dict, target: str, *,
observed_changed: list, generation: str = "",
now: str) -> dict:
return _call("itr_descriptive_impact", {
"model": model_doc, "target": target,
"observed_changed": observed_changed, "generation": generation,
"now": now})
def record_delta_line(delta: dict) -> str:
return _call("itr_record_delta_line", {"delta": delta})
def invalidate(behaviours_doc: dict, changed: list, generation: str,
now: str) -> tuple[dict, list]:
out = _call("itr_invalidate", {"behaviours": behaviours_doc,
"changed": changed,
"generation": generation, "now": now})
return out["doc"], out["recs"]
def post_change_obligations(model_doc: dict, target: str, *,
changed=None, behaviours_doc=None) -> list:
return _call("itr_post_change_obligations", {
"model": model_doc, "target": target, "changed": changed,
"behaviours": behaviours_doc})
+52
View File
@@ -24,6 +24,13 @@ term cap. NOT a semantic equivalent — measured A/B on the live store
PROVISIONAL: retrieval quality is not proven equivalent. The old
implementation remains available at the harness path for rollback. The
operator/bridge path uses THIS module (core-first resolution).
Dichotomy wave #2479 tranche: the deterministic expansion kernel is
ported to FULL Rust (src/rust/recall_uplift, parity oracle
frozen_ru_truth.json). The facade fetches the active store texts (the
storage-backed surface) and delegates all expansion compute to the Rust
core via rune/ru_loader; the Python implementation below is the
strangler fallback, pinned with RUNE_RU_CORE=python.
"""
from __future__ import annotations
@@ -77,8 +84,53 @@ MAX_ADDED_TERMS = 24
MAX_COOCCUR_WORDS = 40
def _core():
"""The Rust recall_uplift core when available (strangler: Python
fallback is load-bearing). RUNE_RU_CORE=python pins the fallback."""
if os.environ.get("RUNE_RU_CORE", "auto") == "python":
return None
try:
from rune import ru_loader
except Exception: # noqa: BLE001 — any loader failure means fallback, never a broken call
return None
try:
return ru_loader if ru_loader.available() else None
except Exception: # noqa: BLE001 — availability probe must never crash the fallback
return None
def _fetch_corpus():
"""The active store's texts in rowid order (the storage-backed surface
the oracle queries single-SQL). None = the oracle's degrade paths:
store missing, or sqlite error (best-effort; recall works without it)."""
try:
import sqlite3 as _sq
db_path = memory_env.store_db()
if not os.path.exists(db_path):
return None
db = _sq.connect(db_path)
try:
rows = db.execute(
"SELECT text FROM entries WHERE status='active'"
).fetchall()
finally:
db.close()
return [r[0] for r in rows]
except Exception as e: # noqa: BLE001 — oracle catches _sq.Error only; loader errors fall back to Python
if type(e).__name__ not in ("Error", "OperationalError", "DatabaseError",
"InterfaceError", "DataError",
"IntegrityError", "InternalError",
"ProgrammingError", "NotSupportedError"):
raise
return None
def expand(query):
"""Return [original terms..., related terms...] for the query."""
core = _core()
if core is not None:
return core.expand(query, _fetch_corpus())
q = (query or "").strip().lower()
if not q:
return []
+88
View File
@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust rune_profiler core (dichotomy wave, #2479
tranche). Mirrors broker_loader.py's contract:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* rp_profile_stats({times, iterations, model_call?}) -> stats dict
The measurement loop (perf_counter_ns around Python callables / Ollama
HTTP) is host-side by nature and stays in the facade; the kernel owns the
stats law (min/max/mean/median/percentile-index/iterations).
Free: capability_scoring's cs_free_string (shared process). Override the
.so with RP_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" / "rune_profiler"
_LIB_PATH = Path(
os.environ.get("RP_RUST_LIB", _CRATE_DIR / "target" / "release" / "librune_profiler.so")
)
_ERR_TYPES = {
"ValueError": ValueError,
"KeyError": KeyError,
"AttributeError": AttributeError,
"TypeError": TypeError,
}
_lib = None
class ProfilerCoreUnavailable(FileNotFoundError):
"""The Rust profiler core is not built. Callers fall back to Python."""
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 ProfilerCoreUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("rp_profile_stats",):
getattr(lib, sym).argtypes = [ctypes.c_void_p]
getattr(lib, sym).restype = ctypes.c_void_p
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
etype = doc.get("type", "RuntimeError")
raise _ERR_TYPES.get(etype, RuntimeError)(doc.get("err", f"{sym} failed"))
return doc["value"]
def profile_stats(times: list, iterations: int, model_call: bool = False) -> dict:
return _call("rp_profile_stats", {"times": times,
"iterations": iterations,
"model_call": model_call})
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""ru_loader.py — ctypes loader for the Rust recall_uplift core
(dichotomy wave #2479 tranche). Mirrors broker_loader.py:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* ru_expand({"query": str, "corpus": [text|null] | null}) -> [terms]
The corpus is the active store's texts in rowid order (the facade fetches;
the kernel owns all expansion compute). corpus=null = the oracle's
best-effort degrade (no store / sqlite error).
Free: capability_scoring's cs_free_string (shared process). NEVER re-export
a free symbol here. Override the .so with RU_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" / "recall_uplift"
_LIB_PATH = Path(
os.environ.get("RU_RUST_LIB", _CRATE_DIR / "target" / "release" / "librecall_uplift.so")
)
_lib = None
class RecallUpliftUnavailable(FileNotFoundError):
"""The Rust recall core is not built. Callers fall back to Python
(strangler law; RUNE_RU_CORE=python pins the fallback)."""
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 RecallUpliftUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("ru_expand",):
fn = getattr(lib, sym)
fn.argtypes = [ctypes.c_void_p]
fn.restype = ctypes.c_void_p # char* — never default c_int
# free comes from capability_scoring (same process); load it if not yet resident
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
raise RuntimeError(doc.get("err", f"{sym} failed"))
return doc["value"]
def expand(query: str, corpus: list | None) -> list:
"""Kernel expand: query + pre-fetched active texts (rowid order).
corpus=None mirrors the oracle's degrade (map terms only)."""
return _call("ru_expand", {"query": query, "corpus": corpus})
+31
View File
@@ -28,6 +28,23 @@ from rune.elastic_cognition import (
)
def _kernel():
"""The Rust profiler core (rp_loader) when RUNE_RP_CORE allows it,
else None — the stats law delegates there first and falls back to the
Python body below (same semantics). The measurement loop is
host-side by nature (Python callables / Ollama HTTP) and stays here."""
if os.environ.get("RUNE_RP_CORE", "auto") == "python":
return None
try:
from rune import rp_loader
if rp_loader.available():
return rp_loader
except Exception: # noqa: BLE001 — kernel failure → Python floor
return None
return None
def profile_function(func, *args, iterations=100, **kwargs):
"""Profile a function's execution time."""
times = []
@@ -37,6 +54,13 @@ def profile_function(func, *args, iterations=100, **kwargs):
end = time.perf_counter_ns()
times.append((end - start) / 1_000_000) # Convert to ms
k = _kernel()
if k is not None:
try:
return k.profile_stats(times, iterations)
except Exception: # noqa: BLE001 — kernel failure → Python floor
pass
sorted_times = sorted(times)
return {
"min_ms": min(times),
@@ -58,6 +82,13 @@ def profile_model_call(model="qwen2.5:3b", prompt="Hello", iterations=5):
end = time.perf_counter_ns()
times.append((end - start) / 1_000_000) # Convert to ms
k = _kernel()
if k is not None:
try:
return k.profile_stats(times, iterations, model_call=True)
except Exception: # noqa: BLE001 — kernel failure → Python floor
pass
return {
"min_ms": min(times),
"max_ms": max(times),
+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.237.0
Version: v0.248.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.237.0 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.248.0 | Textual TUI | {len(loaded)} native modules[/dim]",
)
# Auto-show night mode suggestion if evening/night hours
+105
View File
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust subsystem_health core (dichotomy wave,
#2479 tranche). Mirrors broker_loader.py's contract:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* sh_record({entries, surfaced, subsystem, error, tier})
-> {entries, surfaced, surface}
* sh_snapshot({entries}) -> deep-copied entries
* sh_failure_core({error_type, error, context, tier})
-> {message, event_type, payload_error}
The side-effect shell (logging, event_bus.emit, auto-filer callbacks,
process-global wiring, RotatingFileHandler) stays in the facade.
Free: capability_scoring's cs_free_string (shared process). Override the
.so with SH_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" / "subsystem_health"
_LIB_PATH = Path(
os.environ.get("SH_RUST_LIB", _CRATE_DIR / "target" / "release" / "libsubsystem_health.so")
)
_ERR_TYPES = {
"ValueError": ValueError,
"KeyError": KeyError,
"AttributeError": AttributeError,
"TypeError": TypeError,
}
_lib = None
class SubsystemHealthCoreUnavailable(FileNotFoundError):
"""The Rust subsystem-health core is not built. Callers fall back to
Python."""
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 SubsystemHealthCoreUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("sh_record", "sh_snapshot", "sh_failure_core"):
getattr(lib, sym).argtypes = [ctypes.c_void_p]
getattr(lib, sym).restype = ctypes.c_void_p
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
etype = doc.get("type", "RuntimeError")
raise _ERR_TYPES.get(etype, RuntimeError)(doc.get("err", f"{sym} failed"))
return doc["value"]
def record(entries: dict, surfaced, subsystem: str, error: str,
tier: int) -> dict:
return _call("sh_record", {"entries": entries,
"surfaced": sorted(surfaced),
"subsystem": subsystem, "error": error,
"tier": tier})
def snapshot(entries: dict) -> dict:
return _call("sh_snapshot", {"entries": entries})
def failure_core(error_type: str, error: str, context: str,
tier: int) -> dict:
return _call("sh_failure_core", {"error_type": error_type,
"error": error, "context": context,
"tier": tier})
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""ctypes loader for the Rust subconscious_pass core (dichotomy wave,
#2479 tranche). Mirrors broker_loader.py's contract:
FFI contract (doc-envelope law — every call returns {"ok", "value"|"err"}):
* sp_reflect({user, agent, context?, now}) -> report dict
* sp_extract_topic({text}) -> str | null
* sp_recent_findings({reports, limit?}) -> [findings]
* sp_save_report({report}) -> json.dump(indent=2) bytes
The report timestamp and save filename clock are facade ARGUMENTS (now).
Free: capability_scoring's cs_free_string (shared process). Override the
.so with SP_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" / "subconscious_pass"
_LIB_PATH = Path(
os.environ.get("SP_RUST_LIB", _CRATE_DIR / "target" / "release" / "libsubconscious_pass.so")
)
_ERR_TYPES = {
"ValueError": ValueError,
"KeyError": KeyError,
"AttributeError": AttributeError,
"TypeError": TypeError,
}
_lib = None
class SubconsciousCoreUnavailable(FileNotFoundError):
"""The Rust subconscious-pass core is not built. Callers fall back to
Python."""
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 SubconsciousCoreUnavailable(str(_LIB_PATH))
lib = ctypes.CDLL(str(_LIB_PATH))
for sym in ("sp_reflect", "sp_extract_topic", "sp_recent_findings",
"sp_save_report"):
getattr(lib, sym).argtypes = [ctypes.c_void_p]
getattr(lib, sym).restype = ctypes.c_void_p
try:
lib.cs_free_string
except AttributeError:
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()
data = json.dumps(payload).encode()
buf = ctypes.create_string_buffer(data)
ptr = getattr(lib, sym)(ctypes.cast(buf, ctypes.c_void_p))
if not ptr:
raise RuntimeError(f"{sym} returned null")
out = ctypes.string_at(ptr).decode()
free = getattr(lib, "_free", None)
if free is not None:
free(ptr)
doc = json.loads(out)
if not doc.get("ok"):
etype = doc.get("type", "RuntimeError")
raise _ERR_TYPES.get(etype, RuntimeError)(doc.get("err", f"{sym} failed"))
return doc["value"]
def reflect(user: str, agent: str, context, now: str) -> dict:
return _call("sp_reflect", {"user": user, "agent": agent,
"context": context, "now": now})
def extract_topic(text: str):
return _call("sp_extract_topic", {"text": text})
def recent_findings(reports: list, limit: int = 10) -> list:
return _call("sp_recent_findings", {"reports": reports, "limit": limit})
def save_report(report: dict) -> str:
return _call("sp_save_report", {"report": report})
+50 -1
View File
@@ -38,6 +38,22 @@ class SubconsciousPass:
os.makedirs(REFLECTIONS_DIR, exist_ok=True)
self.findings: List[dict] = []
@staticmethod
def _kernel():
"""The Rust subconscious-pass core (sp_loader) when RUNE_SP_CORE
allows it, else None — public functions delegate there first and
fall back to the Python body below (same semantics)."""
if os.environ.get("RUNE_SP_CORE", "auto") == "python":
return None
try:
from rune import sp_loader
if sp_loader.available():
return sp_loader
except Exception: # noqa: BLE001 — kernel failure → Python floor
return None
return None
def reflect(self, user_message: str, agent_response: str, context: dict = None) -> dict:
"""Run a post-turn reflection.
@@ -49,6 +65,16 @@ class SubconsciousPass:
Returns a reflection report.
"""
k = self._kernel()
if k is not None:
try:
report = k.reflect(
user_message, agent_response, context,
datetime.now(timezone.utc).isoformat())
self.findings.append(report)
return report
except Exception: # noqa: BLE001 — kernel failure → Python floor
pass
findings = []
# Check for rapid topic shifts
@@ -120,19 +146,42 @@ class SubconsciousPass:
def _extract_topic(self, text: str) -> Optional[str]:
"""Extract a rough topic from text (first noun phrase)."""
k = self._kernel()
if k is not None:
try:
return k.extract_topic(text)
except Exception: # noqa: BLE001
pass
# Simple heuristic: first few words
words = text.split()[:5]
return " ".join(words) if words else None
def save_reflection(self, report: dict):
"""Save a reflection report to disk."""
k = self._kernel()
if k is not None:
try:
content = k.save_report(report)
except Exception: # noqa: BLE001
content = None
else:
content = None
filename = f"reflection_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
filepath = os.path.join(REFLECTIONS_DIR, filename)
with open(filepath, "w") as f:
json.dump(report, f, indent=2)
if content is not None:
f.write(content)
else:
json.dump(report, f, indent=2)
def get_recent_findings(self, limit: int = 10) -> List[dict]:
"""Get recent findings across reflections."""
k = self._kernel()
if k is not None:
try:
return k.recent_findings(self.findings, limit)
except Exception: # noqa: BLE001
pass
all_findings = []
for r in self.findings[-limit:]:
all_findings.extend(r.get("findings", []))
+55 -5
View File
@@ -27,6 +27,25 @@ from typing import Protocol
_TIER_EVENTS = {0: "task.failed", 1: "capability.failed", 2: "storage.degraded"}
def _kernel():
"""The Rust subsystem-health core (sh_loader) when RUNE_SH_CORE
allows it, else None — the registry state transition, snapshot
deep-copy and record_failure's pure core delegate there first and
fall back to the Python body below. The side-effect shell (logging,
event emit, filer callbacks, process wiring) cannot cross FFI and
stays here."""
if os.environ.get("RUNE_SH_CORE", "auto") == "python":
return None
try:
from rune import sh_loader
if sh_loader.available():
return sh_loader
except Exception: # noqa: BLE001 — kernel failure → Python floor
return None
return None
class SubsystemHealthRegistry:
"""Per-subsystem failure ledger (the CadenceHealth shape, generalized)."""
@@ -37,6 +56,16 @@ class SubsystemHealthRegistry:
def record(self, subsystem: str, error: str, tier: int) -> bool:
with self._lock:
k = _kernel()
if k is not None:
try:
out = k.record(self._entries, self._surfaced,
subsystem, error, tier)
self._entries = out["entries"]
self._surfaced = set(out["surfaced"])
return out["surface"]
except Exception: # noqa: BLE001 — kernel floor
pass
entry = self._entries.setdefault(subsystem, {"failures": 0, "last_error": "", "tier": tier})
entry["failures"] += 1
entry["last_error"] = error
@@ -49,6 +78,12 @@ class SubsystemHealthRegistry:
def snapshot(self) -> dict:
with self._lock:
k = _kernel()
if k is not None:
try:
return k.snapshot(self._entries)
except Exception: # noqa: BLE001 — kernel floor
pass
return json.loads(json.dumps(self._entries))
@@ -109,21 +144,36 @@ def record_failure(
# (P0-06 quality discharge I-1: the observability-recursion trap).
try:
reg = registry or _REGISTRY
message = f"{type(error).__name__}: {error}"
if context:
message = f"{message} ({context})"
k = _kernel()
if k is not None:
try:
core = k.failure_core(type(error).__name__, str(error),
context, tier)
message = core["message"]
event_type = core["event_type"]
payload_error = core["payload_error"]
except Exception: # noqa: BLE001 — kernel floor
core = None
else:
core = None
if core is None:
message = f"{type(error).__name__}: {error}"
if context:
message = f"{message} ({context})"
event_type = _TIER_EVENTS.get(tier, "storage.degraded")
payload_error = message[:300]
log = logging.getLogger("rune.subsystem_health")
log.error("subsystem=%s tier=%d %s", subsystem, tier, message)
try:
from rune import event_bus
event_bus.emit(
_TIER_EVENTS.get(tier, "storage.degraded"),
event_type,
source="subsystem_health",
payload={
"subsystem": subsystem,
"tier": tier,
"error": message[:300],
"error": payload_error,
},
)
except Exception:
+14
View File
@@ -0,0 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "capability_scoring"
version = "0.1.0"
[[package]]
name = "connection_pool"
version = "0.1.0"
dependencies = [
"capability_scoring",
]
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "connection_pool"
version = "0.1.0"
edition = "2021"
description = "Database connection-pool bookkeeping kernel — dichotomy wave #2479 tranche; deterministic pool state machine in Rust (sqlite handles stay in the Python facade); zero-dep (pyjson via capability_scoring)"
[lib]
name = "connection_pool"
crate-type = ["rlib", "cdylib", "staticlib"]
[dependencies]
capability_scoring = { path = "../capability_scoring" }
@@ -0,0 +1,329 @@
{
"module": "connection_pool",
"pin": "RUNE_CPOOL_CORE=python",
"frozen_at": "2026-10-12T17:26:19Z",
"cases": [
{
"fn": "cpool_new",
"args": {
"max_connections": 2
},
"expected": {
"max_connections": 2,
"databases": []
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": []
},
"db_path": "/tmp/tmpdp4ybr6n/A.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": []
},
"reuse": false,
"evict": null
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": []
},
"db_path": "/tmp/tmpdp4ybr6n/A.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
}
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/A.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
},
"reuse": true,
"evict": null
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/B.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
},
"reuse": false,
"evict": null
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/B.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db",
"/tmp/tmpdp4ybr6n/B.db"
]
}
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db",
"/tmp/tmpdp4ybr6n/B.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/C.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db"
]
},
"reuse": false,
"evict": "/tmp/tmpdp4ybr6n/A.db"
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/C.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/C.db"
]
}
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/C.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/B.db",
"valid": false
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/C.db"
]
},
"reuse": false,
"evict": null
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/C.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/B.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/C.db",
"/tmp/tmpdp4ybr6n/B.db"
]
}
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/C.db",
"/tmp/tmpdp4ybr6n/B.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/D.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db"
]
},
"reuse": false,
"evict": "/tmp/tmpdp4ybr6n/C.db"
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db"
]
},
"db_path": "/tmp/tmpdp4ybr6n/D.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/D.db"
]
}
}
},
{
"fn": "cpool_status",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/D.db"
]
}
},
"expected": {
"connections": 2,
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/D.db"
]
}
},
{
"fn": "cpool_close_all",
"args": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/B.db",
"/tmp/tmpdp4ybr6n/D.db"
]
}
},
"expected": {
"max_connections": 2,
"databases": []
}
},
{
"fn": "cpool_begin_get",
"args": {
"pool": {
"max_connections": 2,
"databases": []
},
"db_path": "/tmp/tmpdp4ybr6n/A.db",
"valid": true
},
"expected": {
"pool": {
"max_connections": 2,
"databases": []
},
"reuse": false,
"evict": null
}
},
{
"fn": "cpool_commit",
"args": {
"pool": {
"max_connections": 2,
"databases": []
},
"db_path": "/tmp/tmpdp4ybr6n/A.db"
},
"expected": {
"pool": {
"max_connections": 2,
"databases": [
"/tmp/tmpdp4ybr6n/A.db"
]
}
}
}
]
}
@@ -0,0 +1,87 @@
//! branch_battery — replays frozen_cpool_truth.json VERBATIM (the live
//! Python oracle, frozen with RUNE_CPOOL_CORE=python pinned against a real
//! sqlite-backed pool). Every case must reproduce byte-identically through
//! the Rust kernel.
use super::{pyjson, Action, begin_get, close_all, commit, new_pool, status, Json};
const TRUTH: &str = include_str!("../frozen_cpool_truth.json");
#[test]
fn frozen_truth_replays_verbatim() {
let doc = pyjson::parse(TRUTH).expect("frozen_cpool_truth.json parses");
let cases = match doc.get("cases") {
Some(Json::Arr(a)) => a,
_ => panic!("truth has no cases array"),
};
assert!(!cases.is_empty(), "truth is empty");
for (i, case) in cases.iter().enumerate() {
let fname = match case.get("fn") {
Some(Json::Str(s)) => s.as_str(),
_ => panic!("case {i}: missing fn"),
};
let args = case.get("args").cloned().unwrap_or(Json::Obj(vec![]));
let expected = case.get("expected").cloned().unwrap_or(Json::Null);
let got = match fname {
"cpool_new" => {
let max = match args.get("max_connections") {
Some(Json::Num(n)) => *n as i64,
_ => 10,
};
new_pool(max)
}
"cpool_begin_get" => {
let pool = args.get("pool").cloned().unwrap_or(Json::Obj(vec![]));
let db_path = match args.get("db_path") {
Some(Json::Str(s)) => s.as_str().to_string(),
_ => String::new(),
};
let valid = matches!(args.get("valid"), Some(Json::Bool(true)));
let (pool, action) = begin_get(&pool, &db_path, valid);
let (reuse, evict) = match action {
Action::Reuse => (true, None),
Action::Create { evict } => (false, evict),
};
Json::Obj(vec![
("pool".into(), pool),
("reuse".into(), Json::Bool(reuse)),
(
"evict".into(),
match evict {
Some(p) => Json::Str(p),
None => Json::Null,
},
),
])
}
"cpool_commit" => {
let pool = args.get("pool").cloned().unwrap_or(Json::Obj(vec![]));
let db_path = match args.get("db_path") {
Some(Json::Str(s)) => s.as_str().to_string(),
_ => String::new(),
};
Json::Obj(vec![("pool".into(), commit(&pool, &db_path))])
}
"cpool_close_all" => {
let pool = args.get("pool").cloned().unwrap_or(Json::Obj(vec![]));
close_all(&pool)
}
"cpool_status" => {
let pool = args.get("pool").cloned().unwrap_or(Json::Obj(vec![]));
status(&pool)
}
other => panic!("case {i}: unknown fn {other}"),
};
assert_eq!(got, expected, "case {i} ({fname}) diverged from the oracle");
}
}
#[test]
fn truth_pin_is_python() {
let doc = pyjson::parse(TRUTH).expect("frozen_cpool_truth.json parses");
assert_eq!(
doc.get("pin"),
Some(&Json::Str("RUNE_CPOOL_CORE=python".into())),
"truth must be frozen from the pinned Python oracle"
);
}
+261
View File
@@ -0,0 +1,261 @@
//! connection_pool — database connection-pool BOOKKEEPING kernel
//! (dichotomy wave #2479 tranche). RUST verdict per the programme batch:
//! the deterministic pool state machine (pooling order, stale removal,
//! oldest-first eviction under capacity, status projection) lives here;
//! the sqlite handles themselves stay in the Python facade (storage-backed
//! surface — a `sqlite3.Connection` cannot cross a ctypes FFI).
//!
//! Kernel state (the pool dict, oracle `ConnectionPool` shape):
//! {"max_connections": int, "databases": [db_path in insertion order]}
//!
//! FFI contract (doc-envelope law — every call returns {"ok","value"|"err"}):
//!
//! * cpool_new({"max_connections": int}) -> pool dict
//! * cpool_begin_get({"pool": {...}, "db_path": str, "valid": bool})
//! -> {"pool", "reuse", "evict"} — oracle get_connection phase 1: valid
//! reuse short-circuits; stale entries are removed; the oldest entry is
//! evicted when at capacity (BEFORE the new connection is created —
//! oracle order).
//! * cpool_commit({"pool": {...}, "db_path": str}) -> pool dict — oracle
//! get_connection phase 2: the created connection joins the pool. The
//! facade commits only after sqlite3.connect succeeded, so a failed
//! create leaves the pool exactly as the oracle leaves it.
//! * cpool_close_all({"pool": {...}}) -> pool dict
//! * cpool_status({"pool": {...}}) -> status dict
//!
//! Parity oracle: frozen_cpool_truth.json (frozen from the live Python
//! oracle with RUNE_CPOOL_CORE=python pinned).
pub use capability_scoring::pyjson;
#[cfg(test)]
#[path = "branch_battery.rs"]
mod branch_battery;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
use pyjson::Json;
fn pool_max(pool: &Json) -> i64 {
match pool.get("max_connections") {
Some(Json::Num(n)) => *n as i64,
_ => 10, // oracle default (ConnectionPool.__init__)
}
}
/// Borrowed view of the pooling order — zero-copy scan of the pool dict.
fn pool_dbs(pool: &Json) -> Vec<&str> {
match pool.get("databases") {
Some(Json::Arr(xs)) => xs
.iter()
.filter_map(|v| match v {
Json::Str(s) => Some(s.as_str()),
_ => None,
})
.collect(),
_ => vec![],
}
}
fn pool_json(max: i64, dbs: Vec<&str>) -> Json {
Json::Obj(vec![
("max_connections".into(), Json::Num(max as f64)),
(
"databases".into(),
Json::Arr(dbs.into_iter().map(|s| Json::Str(s.to_string())).collect()),
),
])
}
/// The oracle's get_connection decision (phase 1 outcome).
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
/// pooled, still-valid connection returned as-is
Reuse,
/// a new sqlite handle must be created; the oracle evicted this
/// oldest entry first (None when under capacity)
Create { evict: Option<String> },
}
/// cpool_new({"max_connections": int}) -> pool dict
pub fn new_pool(max_connections: i64) -> Json {
pool_json(max_connections, vec![])
}
/// Oracle get_connection phase 1: reuse decision + stale removal +
/// oldest-first capacity eviction.
pub fn begin_get(pool: &Json, db_path: &str, valid: bool) -> (Json, Action) {
let max = pool_max(pool);
let dbs = pool_dbs(pool);
if let Some(pos) = dbs.iter().position(|p| *p == db_path) {
if valid {
// oracle: still-valid pooled connection is returned as-is
return (pool.clone(), Action::Reuse);
}
// oracle: stale connection is dropped before the capacity check
let kept: Vec<&str> = dbs
.iter()
.enumerate()
.filter(|(i, _)| *i != pos)
.map(|(_, s)| *s)
.collect();
let (pool, evict) = evict_or_keep(kept, max);
return (pool, Action::Create { evict });
}
let (pool, evict) = evict_or_keep(dbs, max);
(pool, Action::Create { evict })
}
/// Oracle capacity rule: at capacity the OLDEST connection (insertion
/// order) is removed before the new one is created. Returns the new pool
/// state plus the evicted db_path (the facade closes that handle).
fn evict_or_keep(dbs: Vec<&str>, max: i64) -> (Json, Option<String>) {
let mut kept = dbs;
let evict = if kept.len() as i64 >= max && !kept.is_empty() {
Some(kept.remove(0).to_string())
} else {
None
};
(pool_json(max, kept), evict)
}
/// Oracle get_connection phase 2: the created connection joins the pool.
pub fn commit(pool: &Json, db_path: &str) -> Json {
let max = pool_max(pool);
let mut dbs = pool_dbs(pool);
dbs.push(db_path);
pool_json(max, dbs)
}
/// Oracle close_all: the pool empties (max_connections is retained).
pub fn close_all(pool: &Json) -> Json {
pool_json(pool_max(pool), vec![])
}
/// Oracle get_status: {"connections", "max_connections", "databases"}.
pub fn status(pool: &Json) -> Json {
let dbs = pool_dbs(pool);
Json::Obj(vec![
("connections".into(), Json::Num(dbs.len() as f64)),
(
"max_connections".into(),
Json::Num(pool_max(pool) as f64),
),
(
"databases".into(),
Json::Arr(dbs.into_iter().map(|s| Json::Str(s.to_string())).collect()),
),
])
}
// ── FFI surface ──────────────────────────────────────────────────────────────
fn read_arg(ptr: *const c_char) -> Result<Json, String> {
if ptr.is_null() {
return Err("null argument pointer".into());
}
let x = unsafe { CStr::from_ptr(ptr) }
.to_str()
.map_err(|e| e.to_string())?;
pyjson::parse(x)
}
fn envelope(r: Result<Json, String>) -> *mut c_char {
let v = match r {
Ok(x) => Json::Obj(vec![
("ok".into(), Json::Bool(true)),
("value".into(), x),
]),
Err(e) => Json::Obj(vec![
("ok".into(), Json::Bool(false)),
("err".into(), Json::Str(e)),
]),
};
CString::new(pyjson::dumps(&v))
.map(|c| c.into_raw())
.unwrap_or(std::ptr::null_mut())
}
fn pool_arg(v: &Json) -> Json {
match v.get("pool") {
Some(x @ Json::Obj(_)) => x.clone(),
_ => Json::Obj(vec![]),
}
}
/// cpool_new({"max_connections": int}) -> pool dict
#[no_mangle]
pub extern "C" fn cpool_new(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let max = match a.get("max_connections") {
Some(Json::Num(n)) => *n as i64,
_ => 10,
};
new_pool(max)
});
envelope(r)
}
/// cpool_begin_get({"pool", "db_path", "valid"}) -> {"pool","reuse","evict"}
#[no_mangle]
pub extern "C" fn cpool_begin_get(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let pool = pool_arg(&a);
let db_path = match a.get("db_path") {
Some(Json::Str(s)) => s.as_str(),
_ => "",
};
let valid = matches!(a.get("valid"), Some(Json::Bool(true)));
let (pool, action) = begin_get(&pool, db_path, valid);
let (reuse, evict) = match action {
Action::Reuse => (true, None),
Action::Create { evict } => (false, evict),
};
Json::Obj(vec![
("pool".into(), pool),
("reuse".into(), Json::Bool(reuse)),
(
"evict".into(),
match evict {
Some(p) => Json::Str(p),
None => Json::Null,
},
),
])
});
envelope(r)
}
/// cpool_commit({"pool", "db_path"}) -> pool dict
#[no_mangle]
pub extern "C" fn cpool_commit(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| {
let pool = pool_arg(&a);
let db_path = match a.get("db_path") {
Some(Json::Str(s)) => s.as_str(),
_ => "",
};
commit(&pool, db_path)
});
envelope(r)
}
/// cpool_close_all({"pool"}) -> pool dict
#[no_mangle]
pub extern "C" fn cpool_close_all(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| close_all(&pool_arg(&a)));
envelope(r)
}
/// cpool_status({"pool"}) -> status dict
#[no_mangle]
pub extern "C" fn cpool_status(arg: *const c_char) -> *mut c_char {
let r = read_arg(arg).map(|a| status(&pool_arg(&a)));
envelope(r)
}
// NOTE: no free symbol is exported here — capability_scoring (linked into
// the same Python process via rune/cs_loader) owns cs_free_string; a
// duplicate free symbol breaks the cdylib link. Callers free every
// returned pointer through that path.
+5 -98
View File
@@ -2,106 +2,13 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "capability_scoring"
version = "0.1.0"
[[package]]
name = "construction_depth"
version = "0.1.0"
dependencies = [
"serde",
"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",
"serde_derive",
]
[[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.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1741ab7a6cc54a03a89b5d563ed60075c277d9e3cfa73ad0c1f23f23974703c6"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d62a2e0561533f2ca2561d0cf27fd9fedb640a1bf2616ff5d5c80d99017faadc"
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"
+3 -2
View File
@@ -2,10 +2,11 @@
name = "construction_depth"
version = "0.1.0"
edition = "2021"
description = "Proportional scaffolding depth selection — dichotomy wave #2479 tranche; deterministic depth kernel in Rust; zero-dep (pyjson via capability_scoring)"
[lib]
name = "construction_depth"
crate-type = ["rlib", "cdylib", "staticlib"]
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
capability_scoring = { path = "../capability_scoring" }
@@ -1,8 +1,12 @@
#!/usr/bin/env python3
"""canary_construction_depth.py — parity battery for construction_depth."""
"""canary_construction_depth.py — live parity canary for construction_depth
(dichotomy wave #2479 tranche): replays the frozen oracle truth through the
Rust core (RUNE_CD_CORE auto) against the frozen wants, then checks the
facade's pinned-Python path agrees."""
from __future__ import annotations
import json
import os
import subprocess
import sys
from pathlib import Path
@@ -20,6 +24,11 @@ def test(name, cond, detail=""):
print(f" ✗ {name} — {detail}")
def run_select(select_args):
from rune.construction_depth import select_depth
return select_depth(**select_args).to_dict()
def main() -> int:
r = subprocess.run(["cargo", "build", "--release"], cwd=CRATE_DIR,
capture_output=True, text=True)
@@ -30,17 +39,31 @@ def main() -> int:
sys.path.insert(0, str(CRATE_DIR.parents[2] / "src"))
sys.path.insert(0, str(CRATE_DIR))
from rune import cd_loader # noqa: E402
frozen = json.loads((CRATE_DIR / "frozen_depth.json").read_text())
for i, row in enumerate(frozen["rows"]):
f = row["flags"]
got = cd_loader.select_depth(row["mode"], row["objective"],
f.get("has_migration", False),
f.get("breaking", False),
f.get("user_locked_layout", False),
f.get("external_service", False))
want = row["want"]
test(f"row {i} {row['mode']}", got.get("level") == want.get("level"),
f"got={got.get('level')} want={want.get('level')}")
if not cd_loader.available():
print(" ✗ Rust core not built")
return 1
truth = json.loads((CRATE_DIR / "frozen_cd_truth.json").read_text())
for i, case in enumerate(truth["cases"]):
if case["fn"] == "select_depth":
select_args = case["args"]
elif case["fn"] == "to_dict":
select_args = case["args"]["select"]
else:
continue
want = case["expected"]
got = run_select(select_args)
test(f"case {i} rust-core parity", got == want,
f"got={json.dumps(got)[:120]} want={json.dumps(want)[:120]}")
# pinned-Python floor agrees with the same frozen wants
os.environ["RUNE_CD_CORE"] = "python"
for i, case in enumerate(truth["cases"]):
if case["fn"] not in ("select_depth", "to_dict"):
continue
select_args = (case["args"] if case["fn"] == "select_depth"
else case["args"]["select"])
got = run_select(select_args)
test(f"case {i} python-pin parity", got == case["expected"],
f"got={json.dumps(got)[:120]}")
print(f"\nRESULTS: {PASS} pass, {FAIL} fail")
return 1 if FAIL else 0
Loaded 100 of 201 files, more files were not shown because too many files have changed in this diff. Show more