Files
rune/scripts/admit_wave_compaction.py
T
Nick 834eece4d7 feat(runtime+facade): batch landing — receipt presentation, compaction, composer depth, themes, Sleight wiring, gitignore hygiene, taxonomy
- K27 receipt presentation: full decision+evidence+effect packages,
  expandable sections, UNKNOWN-never-success in every dimension state,
  spine verdicts via evidence.Evaluate (read-only import)
- 2.6-depth compaction: append-per-message (O(1) tail line, 198 bytes
  steady-state), compaction every 64 appends (512/channel hot), cool
  archives per memory-continuity contract, nothing deleted, exact-by-ID
  across compaction+restart+tamper, legacy checkpoints heal on load
- K27 composer depth: 3-line input per old TUI contracts (§2.3 history
  walk, placeholder, stash/restore), deterministic natural-language
  resolution (40+ pinned phrases), palette natural-tier + ctrl+p bind,
  Accessibility profile (keyboard-only/no-color/reduced-motion)
- K27 themes: 10 fixed Go theme tables (byte-exact from Textual 8.2.8,
  not guessed; nord/dracula-default/monokai/solarized/catppuccin/tokyo-
  night/flexoki/gruvbox), /theme command (mirrors _cmd_theme exactly),
  live-editor data shape (staged per-token preview overrides), base bg
  rgb(30,30,40), no-drift drift test anchoring Go to retiring Python
- Sleight live wiring: operator._context_broker registers seventh
  contributor 'continuity' (bucket 2, fail-closed); K16 allowlist
  amended (memory_continuity.working_set); matrices now run against
  the live road; 102 tests green
- .gitignore hygiene: directory-level traps fixed (internal/ re-includes
  .go/.json/.md only; root-anchored /index/ /journal/ /state/; fixtures
  + testdata re-included at any depth); 6-test frozen gate; unified_check
  member wired; real git add (no -f) proven on testmod/internal
- Receipts, compaction, composer, themes, sleight-wiring, hygiene all
  under ADMIT contracts (101+ contracts, 0 research-gate violations)
- main.go NOT landed (chat-live P1 wave owns it, still in flight)
2026-10-17 22:00:03 +01:00

201 lines
8.1 KiB
Python

