Compare commits

...
6 Commits
Author SHA1 Message Date
conductor 49bd788442 chore(release): auto-bump version to 0.293.1 — earned by # (patch: converged release (push-to-master bump))
deploy / deploy (push) Skipped
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
Promotion record: (unknown)
2026-10-14 00:55:49 +01:00
Nick 7d20ef9b64 fix(scaffold): kernel-rebuild trap in close_contract — entity re-resolved after record_observed_impact
The Rust core's doc.clear()/update() semantics inside record_observed_impact
rebuild doc['entities'] with fresh objects; the previously captured entity
reference became an orphan, quality mutations silently vanished from the
store, and construction_interface.close() KeyError'd. Fires only where the
structural .so is built (coordinator checkouts, CI) — fresh worktrees took
the pure-Python path, which is why agents never saw it.

Includes the growth_pipeline salvage contract close (phase=closed, quality
persisted — proves the fix in production) + regression test.
2026-10-14 00:55:23 +01:00
Nick bc66b33ebf chore(factory): witness landed (9/0, 50039ed8); model_connect confirmed (claimed at watchdog); lanes backfilled — event_envelope/cy, stage_guards/cz 2026-10-14 00:00:49 +01:00
Nick 885f52ee22 chore(store): close witness dichotomy contract BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi (parity 50039ed8) 2026-10-13 23:40:05 +01:00
Nick cfb50b7576 chore(factory): watchdog C1 — model_connect claimed (close verified on master) 2026-10-13 23:39:22 +01:00
Nick 80249a0ac5 chore(factory): true-floor restoration — dead worktrees removed, 4 new lanes registered (construction_mode, layout_contract, builder_bridge, drift_compression) 2026-10-13 23:29:28 +01:00
26 changed files with 12382 additions and 9 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.293.0**
**Current release: v0.293.1**
**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.**
+9 -3
View File
@@ -53,6 +53,7 @@
"memory_types",
"message_graph",
"message_queue",
"model_connect",
"model_routing",
"mutation_guards",
"night_mode",
@@ -96,6 +97,7 @@
"toolchain",
"verification_layer",
"wait_guard",
"witness",
"work_manager",
"worthiness"
],
@@ -109,15 +111,19 @@
"cache": "rune-wave-ch",
"claim_audit": "rune-wave-cj",
"graph_memory": "rune-wave-ck",
"model_connect": "rune-wave-cl",
"drift_core": "rune-wave-cm",
"witness": "rune-wave-cn",
"cron_engine": "rune-wave-co",
"model_profiles": "rune-wave-cp",
"microkernel": "rune-wave-cq",
"voice_hybrid": "rune-wave-cr",
"parallel_processor": "rune-wave-cs",
"structural_model": "rune-wave-ct"
"structural_model": "rune-wave-ct",
"construction_mode": "rune-wave-cu",
"layout_contract": "rune-wave-cv",
"builder_bridge": "rune-wave-cw",
"drift_compression": "rune-wave-cx",
"event_envelope": "rune-wave-cy",
"stage_guards": "rune-wave-cz"
},
"excluded": [
"TUI-LAST modules",
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rune"
version = "0.293.0"
version = "0.293.1"
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
requires-python = ">=3.10"
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Close the #2479 dichotomy-wave witness gap contract (GO port).
Full lifecycle walk in ONE process (shared-store clobber hazard; segment
transitions can take ~60s each — do NOT split across processes). Carries
the already-pushed parity SHA as evidence:
feat cc51b181 close PARTIAL gaps — dichotomy wave
Usage: close_contract_witness.py
"""
import json
import os
import sys
from pathlib import Path
os.environ.setdefault(
"CS_RUST_LIB",
"/mnt/workdrive/rune/src/rust/capability_scoring/target/release/libcapability_scoring.so",
)
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune.construction_interface import ConstructionInterface
PARITY_SHA = "cc51b181"
EVIDENCE = f"parity {PARITY_SHA}"
iface = ConstructionInterface(builder="factory-gap-wi")
r = iface.submit_need(
"witness dichotomy gap-close (GO): name-preserving port of the 4 "
"audit-missing functions (_now, log_entry, read_log, log_stats) into "
"src/go/witness as now / logEntry / readLog / logStats with the "
"injectable clock + log-path seams, plus parity-driven defect fixes "
"to the old-era port: current 20-pattern correction table + family "
"tables, kernel-parity extract_topic (ASCII \\w runs, cap 5), "
"detect_signals kernel order (error → correction → completion → "
"drift → commitment → contradiction → preference → urgency → "
"learning) with case-insensitive family matching, rune-safe [:200] "
"error_text and context[-500:], extraction-ordered new_topics, "
"num_ctx 30720 via the _ctx_budget seam, and json.dumps byte-parity "
"log lines (separators, insertion order, ensure_ascii). Frozen-truth "
"battery (truth.json, 58 cases incl. the capital-letter is_correction "
"quirk, completion triple, half-even skip_rate 37.5→38%) generated "
"against the live oracle and verified byte-identical via "
"freeze_truth.py, embedded VERBATIM in truth_test.go "
"TestFrozenTruthReplay + seam units (deque read semantics, malformed/"
"blank lines, list-shaped signal_types, log-line bytes, rune "
"truncation); live parity sweep 59/59 with byte-compared log files "
"(scripts/check_witness_parity.py); gofmt/vet/go build clean; Python "
"oracle battery green both pins (16 live + 9 under "
"RUNE_COGNITION_CORE=python). Dichotomy audit 11/15 PARTIAL -> "
"15/15 FULL. Delivered on gitea/master: feat " + PARITY_SHA + ".",
origin="builder",
)
print("submit_need:", json.dumps(r)[:300])
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", "verifying", "closed"):
t = iface.transition(c, phase, evidence_ref=EVIDENCE)
ok = t.get("success")
print(f"transition->{phase}:", "ok" if ok else json.dumps(t)[:300])
if not ok:
sys.exit(1)
doc = iface.scaffold.load()
e = iface.scaffold.contract(doc, c)
print("FINAL PHASE:", e.get("phase") if e else "MISSING")
if not e or e.get("phase") != "closed":
sys.exit(1)
print("CLOSED", c)
+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.293.0"
__version__ = "0.293.1"
# 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.293.0"' in rune_version,
'__version__ = "0.293.1"' in rune_version,
failures,
)
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
+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.293.0
Version: v0.293.1
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.293.0 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.293.1 | Textual TUI | {len(loaded)} native modules[/dim]",
)
# Auto-show night mode suggestion if evening/night hours
+12
View File
@@ -615,6 +615,18 @@ class Scaffold:
# independent observed impact (§17): evidence items only
obs = record_observed_impact(doc, contract_id, observed_evidence or [])
# KERNEL-REBUILD TRAP (2026-10-13, found via salvage-close KeyError):
# record_observed_impact delegates to the Rust core when live — and
# the core rebuilds doc["entities"] with FRESH objects (doc.clear()/
# update semantics). The `e` captured above is then an orphaned
# reference no longer in the doc; mutations land on the orphan and
# silently never persist (observed: contract_quality absent after
# close → construction_interface.close() KeyError on re-read).
# Law: RE-RESOLVE the entity after any kernel-delegating call.
e = entity(doc, f"contract:{contract_id}")
if e is None:
raise ValueError(f"contract vanished during impact recording: {contract_id}")
# R2 Wave 1: the bucket math is factored out so the Rust engine
# (scaffold_core.close_quality) computes from the SAME gathered
# inputs — the production ledger replay is the parity oracle.
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi
**Phase:** closed · **Mode:** n/a · **Depth:** n/a
## What was built
witness dichotomy gap-close (GO): name-preserving port of the 4 audit-missing functions (_now, log_entry, read_log, log_stats) into src/go/witness as now / logEntry / readLog / logStats with the injectable clock + log-path seams, plus parity-driven defect fixes to the old-era port: current 20-pattern correction table + family tables, kernel-parity extract_topic (ASCII \w runs, cap 5), detect_signals kernel order (error → correction → completion → drift → commitment → contradiction → preference → urgency → learning) with case-insensitive family matching, rune-safe [:200] error_text and context[-500:], extraction-ordered new_topics, num_ctx 30720 via the _ctx_budget seam, and json.dumps byte-parity log lines (separators, insertion order, ensure_ascii). Frozen-truth battery (truth.json, 58 cases incl. the capital-letter is_correction quirk, completion triple, half-even skip_rate 37.5→38%) generated against the live oracle and verified byte-identical via freeze_truth.py, embedded VERBATIM in truth_test.go TestFrozenTruthReplay + seam units (deque read semantics, malformed/blank lines, list-shaped signal_types, log-line bytes, rune truncation); live parity sweep 59/59 with byte-compared log files (scripts/check_witness_parity.py); gofmt/vet/go build clean; Python oracle battery green both pins (16 live + 9 under RUNE_COGNITION_CORE=python). Dichotomy audit 11/15 PARTIAL -> 15/15 FULL. Delivered on gitea/master: feat cc51b181.
## What it connects to
(no affected surface recorded)
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 4 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- parity cc51b181
- parity cc51b181
- parity cc51b181
- parity cc51b181
@@ -0,0 +1,24 @@
# Contract BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp
**Phase:** verifying · **Mode:** n/a · **Depth:** n/a
## What was built
growth_pipeline FULL Rust port (salvage landing — cancelled-agent commits verified + pushed post-cancel; contract closed post-hoc per the scaffolding law)
## What it connects to
- `src/rune/growth_pipeline.py`
- `src/rust/growth_pipeline/`
## How to update those connections
- Open a NEW construction contract (scaffolding is absolute) scoped to the same surface.
- Evidence trail: 3 checkpoint(s) recorded on the contract entity.
- Quality at close: not recorded.
## Evidence
- builder:factory-salvage-gp
- builder:factory-salvage-gp
- builder:factory-salvage-gp
@@ -3942,3 +3942,19 @@
{"builder": "factory-gap-mconn", "detail": "BUILDER-2026-10-13T22:11:49Z-3df478-factory-gap-mconn \u2192 building", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:12:36Z", "operation": "transition"}
{"builder": "factory-gap-mconn", "detail": "BUILDER-2026-10-13T22:11:49Z-3df478-factory-gap-mconn \u2192 verifying", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:13:01Z", "operation": "transition"}
{"builder": "factory-gap-mconn", "detail": "BUILDER-2026-10-13T22:11:49Z-3df478-factory-gap-mconn \u2192 closed", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:13:24Z", "operation": "transition"}
{"builder": "factory-gap-wi", "detail": "need-2026-10-13T22:30:01Z-factory-gap-wi \u2192 REUSE", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:30:08Z", "operation": "submit_need"}
{"builder": "factory-gap-wi", "detail": "BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi \u2192 approved", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:31:12Z", "operation": "transition"}
{"builder": "factory-gap-wi", "detail": "BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi \u2192 building", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:32:13Z", "operation": "transition"}
{"builder": "factory-gap-wi", "detail": "BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi \u2192 verifying", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:33:08Z", "operation": "transition"}
{"builder": "factory-gap-wi", "detail": "BUILDER-2026-10-13T22:30:08Z-fd6e49-factory-gap-wi \u2192 closed", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T22:34:04Z", "operation": "transition"}
{"builder": "factory-salvage-gp", "detail": "need-2026-10-13T23:41:27Z-factory-salvage-gp \u2192 REUSE", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:41:31Z", "operation": "submit_need"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp \u2192 approved", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:41:48Z", "operation": "transition"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp \u2192 building", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:42:04Z", "operation": "transition"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp \u2192 verifying", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:42:19Z", "operation": "transition"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp closed", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:42:38Z", "operation": "close"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp closed", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:44:49Z", "operation": "close"}
{"builder": "factory-salvage-gp", "detail": "BUILDER-2026-10-13T22:45:00Z-gpsalv-factory-salvage-gp closed", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:45:54Z", "operation": "close"}
{"builder": "test-kernel-rebuild-trap", "detail": "need-2026-10-13T23:53:16Z-test-kernel-rebuild-trap \u2192 REUSE", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:53:20Z", "operation": "submit_need"}
{"builder": "test-kernel-rebuild-trap", "detail": "BUILDER-2099-01-01T00:00:00Z-kerneltrap-regression \u2192 approved", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:53:37Z", "operation": "transition"}
{"builder": "test-kernel-rebuild-trap", "detail": "BUILDER-2099-01-01T00:00:00Z-kerneltrap-regression \u2192 building", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:53:53Z", "operation": "transition"}
{"builder": "test-kernel-rebuild-trap", "detail": "BUILDER-2099-01-01T00:00:00Z-kerneltrap-regression \u2192 verifying", "kind": "builder_session", "mode": "rune_internal", "observed_at": "2026-10-13T23:54:10Z", "operation": "transition"}
@@ -0,0 +1,67 @@
"""Regression test: the kernel-rebuild trap in close_contract.
record_observed_impact delegates to the Rust core when the structural_store
cdylib is live — and the kernel rebuilds doc["entities"] with FRESH objects.
close_contract previously captured the entity reference BEFORE that call and
mutated the orphaned object: contract_quality vanished from the store and
construction_interface.close() KeyError'd on re-read. Only fired with the
.so built (fresh worktrees lack it — agents never saw it; the coordinator's
checkout did)."""
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from rune.structural_store import new_doc, add_entity
@pytest.fixture
def ci():
from rune.construction_interface import ConstructionInterface
import os
os.environ.setdefault(
"CS_RUST_LIB",
"/mnt/workdrive/rune/src/rust/capability_scoring/target/release/libcapability_scoring.so",
)
return ConstructionInterface(builder="test-kernel-rebuild-trap")
def test_close_contract_persists_quality_with_kernel_live(ci, tmp_path):
"""With the Rust core live (kernel-rebuild path), close_contract's
quality mutation must survive into the persisted doc."""
import os
if not Path(os.environ["CS_RUST_LIB"]).exists():
pytest.skip("capability_scoring kernel not built")
cid = "BUILDER-2099-01-01T00:00:00Z-kerneltrap-regression"
ci.submit_need(
"regression probe",
contract_id=cid,
affected_surface=["src/rust/growth_pipeline/"],
)
for phase in ("approved", "building", "verifying"):
r = ci.transition(cid, phase)
assert r.get("success"), f"transition to {phase} failed: {r}"
doc = ci.scaffold.load()
ci.scaffold.close_contract(
doc, cid,
observed_evidence=[{"type": "commit", "ref": "deadbeef"}],
scope_files=["src/rust/growth_pipeline/"],
)
ci.scaffold.commit(doc, what="regression test close")
doc2 = ci.scaffold.load()
e = [x for x in doc2["entities"] if x["id"] == f"contract:{cid}"][0]
assert "contract_quality" in e.get("ext", {}), (
"kernel-rebuild trap: quality mutation lost after "
"record_observed_impact rebuilt doc entities"
)
assert e["phase"] == "closed"
# cleanup: remove the probe contract so the shared store stays clean
doc3 = ci.scaffold.load()
doc3["entities"] = [x for x in doc3["entities"] if x["id"] != f"contract:{cid}"]
ci.scaffold.commit(doc3, what="regression test cleanup")
seg = Path(f"store/scaffold/segments/entities/contract__BUILDER-2099-01-01T00__00__00Z-kerneltrap-regression.json")
if seg.exists():
seg.unlink()
+1
View File
@@ -0,0 +1 @@
exit=0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+1
View File
@@ -0,0 +1 @@
0
+62
View File
@@ -0,0 +1,62 @@
# witness GO gap-close — verification summary (#2479, factory-gap-wi)
Worktree rune-wave-cn. Oracle: src/rune/witness.py (446 lines, 15 audit fns,
11/15 → **15/15 FULL (GO)**; programme headline 82→83 FULL after regen).
## What was ported (name-preserving)
- `_now` → `now()` with the injectable `clock` seam (Python isoformat shape:
6-digit micros when nonzero, `+00:00` offset).
- `log_entry` → `logEntry` — append-only JSONL with Python json.dumps
byte-parity (", "/": " separators, ensure_ascii, insertion key order:
timestamp, session_id, signals, reflection, signal_count).
- `read_log` → `readLog` — deque semantics (limit counts LINES), blank +
malformed lines skipped, [] on missing file.
- `log_stats` → `logStats` — 3-key zero shape without skip_rate on missing
file; skip_rate replicates Python f"{x:.0f}%" half-even rounding
(37.5→"38%", 62.5→"62%"); signal_types iterates dict keys OR list
elements (oracle parity incl. int-key coercion "1"/"2").
## Defect fixes found by parity (pre-existing divergences)
- Correction table was the RETIRED 11-pattern set → now the current 20
oracle patterns; family tables likewise.
- `is_correction` quirk preserved: patterns match AS-IS against lowercased
text, so capital-letter patterns (r"\bI (said|meant|asked)\b", …) never
fire — frozen, not fixed ("I meant the left column" → False).
- `extract_topic` was Fields+TrimRight punctuation → kernel parity:
contiguous ASCII \w runs of the lowercased text, rune-len > 3,
stopwords, cap 5 ("café résumé matters" → ["matters"]).
- `detect_signals`: kernel signal ORDER (error → correction → completion →
drift → commitment → contradiction → preference → urgency → learning);
case-INSENSITIVE family matching (kernel lowercases pattern and text —
richer than public is_correction); rune-safe [:200] error_text (was
byte-slicing); new_topics keep EXTRACTION order (was map-random).
- `witness_reflect`: num_ctx via the oracle's _ctx_budget(LOCAL_MODEL) =
30720 (was hardcoded 8192); rune-safe context[-500:]; prompt renders
signals with Python separators.
- Log path derives from RUNE_MEMORY_DIR/RUNE_HOME like memory_env (was
absent — the log family didn't exist).
## Divergences documented (not bugs)
- extract_topic under the RUNE_COGNITION_CORE=python pin: the retired
pure-Python oracle used Unicode \w; the Go port follows the kernel's
ASCII runs (the frozen authority; the _py oracle raises RuntimeError
by design when the kernel is off).
- Public is_correction vs kernel correction tables: kernel matching is
case-insensitive, the public fn is not (capital-I patterns never fire).
Both behaviors frozen separately in truth.json.
## Gates (all evidence in verification/wi-*.log, exits in wi-*.exit)
| Gate | Result | Evidence |
|---|---|---|
| truth freeze gen ×2 | 58 cases byte-identical | wi-freeze-gen.{log,exit} |
| freeze_truth --verify ×2 | OK 58 cases byte-identical vs live oracle | wi-freeze-verify{1,2}.log, wi-freeze-verify.exit |
| Go battery (truth.json embedded verbatim + seams) | ok rune/witness | wi-gotest.{log,exit} |
| Live parity (oracle vs Go binary, incl. byte-compared log files) | 59/59 match | wi-parity.{log,exit} |
| gofmt / go vet / go build ./... | clean | wi-gofmt / wi-govet / wi-gobuild |
| pytest LIVE (delegation + pinned-paths + cc_loader seam) | 16 passed | wi-pytest-live.{log,exit} |
| pytest PINNED (RUNE_COGNITION_CORE=python: pinned-paths + seam) | 9 passed | wi-pytest-pinned.{log,exit} |
| ruff (new scripts) | clean | wi-ruff.{log,exit} |