"""Admission dispatch for wave wave-compaction: spec 2.6 depth — the
conversation checkpoint stops growing unbounded.
classify + activate + admit (the headless scaffolding entry law,
scripts/admit_wave_chat_live_p1.py pattern), admitted through the
research gate on the chain research/factory-chat-live/07-qualify.json
(verdict PROCEED — the chain's terminal QUALIFY artifact). The chain's
adversarial break #5 ("CHECKPOINT GROWTH / WRITE AMPLIFICATION",
6372 msgs / 1.7MB rewritten on EVERY append) names this exact work and
its mitigation (O(1) msg_id dedupe + append-only JSONL tail + periodic
snapshot compaction); the synthesis lists it as the phase-3 depth item.
Artifacts this wave admits: (a) incremental append — one JSONL line per
message, fsync'd, NO full checkpoint rewrite per message (the hot
checkpoint moves only on compaction); (b) the compaction policy —
compaction keeps the last N messages per channel hot and cools older
messages through the memory-continuity runtime's cooling contract
(durable per-channel checkpoint files with content digests, typed
exact-by-ID reads, cooling is attention release, never deletion); (c)
red-first frozen tests: append-per-message proof, exact-by-ID reads
across compaction, cool-path search.
"""
import json
import os
import subprocess
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
from rune import construction_activation as cact # noqa: E402
from rune import construction_admission as cadm # noqa: E402
from rune import construction_mode as cmode # noqa: E402
from rune import scaffold as sc # noqa: E402
ROOT = os.path.join(os.path.dirname(__file__), "..")
SLUG = "wave-compaction"
RESEARCH_SLUG = "factory-chat-live"
OBJECTIVE = (
"Build the spec-2.6-depth conversation checkpoint compaction: the "
"ConversationStateRepository stops rewriting the full hot checkpoint "
"on every message (6372 msgs / 1.7MB per append today, write "
"amplification compounding forever). (a) Incremental append: each "
"message appends one fsync'd JSONL line to a tail file with an O(1) "
"msg_id dedupe set (replacing the O(bucket) scan); the hot "
"checkpoint moves ONLY on compaction, never per message. "
"(b) Compaction policy, periodic: the checkpoint is rewritten from "
"the tail keeping the last N messages per channel hot while older "
"messages cool through the memory-continuity runtime's cooling "
"contract — durable per-channel cool files carrying each record "
"with a content digest, cooling releases the hot window without "
"deleting anything, and recovery replays checkpoint + tail with "
"corrupt files a typed loud error. (c) Red-first frozen tests: "
"append-per-message proof (byte-identical checkpoint across "
"appends, exactly one tail line per message), compaction preserves "
"exact-by-ID reads (every msg_id, hot and cooled, returns the exact "
"record pre- and post-restart), cool path preserves search (cool-tier "
"messages remain searchable by content with tier attribution)."
)
AFFECTED = [
"src/rune/orchestration/conversation_state.py",
"tests/test_conversation_checkpoint_compaction.py",
"docs/conversation-state.md",
"scripts/admit_wave_compaction.py",
]
EXPECTED_NEW = [
"tests/test_conversation_checkpoint_compaction.py",
"scripts/admit_wave_compaction.py",
]
def record_research_gate(marker: str) -> int:
"""Post-mint: pin the gate evidence on the contract's ext.research_gate
record so the contract resolves through the chat-live chain, never
through a registry glob. Idempotent."""
store_dir = os.path.join(ROOT, "store", "scaffold")
scaffold = sc.Scaffold(store_dir, "rune")
doc = scaffold.load()
c = scaffold.contract(doc, f"ADMIT-{SLUG}")
if c is None:
print("contract ADMIT-<slug> not found — nothing to record")
return 1
ext = c.setdefault("ext", {})
rg = ext.get("research_gate") or {}
rg.update({
"chain": f"research/{RESEARCH_SLUG}/07-qualify.json",
"verdict": "PROCEED",
"marker": marker,
})
ext["research_gate"] = rg
scaffold.commit(doc, what=f"record research_gate evidence for {SLUG}")
print("research_gate record committed on ADMIT-" + SLUG)
return 0
def main() -> int:
gate = subprocess.run(
[sys.executable, os.path.join("scripts", "check_research_gate.py"),
"admit", "--slug", SLUG, "--objective", OBJECTIVE,
"--research-slug", RESEARCH_SLUG],
capture_output=True, text=True, cwd=ROOT,
)
print(gate.stdout.strip())
if gate.returncode != 0:
print("research gate REFUSED — the law holds")
return 1
marker = ""
for line in gate.stdout.splitlines():
if line.startswith("research-gate:ALLOW"):
marker = line.strip()
break
if not marker:
print("no ALLOW marker in gate output — refusing to mint unrecorded")
return 1
store = os.path.join(ROOT, "store", "scaffold")
scaffold = sc.Scaffold(store, "rune")
md = cmode.classify_mode(
OBJECTIVE,
target_project="rune",
project_exists=True,
affected_surface=AFFECTED,
)
print("classified mode:", md.mode)
need = {
"need_id": f"need-{SLUG}",
"objective": OBJECTIVE,
"origin": "worker",
"project": "rune",
"task_ref": SLUG,
"affected_surface": AFFECTED,
"evidence_refs": [
marker,
"research/factory-chat-live/07-qualify.json",
"research/factory-chat-live/06-synthesis.json",
"research/factory-chat-live/05-adversarial.json",
"docs/openspec/changes/add-native-rune-tui/tasks.md",
"src/rune/orchestration/conversation_state.py",
],
}
act = cact.activate(md, need=need, scaffold=scaffold,
builder=SLUG)
print("activated:", act.get("activated"), act.get("mode"))
env = cadm.admit(
act,
objective=OBJECTIVE,
builder=SLUG,
affected_surface=AFFECTED,
evidence_refs=need["evidence_refs"],
origin="worker",
task_ref=SLUG,
expected_new_entities=EXPECTED_NEW,
expected_runtime_effects=[
"appending a conversation message writes one fsync'd JSONL "
"line and rewrites nothing else — the hot checkpoint file is "
"byte-identical (same inode) across appends below the "
"compaction threshold",
"msg_id dedupe is O(1) (a loaded id set), not a bucket scan",
"compaction folds the tail into the hot checkpoint keeping "
"the last N messages per channel hot; older messages cool "
"into per-channel memory-continuity cool files carrying "
"content digests — nothing is deleted",
"exact-by-ID reads (get_message) span hot, tail, and cool "
"tiers with typed statuses (FOUND_VERIFIED / "
"SOURCE_CORRUPT / NOT_FOUND_CONFIRMED) and survive restart",
"search spans hot and cool tiers with tier attribution, so "
"cooled history stays searchable",
"recovery = checkpoint + tail replay with msg_id dedupe; a "
"corrupt tail or checkpoint is a typed loud error, never a "
"silent reset",
],
verification_obligations=[
"PYTHONPATH=src python -m pytest "
"tests/test_conversation_checkpoint_compaction.py -q green "
"(red-first: RED before implementation)",
"PYTHONPATH=src python -m pytest "
"tests/test_orchestration_conversation_state.py "
"tests/test_orchestration_atomic.py "
"tests/test_orchestration_event_store.py -q green (no "
"regressions in the orchestration persistence stack)",
],
approval_ref=f"user:{SLUG} dispatch",
contract_id=f"ADMIT-{SLUG}",
project_store=store,
project_id="rune",
)
print(json.dumps(env, indent=2, default=str)[:2400])
rc = 0 if env.get("success") else 1
if record_research_gate(marker) != 0:
return 1
return rc
if __name__ == "__main__":
sys.exit(main())