Compare commits

...
51 Commits
Author SHA1 Message Date
conductor b68f31ff0d chore(release): auto-bump version to 0.85.6 — earned by #344 (chore(hardening): 18/18 gates — EVENT_DRIVEN_CONTINUATION_COMPLETE)
Auto-version and Release / release (push) Successful in 24s
deploy / deploy (push) Successful in 2m45s
CI Pipeline / lint (push) Failing after 14m13s
CI Pipeline / unit-tests (push) Successful in 3m27s
CI Pipeline / canary (push) Successful in 34s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 17s
CI Pipeline / type-check (push) Successful in 40s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
Promotion record: #344
2026-09-18 12:28:18 +01:00
conductor dd41f15571 Merge pull request 'chore(hardening): 18/18 gates — EVENT_DRIVEN_CONTINUATION_COMPLETE' (#344) from hardening-live-proof into master
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / canary (push) Successful in 37s
CI Pipeline / documentation (push) Successful in 11s
CI Pipeline / gitea-offline (push) Successful in 20s
CI Pipeline / type-check (push) Successful in 36s
CI Pipeline / lint (push) Successful in 44s
Auto-version and Release / release (push) Successful in 21s
CI Pipeline / unit-tests (push) Successful in 3m24s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
deploy / deploy (push) Successful in 7m21s
2026-09-18 12:26:33 +01:00
conductor 57e4b8672c Merge branch 'master' into hardening-live-proof
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / canary (push) Successful in 35s
CI Pipeline / lint (push) Successful in 48s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / lint (pull_request) Successful in 39s
CI Pipeline / best-practices (pull_request) Successful in 6s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / canary (pull_request) Successful in 34s
CI Pipeline / gitea-offline (pull_request) Successful in 18s
CI Pipeline / type-check (pull_request) Successful in 33s
CI Pipeline / unit-tests (push) Successful in 3m26s
Spec gate (headless) / spec-gate (pull_request) Successful in 17s
deploy / deploy (push) Skipped
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 8s
CI Pipeline / unit-tests (pull_request) Successful in 3m29s
CI Pipeline / required-checks (pull_request) Successful in 4s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 7s
Auto-version and Release / release (pull_request) Successful in 1m1s
2026-09-18 12:20:35 +01:00
Nick 6923128f45 chore(hardening): 18/18 gates PASS, can_accept=true — EVENT_DRIVEN_CONTINUATION_COMPLETE (recomputed)
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 50s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / lint (push) Successful in 58s
Auto-label / auto-label (pull_request) Successful in 10s
CI Pipeline / gitea-offline (push) Successful in 17s
deploy / deploy (push) Skipped
CI Pipeline / type-check (push) Successful in 57s
CI Pipeline / best-practices (pull_request) Successful in 7s
CI Pipeline / canary (pull_request) Successful in 33s
CI Pipeline / lint (pull_request) Successful in 48s
CI Pipeline / type-check (pull_request) Successful in 31s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
Spec gate (headless) / spec-gate (pull_request) Successful in 19s
CI Pipeline / documentation (pull_request) Successful in 10s
CI Pipeline / unit-tests (push) Successful in 3m37s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
CI Pipeline / unit-tests (pull_request) Successful in 3m26s
CI Pipeline / required-checks (pull_request) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 6s
2026-09-18 12:13:55 +01:00
conductor 9db239fcb4 chore(release): auto-bump version to 0.85.5 — earned by #343 (docs(hardening): live proof marker (H12/H13))
Auto-version and Release / release (push) Successful in 22s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / lint (push) Successful in 40s
CI Pipeline / unit-tests (push) Successful in 3m20s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 8s
deploy / deploy (push) Successful in 2m49s
Promotion record: #343
2026-09-18 11:36:03 +01:00
conductor 658ec63627 Merge pull request 'docs(hardening): live proof marker (H12/H13)' (#343) from hardening-live-proof into master
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / canary (push) Successful in 36s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 28s
Auto-version and Release / release (push) Successful in 31s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / unit-tests (push) Successful in 3m22s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
deploy / deploy (push) Successful in 7m21s
2026-09-18 11:35:45 +01:00
Nick 427c3ac6bb docs(hardening): live proof marker (H12-H14)
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / canary (push) Successful in 33s
deploy / deploy (push) Skipped
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / lint (push) Successful in 46s
CI Pipeline / unit-tests (push) Successful in 3m17s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 4s
Auto-label / priority-gate (pull_request) Skipped
Auto-label / auto-label (pull_request) Successful in 3s
CI Pipeline / best-practices (pull_request) Successful in 15s
CI Pipeline / documentation (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 34s
CI Pipeline / lint (pull_request) Successful in 45s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
CI Pipeline / type-check (pull_request) Successful in 29s
Spec gate (headless) / spec-gate (pull_request) Successful in 20s
CI Pipeline / unit-tests (pull_request) Successful in 3m23s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 4s
Auto-version and Release / release (pull_request) Failing after 51s
2026-09-18 11:02:22 +01:00
conductor 509ec00c87 chore(release): auto-bump version to 0.85.4 — earned by #342 (fix(hardening): operation-identity authority — explicit sha end-to-end)
Auto-version and Release / release (push) Successful in 24s
CI Pipeline / lint (push) Successful in 41s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 12s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 3m17s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
deploy / deploy (push) Successful in 5m51s
Promotion record: #342
2026-09-18 10:34:26 +01:00
conductor bea523a0e3 chore(release): auto-bump version to 0.85.4 — earned by # (patch: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 26s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 14s
CI Pipeline / lint (push) Successful in 45s
CI Pipeline / unit-tests (push) Successful in 3m24s
CI Pipeline / canary (push) Successful in 29s
CI Pipeline / best-practices (push) Successful in 14s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 7m23s
Promotion record: (unknown)
2026-09-18 10:33:03 +01:00
conductor 0a15a1675d Merge pull request 'fix(hardening): operation-identity authority — explicit sha end-to-end' (#342) from hardening-authority-identity into master
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / lint (push) Successful in 51s
CI Pipeline / type-check (push) Successful in 36s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / gitea-offline (push) Successful in 24s
Auto-version and Release / release (push) Failing after 1m7s
CI Pipeline / unit-tests (push) Successful in 3m17s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Successful in 12m36s
2026-09-18 10:31:33 +01:00
Nick 81c6d1f9c6 fix(hardening): operation-identity authority — explicit sha end-to-end, paginated runs fetch, model-sha-as-hint
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / type-check (push) Successful in 30s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 21s
Auto-label / auto-label (pull_request) Successful in 23s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / canary (pull_request) Successful in 36s
CI Pipeline / type-check (pull_request) Successful in 27s
CI Pipeline / gitea-offline (pull_request) Successful in 22s
Spec gate (headless) / spec-gate (pull_request) Successful in 18s
CI Pipeline / best-practices (pull_request) Successful in 7s
CI Pipeline / lint (pull_request) Successful in 40s
CI Pipeline / unit-tests (push) Successful in 3m22s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
CI Pipeline / unit-tests (pull_request) Successful in 3m22s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 5s
Auto-version and Release / release (pull_request) Successful in 39s
Defect A root cause: Gitea runs-list page flood (scheduled merge-robot
runs push relevant SHAs past the limit=50 first page) + collect-only-
first-page pagination -> terminal commit read as pending -> parked until
deadline. FIX: _fetch_runs paginates up to 4 pages collecting all matches
before verdict.

Defect B root cause: authority_verdict spawned deploy_qualify reading
DEPLOY_SHA from ambient env. FIX: explicit --sha arg (env masked when
sha is explicit); _ci_runs_verdict/op_ci_alive take sha as parameter
only; no env read remains in the authority path.

Defect C root cause: model sha treated as lookup key — a typo derived a
ghost operation. FIX: model sha is a HINT; unresolved sha + single
pending op -> stored target used with model_sha_mismatch logged; bound
op always wins over hints. deploy_qualify gained --sha flag (env kept
for workflow backward-compat only).

Tests: H-matrix (identity, prefix collision, env staleness,
monotonicity, aggregator lag, operation-id-first) + full 2179 suite.
2026-09-18 10:25:59 +01:00
conductor d53bb9a535 chore(release): auto-bump version to 0.85.3 — earned by #341 (chore(event-driven): E13 final convergence evidence)
Auto-version and Release / release (push) Successful in 17s
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 2s
CI Pipeline / documentation (push) Successful in 2s
CI Pipeline / lint (push) Failing after 40s
CI Pipeline / canary (push) Failing after 36s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / type-check (push) Successful in 41s
CI Pipeline / unit-tests (push) Failing after 4m23s
CI Pipeline / required-checks (push) Failing after 5s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
Promotion record: #341
2026-09-18 04:28:45 +01:00
conductor 023151acb9 Merge pull request 'chore(event-driven): E13 final convergence evidence' (#341) from event-driven-gates-evidence into master
CI Pipeline / best-practices (push) Successful in 11s
Auto-version and Release / release (push) Successful in 27s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / type-check (push) Successful in 34s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / unit-tests (push) Successful in 3m24s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Successful in 6m28s
2026-09-18 04:26:47 +01:00
conductor 2da9305d96 Merge branch 'master' into event-driven-gates-evidence
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / lint (push) Successful in 44s
CI Pipeline / canary (push) Successful in 39s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / lint (pull_request) Successful in 39s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 29s
CI Pipeline / documentation (pull_request) Successful in 8s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
CI Pipeline / type-check (pull_request) Successful in 32s
deploy / deploy (push) Skipped
Spec gate (headless) / spec-gate (pull_request) Successful in 17s
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / unit-tests (push) Successful in 3m20s
CI Pipeline / required-checks (push) Successful in 3s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
CI Pipeline / unit-tests (pull_request) Successful in 3m15s
CI Pipeline / required-checks (pull_request) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 7s
Auto-version and Release / release (pull_request) Failing after 1m4s
2026-09-18 04:21:24 +01:00
Nick 2e05ea6848 chore(event-driven): E13 final convergence evidence — deployed 05f2a74/0.85.2 after CI retrigger
Auto-label / priority-gate (pull_request) Skipped
Auto-label / auto-label (pull_request) Successful in 2s
CI Pipeline / lint (pull_request) Successful in 40s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 28s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
CI Pipeline / type-check (pull_request) Successful in 30s
Spec gate (headless) / spec-gate (pull_request) Successful in 20s
CI Pipeline / unit-tests (pull_request) Successful in 3m22s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 5s
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 2s
CI Pipeline / documentation (push) Successful in 1s
CI Pipeline / lint (push) Failing after 37s
CI Pipeline / canary (push) Failing after 39s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / type-check (push) Successful in 36s
CI Pipeline / unit-tests (push) Failing after 4m13s
CI Pipeline / required-checks (push) Failing after 8s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 10s
2026-09-18 04:14:27 +01:00
Nick be161c2043 chore: retrigger CI (type-check transient on 1c5dc55; local fresh-venv ratchet PASS 447/454) 2026-09-18 04:14:27 +01:00
conductor a6539986b9 chore(release): auto-bump version to 0.85.2 — earned by # (patch: converged release (push-to-master bump))
Promotion record: (unknown)
2026-09-18 04:14:27 +01:00
conductor 8da216d155 chore(release): auto-bump version to 0.85.2 — earned by #340 (fix(event-driven): authority resilience — status-404 fallback)
Promotion record: #340
2026-09-18 04:14:27 +01:00
Nick 05f2a74c6f chore: retrigger CI (type-check transient on 1c5dc55; local fresh-venv ratchet PASS 447/454)
CI Pipeline / best-practices (push) Successful in 13s
Auto-version and Release / release (push) Successful in 28s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / canary (push) Successful in 40s
CI Pipeline / lint (push) Successful in 49s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 4s
deploy / deploy (push) Successful in 3m8s
2026-09-18 03:46:55 +01:00
conductor 1c5dc557a6 chore(release): auto-bump version to 0.85.2 — earned by # (patch: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 21s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / unit-tests (push) Successful in 3m15s
CI Pipeline / canary (push) Successful in 29s
CI Pipeline / type-check (push) Failing after 14m23s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Failing after 15m19s
Promotion record: (unknown)
2026-09-18 03:18:19 +01:00
conductor a6bccc1c5d chore(release): auto-bump version to 0.85.2 — earned by #340 (fix(event-driven): authority resilience — status-404 fallback)
Auto-version and Release / release (push) Successful in 24s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 20s
CI Pipeline / lint (push) Successful in 39s
CI Pipeline / unit-tests (push) Successful in 3m21s
CI Pipeline / canary (push) Successful in 29s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 15s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 9m17s
Promotion record: #340
2026-09-18 03:16:27 +01:00
conductor f208b5e61c Merge pull request 'fix(event-driven): authority resilience — status-404 fallback' (#340) from event-driven-continuation into master
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / lint (push) Successful in 40s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / type-check (push) Successful in 29s
Auto-version and Release / release (push) Successful in 1m6s
CI Pipeline / unit-tests (push) Successful in 3m19s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Successful in 8m22s
2026-09-18 03:15:46 +01:00
conductor aa800acbad Merge branch 'master' into event-driven-continuation
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / best-practices (pull_request) Successful in 10s
CI Pipeline / documentation (pull_request) Successful in 10s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / gitea-offline (pull_request) Successful in 18s
CI Pipeline / type-check (pull_request) Successful in 29s
CI Pipeline / lint (push) Successful in 39s
deploy / deploy (push) Skipped
CI Pipeline / type-check (push) Successful in 34s
Spec gate (headless) / spec-gate (pull_request) Successful in 12s
CI Pipeline / lint (pull_request) Successful in 37s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / unit-tests (pull_request) Successful in 3m34s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 4s
CI Pipeline / unit-tests (push) Successful in 3m23s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
Auto-version and Release / release (pull_request) Successful in 1m7s
2026-09-18 03:09:04 +01:00
Nick 30be2c96b8 chore(deps): apply regenerated lock (platformdirs 4.11.10)
CI Pipeline / lint (pull_request) Successful in 50s
CI Pipeline / canary (pull_request) Successful in 31s
CI Pipeline / documentation (pull_request) Successful in 12s
CI Pipeline / best-practices (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 18s
CI Pipeline / type-check (pull_request) Successful in 32s
Spec gate (headless) / spec-gate (pull_request) Successful in 34s
CI Pipeline / unit-tests (pull_request) Successful in 3m28s
CI Pipeline / required-checks (pull_request) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 7s
deploy / deploy (push) Skipped
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 1s
CI Pipeline / lint (push) Failing after 41s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / canary (push) Failing after 41s
CI Pipeline / type-check (push) Successful in 39s
CI Pipeline / unit-tests (push) Failing after 3m49s
CI Pipeline / required-checks (push) Failing after 5s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 10s
2026-09-18 02:59:55 +01:00
Nick ca00be8259 chore(deps): re-lock requirements-ci.txt (upstream platformdirs 4.11.10) — dep-lock gate
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / best-practices (pull_request) Successful in 7s
CI Pipeline / documentation (pull_request) Successful in 16s
CI Pipeline / type-check (pull_request) Successful in 29s
CI Pipeline / gitea-offline (pull_request) Successful in 18s
deploy / deploy (push) Skipped
Spec gate (headless) / spec-gate (pull_request) Successful in 23s
CI Pipeline / unit-tests (push) Successful in 3m20s
CI Pipeline / unit-tests (pull_request) Successful in 3m20s
CI Pipeline / canary (pull_request) Successful in 31s
CI Pipeline / lint (push) Failing after 38s
CI Pipeline / lint (pull_request) Failing after 29s
CI Pipeline / required-checks (push) Failing after 2s
CI Pipeline / required-checks (pull_request) Failing after 3s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 9s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 7s
2026-09-18 02:59:04 +01:00
Nick 50a63e587f fix(event-driven): authority resilience — commit-status 404 fallback to runs-based verdict
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 6s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / canary (push) Successful in 30s
CI Pipeline / lint (push) Failing after 34s
deploy / deploy (push) Skipped
Auto-label / auto-label (pull_request) Successful in 4s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / lint (pull_request) Failing after 29s
CI Pipeline / best-practices (pull_request) Successful in 7s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / documentation (pull_request) Successful in 7s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
CI Pipeline / type-check (pull_request) Successful in 31s
CI Pipeline / unit-tests (push) Successful in 3m22s
CI Pipeline / required-checks (push) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 4s
CI Pipeline / unit-tests (pull_request) Successful in 3m23s
CI Pipeline / required-checks (pull_request) Failing after 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 6s
Spec gate (headless) / spec-gate (pull_request) Failing after 11m33s
Gitea's combined commit-status endpoint can 404 for the newest commit
(observed live on auto-version bump commits: status object materializes
late). When deploy_qualify returns pending AND the status endpoint is
unreadable, fall back to the operation-scoped Actions-runs verdict (same
evidence the two legs read). Also export DEPLOY_SHA in run() for python
callers. Found via E10 fresh-process proof.
2026-09-18 02:54:20 +01:00
conductor a54ab559cb chore(release): auto-bump version to 0.85.1 — earned by #339 (chore(event-driven): 16/16 gates — EVENT_DRIVEN_CONTINUATION_COMPLETE)
Auto-version and Release / release (push) Successful in 17s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 15s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / unit-tests (push) Successful in 3m23s
CI Pipeline / canary (push) Successful in 28s
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 21s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 4m7s
Promotion record: #339
2026-09-18 01:28:33 +01:00
conductor 599c3ab1c2 Merge pull request 'chore(event-driven): 16/16 gates — EVENT_DRIVEN_CONTINUATION_COMPLETE' (#339) from event-driven-continuation into master
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / canary (push) Successful in 34s
CI Pipeline / type-check (push) Successful in 41s
CI Pipeline / best-practices (push) Successful in 11s
Auto-version and Release / release (push) Successful in 26s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 3m23s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 9s
deploy / deploy (push) Successful in 8m29s
2026-09-18 01:27:35 +01:00
conductor 483bfd7944 Merge branch 'master' into event-driven-continuation
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 38s
CI Pipeline / lint (push) Successful in 47s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / lint (pull_request) Successful in 40s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 19s
deploy / deploy (push) Skipped
CI Pipeline / type-check (pull_request) Successful in 33s
Spec gate (headless) / spec-gate (pull_request) Successful in 17s
CI Pipeline / unit-tests (push) Successful in 3m27s
CI Pipeline / required-checks (push) Successful in 3s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
CI Pipeline / unit-tests (pull_request) Successful in 3m27s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 6s
Auto-version and Release / release (pull_request) Failing after 1m6s
2026-09-18 01:21:47 +01:00
Nick 1650b470c6 chore(event-driven): 16/16 gates PASS, can_accept=true — EVENT_DRIVEN_CONTINUATION_COMPLETE
CI Pipeline / best-practices (push) Successful in 12s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / documentation (push) Successful in 9s
Auto-label / auto-label (pull_request) Successful in 8s
CI Pipeline / lint (push) Successful in 46s
Auto-label / priority-gate (pull_request) Skipped
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / best-practices (pull_request) Successful in 10s
CI Pipeline / documentation (pull_request) Successful in 11s
CI Pipeline / canary (pull_request) Successful in 32s
CI Pipeline / lint (pull_request) Successful in 52s
CI Pipeline / gitea-offline (pull_request) Successful in 21s
CI Pipeline / type-check (pull_request) Successful in 39s
CI Pipeline / unit-tests (push) Successful in 3m27s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
CI Pipeline / unit-tests (pull_request) Successful in 3m27s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 5s
2026-09-18 01:15:08 +01:00
conductor 853cf3e0ae chore(release): auto-bump version to 0.85.0 — earned by # (minor: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 18s
CI Pipeline / lint (push) Successful in 39s
CI Pipeline / canary (push) Successful in 27s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 14s
CI Pipeline / unit-tests (push) Successful in 3m16s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
deploy / deploy (push) Successful in 5m11s
Promotion record: (unknown)
2026-09-18 00:47:49 +01:00
conductor 875bb792f7 chore(release): auto-bump version to 0.85.0 — earned by #338 (feat(event-driven): structured-state routing + event-triggered cognition)
Auto-version and Release / release (push) Successful in 20s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 8s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / unit-tests (push) Successful in 3m21s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 20s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 9m42s
Promotion record: #338
2026-09-18 00:46:00 +01:00
conductor f06ddb3a20 Merge pull request 'feat(event-driven): structured-state routing + event-triggered cognition' (#338) from event-driven-continuation into master
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / type-check (push) Successful in 35s
CI Pipeline / lint (push) Successful in 50s
Auto-version and Release / release (push) Successful in 47s
CI Pipeline / unit-tests (push) Successful in 3m22s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
deploy / deploy (push) Successful in 8m17s
2026-09-18 00:45:16 +01:00
Nick 2ebd9da139 feat(event-driven): structured-state routing + event-triggered cognition
CI Pipeline / best-practices (push) Successful in 11s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 35s
deploy / deploy (push) Skipped
CI Pipeline / lint (push) Successful in 45s
CI Pipeline / gitea-offline (push) Successful in 18s
Auto-label / auto-label (pull_request) Successful in 8s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / lint (pull_request) Successful in 44s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
CI Pipeline / type-check (pull_request) Successful in 29s
Spec gate (headless) / spec-gate (pull_request) Successful in 23s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / best-practices (pull_request) Successful in 8s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / canary (pull_request) Successful in 32s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 9s
CI Pipeline / unit-tests (pull_request) Successful in 3m27s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 7s
Auto-version and Release / release (pull_request) Failing after 1m5s
- PendingOperation = durable continuation object: continuation_state
  (ACTIVE_REASONING/WAITING_EXTERNAL/RESUMABLE/RECOVERY_REQUIRED),
  canonical op_type/authority, task_id — parked cognition is a first-class
  durable state a fresh process can read
- ci_event_wait stamps cognitive-state transitions (WAITING_EXTERNAL on
  park, RESUMABLE/RECOVERY_REQUIRED on terminal)
- DEPLOY_SHA export fix: CLI/python run() consumers previously got a
  silent 'pending' authority verdict forever — the authority subprocess
  never received the sha (found via E10 fresh-process proof)
- await_intent_cli route-bash: Bash commands expressing external wait
  intent compile to the canonical continuation (new bash.ts harness tool
  routes through it); plain local sleeps execute normally
- tests/test_await_intent.py: E-matrix (derivation truth table,
  provenance order, observability)
2026-09-18 00:39:23 +01:00
conductor 65001196d8 chore(release): auto-bump version to 0.84.2 — earned by #337 (chore(async-intent): 13/13 gates — ASYNC_INTENT_NORMALIZATION_COMPLETE)
Auto-version and Release / release (push) Successful in 22s
CI Pipeline / lint (push) Successful in 48s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / canary (push) Successful in 35s
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / documentation (push) Successful in 8s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 11s
deploy / deploy (push) Successful in 2m33s
Promotion record: #337
2026-09-17 23:37:23 +01:00
conductor 76bb2b97be Merge pull request 'chore(async-intent): 13/13 gates — ASYNC_INTENT_NORMALIZATION_COMPLETE' (#337) from async-intent-live-proof into master
CI Pipeline / documentation (push) Successful in 10s
CI Pipeline / canary (push) Successful in 42s
CI Pipeline / lint (push) Successful in 54s
CI Pipeline / type-check (push) Successful in 33s
CI Pipeline / best-practices (push) Successful in 6s
Auto-version and Release / release (push) Successful in 32s
CI Pipeline / unit-tests (push) Successful in 3m31s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 9s
deploy / deploy (push) Successful in 3m24s
2026-09-17 23:36:25 +01:00
conductor e765f654f9 Merge branch 'master' into async-intent-live-proof
CI Pipeline / best-practices (push) Successful in 21s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / lint (push) Successful in 43s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / lint (pull_request) Successful in 44s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / documentation (pull_request) Successful in 7s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
CI Pipeline / type-check (pull_request) Successful in 30s
deploy / deploy (push) Skipped
Spec gate (headless) / spec-gate (pull_request) Successful in 17s
CI Pipeline / unit-tests (push) Successful in 3m20s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
CI Pipeline / unit-tests (pull_request) Successful in 3m20s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 10s
Auto-version and Release / release (pull_request) Failing after 1m20s
2026-09-17 23:31:09 +01:00
Nick f7141200bd chore(async-intent): 13/13 gates PASS, can_accept=true — ASYNC_INTENT_NORMALIZATION_COMPLETE (normalization observability log included)
Auto-label / auto-label (pull_request) Successful in 5s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / best-practices (pull_request) Successful in 8s
CI Pipeline / documentation (pull_request) Successful in 7s
CI Pipeline / canary (pull_request) Successful in 35s
CI Pipeline / type-check (pull_request) Successful in 30s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
Spec gate (headless) / spec-gate (pull_request) Successful in 24s
CI Pipeline / lint (pull_request) Successful in 51s
CI Pipeline / unit-tests (pull_request) Successful in 3m25s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 4s
deploy / deploy (push) Skipped
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / gitea-offline (push) Successful in 29s
CI Pipeline / type-check (push) Successful in 55s
CI Pipeline / lint (push) Failing after 1m3s
CI Pipeline / canary (push) Failing after 1m2s
CI Pipeline / unit-tests (push) Failing after 4m31s
CI Pipeline / required-checks (push) Failing after 6s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 11s
2026-09-17 23:25:33 +01:00
conductor 53b4830b08 chore(release): auto-bump version to 0.84.1 — earned by #336 (docs(async-intent): live proof marker (A8/A9))
Auto-version and Release / release (push) Successful in 21s
CI Pipeline / lint (push) Successful in 43s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / required-checks (push) Successful in 5s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
deploy / deploy (push) Successful in 2m6s
Promotion record: #336
2026-09-17 22:57:07 +01:00
conductor fa1b7c4be1 Merge pull request 'docs(async-intent): live proof marker (A8/A9)' (#336) from async-intent-live-proof into master
CI Pipeline / lint (push) Successful in 46s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / canary (push) Successful in 32s
Auto-version and Release / release (push) Successful in 27s
CI Pipeline / unit-tests (push) Successful in 3m30s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
deploy / deploy (push) Successful in 1m43s
2026-09-17 22:56:32 +01:00
Nick 246f26663d docs(async-intent): live-proof marker for A8-A10 workflows
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 36s
CI Pipeline / lint (push) Successful in 45s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 16s
deploy / deploy (push) Skipped
CI Pipeline / unit-tests (push) Successful in 3m20s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 4s
Auto-label / priority-gate (pull_request) Skipped
Auto-label / auto-label (pull_request) Successful in 1s
CI Pipeline / best-practices (pull_request) Successful in 9s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / lint (pull_request) Successful in 45s
CI Pipeline / canary (pull_request) Successful in 39s
CI Pipeline / type-check (pull_request) Successful in 35s
Spec gate (headless) / spec-gate (pull_request) Successful in 14s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
CI Pipeline / unit-tests (pull_request) Successful in 3m24s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 4s
Auto-version and Release / release (pull_request) Successful in 1m9s
2026-09-17 22:19:35 +01:00
conductor 5718a3ea85 chore(release): auto-bump version to 0.84.0 — earned by # (minor: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 20s
CI Pipeline / lint (push) Successful in 41s
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / canary (push) Successful in 37s
CI Pipeline / documentation (push) Successful in 7s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / unit-tests (push) Successful in 3m21s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 8s
deploy / deploy (push) Successful in 3m39s
Promotion record: (unknown)
2026-09-17 22:04:28 +01:00
conductor 02802f321f chore(release): auto-bump version to 0.84.0 — earned by #335 (feat(async-intent): intent normalization at the execution boundary)
Auto-version and Release / release (push) Successful in 23s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / unit-tests (push) Successful in 3m19s
CI Pipeline / canary (push) Successful in 27s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 34s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 4m31s
Promotion record: #335
2026-09-17 22:02:43 +01:00
conductor 4ce121a493 Merge pull request 'feat(async-intent): intent normalization at the execution boundary' (#335) from async-intent-normalization into master
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / canary (push) Successful in 34s
CI Pipeline / lint (push) Successful in 51s
CI Pipeline / gitea-offline (push) Successful in 21s
CI Pipeline / type-check (push) Successful in 30s
Auto-version and Release / release (push) Successful in 39s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Successful in 10m51s
2026-09-17 22:02:15 +01:00
Nick 8a8d3534c6 feat(async-intent): intent normalization at the execution boundary
CI Pipeline / best-practices (push) Successful in 14s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / lint (push) Successful in 43s
CI Pipeline / canary (push) Successful in 32s
Auto-label / auto-label (pull_request) Successful in 11s
deploy / deploy (push) Skipped
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / documentation (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 29s
CI Pipeline / lint (pull_request) Successful in 44s
CI Pipeline / type-check (pull_request) Successful in 30s
CI Pipeline / gitea-offline (pull_request) Successful in 20s
Spec gate (headless) / spec-gate (pull_request) Successful in 19s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / unit-tests (push) Successful in 3m19s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
CI Pipeline / unit-tests (pull_request) Successful in 3m27s
CI Pipeline / required-checks (pull_request) Successful in 5s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 5s
Auto-version and Release / release (pull_request) Failing after 1m10s
MODEL OUTPUT = INTENT; RUNE CONTROLLER = EXECUTION SEMANTICS.

scripts/await_intent.py: deterministic resolver that derives canonical
op_type from stored normalized records / open PRs / git ancestry — model
supplied op_type and deadline_secs are recorded but NEVER used as policy
(git/Gitea truth outranks even legacy wait records). Sleep/check/poll
intent aimed at a known pending operation compiles to
ContinuePendingOperation; plain legitimate sleeps are untouched.
Timing provenance: USER_EXPLICIT/EXTERNAL_CONTRACT authoritative,
MODEL_INVENTED discarded. Ambiguity fails safe with structured
candidates. await_intent_cli.py = tool surface; compact JSONL
observability per normalization. await-operation.ts rewired to normalize
before dispatch (needs commit of harness tool separately).
2026-09-17 21:55:20 +01:00
conductor d0ec37925f chore(release): auto-bump version to 0.83.5 — earned by #334 (docs(memory-t0): external review report)
Auto-version and Release / release (push) Successful in 18s
CI Pipeline / unit-tests (push) Successful in 3m19s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / canary (push) Successful in 34s
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / gitea-offline (push) Successful in 20s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
deploy / deploy (push) Successful in 4m9s
Promotion record: #334
2026-09-17 21:11:55 +01:00
conductor f9936fa244 Merge pull request 'docs(memory-t0): external review report' (#334) from memory-t0-external-report into master
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 11s
CI Pipeline / canary (push) Successful in 34s
CI Pipeline / lint (push) Successful in 44s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / type-check (push) Successful in 31s
Auto-version and Release / release (push) Successful in 22s
CI Pipeline / unit-tests (push) Successful in 3m27s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 4s
deploy / deploy (push) Successful in 6m10s
2026-09-17 21:11:04 +01:00
Nick 04a277f22c docs(memory-t0): external review report (self-contained brief for third-party LLM review)
CI Pipeline / best-practices (push) Successful in 11s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 36s
Auto-label / auto-label (pull_request) Successful in 4s
CI Pipeline / lint (push) Successful in 45s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / type-check (push) Successful in 33s
CI Pipeline / lint (pull_request) Successful in 41s
CI Pipeline / best-practices (pull_request) Successful in 5s
CI Pipeline / canary (pull_request) Successful in 34s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 17s
Spec gate (headless) / spec-gate (pull_request) Successful in 16s
CI Pipeline / type-check (pull_request) Successful in 29s
CI Pipeline / unit-tests (push) Successful in 3m25s
CI Pipeline / required-checks (push) Successful in 5s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 5s
CI Pipeline / unit-tests (pull_request) Successful in 3m19s
CI Pipeline / required-checks (pull_request) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 5s
Auto-version and Release / release (pull_request) Failing after 1m1s
2026-09-17 21:05:37 +01:00
conductor b2777d666f chore(release): auto-bump version to 0.83.4 — earned by #333 (chore(memory-t0): as-is memory inventory — MEMORY_T0_COMPLETE)
Auto-version and Release / release (push) Successful in 18s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / unit-tests (push) Successful in 3m24s
CI Pipeline / canary (push) Successful in 29s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / gitea-offline (push) Successful in 17s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 11s
deploy / deploy (push) Successful in 3m44s
Promotion record: #333
2026-09-17 20:17:10 +01:00
conductor 0982f7317f Merge pull request 'chore(memory-t0): as-is memory inventory — MEMORY_T0_COMPLETE' (#333) from memory-t0-asis-map into master
Auto-version and Release / release (push) Successful in 21s
CI Pipeline / documentation (push) Successful in 9s
CI Pipeline / best-practices (push) Successful in 12s
CI Pipeline / canary (push) Successful in 36s
CI Pipeline / gitea-offline (push) Successful in 19s
CI Pipeline / lint (push) Successful in 41s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / unit-tests (push) Successful in 3m26s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 6s
deploy / deploy (push) Successful in 6m40s
2026-09-17 20:15:54 +01:00
Nick 9583678997 chore(memory-t0): as-is memory inventory — MEMORY_T0_COMPLETE (17/17 gates)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 10s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / canary (push) Successful in 29s
deploy / deploy (push) Skipped
Auto-label / auto-label (pull_request) Successful in 6s
CI Pipeline / gitea-offline (push) Successful in 18s
CI Pipeline / type-check (push) Successful in 31s
CI Pipeline / best-practices (pull_request) Successful in 10s
CI Pipeline / documentation (pull_request) Successful in 6s
CI Pipeline / lint (pull_request) Successful in 50s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
CI Pipeline / type-check (pull_request) Successful in 29s
CI Pipeline / canary (pull_request) Successful in 31s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / unit-tests (push) Successful in 3m19s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (push) Successful in 7s
CI Pipeline / unit-tests (pull_request) Successful in 3m26s
CI Pipeline / required-checks (pull_request) Successful in 2s
CI Pipeline / CI Pipeline / notify-event-bridge (pull_request) Successful in 6s
Auto-version and Release / release (pull_request) Successful in 1m0s
Read-mostly archaeology: one canonical experiential store (memory.db:
899 entries, hybrid dense+BM25 recall, dedupe/supersede gate with 1465
receipts), derived knowledge.json (7965 items), dormant graph/shards/
temporal, harness-native duplicate-authority surface identified, INWARD
port verified as unbound-but-real contract. DEFECT FOUND (recorded, not
fixed): sleep-time systemd timer reads stale opencode.db — designed
transcript-mining loop broken; consolidation survives via per-turn
mandate. Preservation risks classified; fresh-worker answers embedded.
2026-09-17 20:10:03 +01:00
23 changed files with 2034 additions and 40 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.83.3**
**Current release: v0.85.6**
**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.**
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rune"
version = "0.83.3"
version = "0.85.6"
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
requires-python = ">=3.10"
+2 -2
View File
@@ -1,5 +1,5 @@
# This file was autogenerated by uv via the following command:
# uv pip compile pyproject.toml -o /tmp/regen-req.txt --extra dev --extra memory --python-version 3.11
# uv pip compile pyproject.toml -o /tmp/regen2.txt --extra dev --extra memory --python-version 3.11
aiohappyeyeballs==2.7.1
# via aiohttp
aiohttp==3.14.3
@@ -64,7 +64,7 @@ nodeenv==1.10.0
# via pyright
packaging==26.3
# via pytest
platformdirs==4.11.9
platformdirs==4.11.10
# via textual
pluggy==1.6.0
# via
+404
View File
@@ -0,0 +1,404 @@
"""await_intent.py — ASYNC CORRECTIVE PATCH: intent normalization at the
execution boundary.
PRINCIPLE: MODEL OUTPUT = INTENT. RUNE CONTROLLER = EXECUTION SEMANTICS.
The model may express continuation intent in any quality — `await_operation
(deadline_secs=1200)`, `await-operation [op_type=master_ci, sha=X]`,
"sleep 300 then check CI", "poll until done". When a matching
PendingOperation exists (or the deterministic resolver can derive the
operation truth from git/Gitea state), the controller executes the
CANONICAL continuation and discards model-supplied scheduling policy.
Authority provenance for timing:
USER_EXPLICIT / EXTERNAL_CONTRACT / TEST_HARNESS /
GOVERNED_OPERATION_POLICY -> authoritative, retained
MODEL_INVENTED -> non-authoritative, ignored
This module owns NO storage: it reads the existing W/R wait store
(rune.event_wait) and git/Gitea state. The canonical continuation remains
scripts/ci_event_wait.py run() (the T21.5 single-logical-await).
"""
from __future__ import annotations
import json
import os
import re
import subprocess
import sys
from pathlib import Path
from typing import Any
_SCRIPT_DIR = Path(__file__).resolve().parent
if str(_SCRIPT_DIR) not in sys.path:
sys.path.insert(0, str(_SCRIPT_DIR))
_REPO_SRC = str(_SCRIPT_DIR.parent / "src")
if _REPO_SRC not in sys.path:
sys.path.insert(0, _REPO_SRC)
WR_BRIDGE = Path(os.environ.get("RUNE_WR_ROOT", "/mnt/workdrive/wr-bridge"))
REPO = Path("/mnt/workdrive/issue161-harness")
GIT_TIMEOUT = 10
# Default policy deadline per operation type — GOVERNED_OPERATION_POLICY.
# The model's numbers never become policy; these are the controller's.
POLICY_DEADLINES = {
"branch_ci": 1800,
"pull_request_checks": 1800,
"master_ci": 1800,
"deploy": 900,
"release": 900,
}
VALID_OP_TYPES = ("branch_ci", "pull_request_checks", "master_ci",
"deploy", "release")
# ── timing provenance ───────────────────────────────────────────────────────
def classify_timing_provenance(model_deadline: Any = None,
user_deadline: Any = None,
contract_deadline: Any = None) -> tuple[int, str]:
"""Resolve the effective deadline + its provenance.
Authority order: USER_EXPLICIT > EXTERNAL_CONTRACT > TEST_HARNESS >
GOVERNED_OPERATION_POLICY. MODEL_INVENTED values are recorded but
NEVER used as policy.
"""
if model_deadline is not None:
try:
model_deadline = int(model_deadline)
except (TypeError, ValueError):
model_deadline = None
if user_deadline is not None:
return int(user_deadline), "USER_EXPLICIT"
if contract_deadline is not None:
return int(contract_deadline), "EXTERNAL_CONTRACT"
return (model_deadline or 0), "MODEL_INVENTED" # caller discards this
# ── PendingOperation lookup over the existing W/R wait store ────────────────
def _load_wait_records() -> list[dict]:
"""All durable wait records from the bridge store (read-only)."""
out = []
waits = WR_BRIDGE / "waits"
if not waits.is_dir():
return out
for f in sorted(waits.glob("*.json")):
try:
rec = json.loads(f.read_text())
rec["_file"] = f.name
out.append(rec)
except (OSError, ValueError):
continue
return out
def _rec_operation_id(rec: dict) -> str:
return str((rec.get("ext") or {}).get("operation_id")
or rec.get("operation_id") or "")
def _rec_sha(rec: dict) -> str:
return str(rec.get("sha") or "")
def pending_operations(sha: str = "", op_type: str = "") -> list[dict]:
"""Pending (non-terminal) operations, optionally filtered."""
terminal = {"COMPLETED", "FAILED", "CLOSED", "CANCELLED", "EXPIRED"}
out = []
for rec in _load_wait_records():
status = str(rec.get("status", "")).upper()
if status in terminal:
continue
if sha and _rec_sha(rec) != sha:
continue
out.append(rec)
return out
def find_op_type_for_sha(sha: str) -> str | None:
"""The op_type a prior canonical wait already recorded for this SHA
(objective text embeds the type: 'event-driven {op_type} qualification')."""
for rec in _load_wait_records():
if _rec_sha(rec) != sha:
continue
obj = str(rec.get("continuation", {}).get("objective", ""))
m = re.search(r"event-driven (\w+) qualification", obj)
if m and m.group(1) in VALID_OP_TYPES:
return m.group(1)
return None
# ── deterministic op_type derivation from repo/Gitea truth ─────────────────
def _git(*args: str) -> str:
try:
r = subprocess.run(["git", "-C", str(REPO), *args],
capture_output=True, text=True, timeout=GIT_TIMEOUT)
return r.stdout.strip()
except (OSError, subprocess.TimeoutExpired):
return ""
def sha_branch(sha: str) -> str:
"""Branch(es) containing this commit in the local repo."""
return _git("branch", "--all", "--contains", sha)
def sha_on_master(sha: str) -> bool:
out = _git("branch", "--contains", sha)
return any(l.strip().endswith("master") or l.strip() == "master"
for l in out.splitlines())
def open_pr_for_sha(sha: str) -> int | None:
"""Is there an OPEN PR whose head SHA is this one? (Gitea API, read-only.)"""
try:
sys.path.insert(0, str(_SCRIPT_DIR))
import gitea_auth # noqa: E402
st, prs = gitea_auth.api("/pulls?state=open&limit=50")
if st != 200:
return None
for p in prs:
hs = str(p.get("head") or {}).get("sha") if isinstance(
p.get("head"), dict) else None
if hs and str(hs).startswith(sha[:12]):
return int(p.get("number"))
except Exception: # noqa: BLE001 — resolver must never crash the tool
return None
return None
def derive_op_type(sha: str) -> tuple[str, str]:
"""Deterministically derive the canonical op_type for a SHA.
Returns (op_type, evidence). Order (A-patch §2 amendment):
1. POST-PATCH normalized record (ext.intent_normalized=true) — true
stored operation truth, wins outright;
2. open PR for the sha -> pull_request_checks;
3. sha ancestor of master -> master_ci;
4. sha on a feature branch -> branch_ci;
5. legacy (pre-patch) records only CONFIRM, never override — they
were created from model-supplied defaults and cannot be trusted.
Never trusts model input.
"""
for rec in _load_wait_records():
if _rec_sha(rec) != sha:
continue
if (rec.get("ext") or {}).get("intent_normalized"):
obj = str(rec.get("continuation", {}).get("objective", ""))
m = re.search(r"event-driven (\w+) qualification", obj)
if m and m.group(1) in VALID_OP_TYPES:
return m.group(1), "normalized_record:" + m.group(1)
pr = open_pr_for_sha(sha)
if pr:
return "pull_request_checks", f"open_pr:#{pr}"
if sha_on_master(sha):
return "master_ci", "commit_ancestor_of_master"
return "branch_ci", "commit_on_feature_branch"
# ── intent normalization ────────────────────────────────────────────────────
def normalize_action(action: dict, *,
model_deadline: Any = None,
user_deadline: Any = None,
contract_deadline: Any = None) -> dict:
"""Normalize a model continuation action into the canonical continuation.
action: {kind: await_operation|sleep_poll|check_status|unknown,
sha?: str, operation_id?: str, op_type?: str, raw?: str}
Returns:
{normalized: bool, action: "ContinuePendingOperation", operation_id,
op_type, authority, deadline_secs, deadline_provenance,
model_deadline_ignored, model_op_type_ignored, evidence}
or {normalized: False, reason: ...} / {normalized: "AMBIGUOUS", candidates}
"""
sha = str(action.get("sha") or "")
op_id = str(action.get("operation_id") or "")
model_op_type = action.get("op_type")
model_deadline_ignored = model_deadline is not None
model_op_type_ignored = model_op_type is not None
# 1. explicit operation_id wins
if op_id:
from rune import event_wait as ew # noqa: E402
rec = ew.operation_wait(op_id)
if rec is None:
return {"normalized": False,
"reason": f"operation_id {op_id} has no wait record"}
return _canonical_from_record(rec, model_deadline_ignored,
model_op_type_ignored, "explicit_id",
user_deadline, contract_deadline)
# 2. resolve by sha / active operation.
# H-PATCH H2/H3: the model sha is a HINT. If it doesn't resolve but
# unambiguous pending operations exist, the STORED target wins — a
# mistyped model sha must never create a ghost operation (the A-patch
# live failure: a typo'd sha derived branch_ci for a nonexistent commit
# and parked a wait on a ghost).
candidates = pending_operations(sha=sha)
if len(candidates) > 1 and not sha:
return {"normalized": "AMBIGUOUS",
"candidates": [_rec_operation_id(c) for c in candidates],
"reason": "multiple pending operations, no target"}
if len(candidates) == 1:
rec = candidates[0]
stored_sha = _rec_sha(rec)
norm = _canonical_from_record(rec, model_deadline_ignored,
model_op_type_ignored, "pending_match",
user_deadline, contract_deadline)
if sha and stored_sha and sha != stored_sha:
norm["model_sha_mismatch"] = {
"model_sha": sha, "stored_sha": stored_sha,
"resolution": "stored_target_used"}
return norm
# model sha unresolved: any unambiguous pending op at all? then the
# model probably mistyped the sha — use the stored target, log it.
all_pending = pending_operations()
if len(all_pending) == 1 and sha:
rec = all_pending[0]
stored_sha = _rec_sha(rec)
norm = _canonical_from_record(rec, model_deadline_ignored,
model_op_type_ignored,
"unresolved_sha_single_pending",
user_deadline, contract_deadline)
norm["model_sha_mismatch"] = {
"model_sha": sha, "stored_sha": stored_sha,
"resolution": "stored_target_used"}
return norm
# 3. no stored record: derive truth deterministically
if not sha:
return {"normalized": False,
"reason": "no pending operation and no sha to resolve"}
op_type, evidence = derive_op_type(sha)
return {
"normalized": True,
"action": "ContinuePendingOperation",
"operation_id": f"ci-{sha}",
"op_type": op_type,
"authority": "ci_runs" if op_type in ("branch_ci",
"pull_request_checks")
else "deploy_qualify",
"deadline_secs": POLICY_DEADLINES[op_type],
"deadline_provenance": "GOVERNED_OPERATION_POLICY",
"model_deadline_ignored": model_deadline_ignored,
"model_op_type_ignored": model_op_type_ignored,
"evidence": evidence,
}
def _canonical_from_record(rec: dict, model_deadline_ignored: bool,
model_op_type_ignored: bool, how: str,
user_deadline: Any, contract_deadline: Any) -> dict:
op_id = _rec_operation_id(rec)
obj = str(rec.get("continuation", {}).get("objective", ""))
m = re.search(r"event-driven (\w+) qualification", obj)
recorded = m.group(1) if (m and m.group(1) in VALID_OP_TYPES) else None
rec_sha = _rec_sha(rec)
if (rec.get("ext") or {}).get("intent_normalized") or how == "explicit_id":
# normalized record or explicit id: stored truth wins
op_type = recorded or "master_ci"
else:
# legacy record: git/Gitea derivation outranks the model-era default
op_type, _ev = derive_op_type(rec_sha) if rec_sha else \
(recorded or "master_ci", "no_sha")
deadline, prov = classify_timing_provenance(
user_deadline=user_deadline, contract_deadline=contract_deadline)
if prov == "MODEL_INVENTED" or not deadline:
deadline = POLICY_DEADLINES.get(op_type, 1800)
prov = "GOVERNED_OPERATION_POLICY"
return {
"normalized": True,
"action": "ContinuePendingOperation",
"operation_id": op_id,
"op_type": op_type,
"authority": "ci_runs" if op_type in ("branch_ci",
"pull_request_checks")
else "deploy_qualify",
"deadline_secs": deadline,
"deadline_provenance": prov,
"model_deadline_ignored": model_deadline_ignored,
"model_op_type_ignored": model_op_type_ignored,
"matched_by": how,
}
def normalize_bash(command: str, *, sha_hint: str = "") -> dict | None:
"""Recognize sleep/check/poll intent aimed at a known pending operation.
Returns a normalization record if the command's semantic intent is
continuation of a known external operation; None if the command is
legitimate local timing (short sync, user delay, backoff) with no
pending operation to continue. NEVER returns an executed sleep.
"""
if not command:
return None
cmd = command.strip()
# long sleep + (status-check language or an explicit sha hint)
sleep_m = re.search(r"\bsleep\s+(\d{2,5})\b", cmd)
if not sleep_m:
return None
secs = int(sleep_m.group(1))
check_intent = bool(re.search(
r"\b(ci|deploy|release|status|check|poll|pipeline|run)\b", cmd,
re.IGNORECASE))
sha = sha_hint or ""
m = re.search(r"\b([0-9a-f]{40}|[0-9a-f]{12})\b", cmd)
if m:
sha = m.group(1)
if not check_intent and not sha:
return None # plain sleep, no continuation intent
cands = pending_operations(sha=sha) if sha else pending_operations()
if not cands and not sha:
return None
if len(cands) > 1:
return {"normalized": "AMBIGUOUS",
"candidates": [_rec_operation_id(c) for c in cands],
"raw_command_kind": "sleep_poll"}
rec = cands[0] if cands else None
if rec is not None:
norm = _canonical_from_record(rec, True, False, "sleep_poll_intent",
None, None)
norm["sha_for_wait"] = _rec_sha(rec)
elif sha:
op_type, evidence = derive_op_type(sha)
norm = {
"normalized": True, "action": "ContinuePendingOperation",
"operation_id": f"ci-{sha}", "op_type": op_type,
"authority": "ci_runs" if op_type in ("branch_ci",
"pull_request_checks")
else "deploy_qualify",
"deadline_secs": POLICY_DEADLINES[op_type],
"deadline_provenance": "GOVERNED_OPERATION_POLICY",
"model_deadline_ignored": True, "model_op_type_ignored": False,
"evidence": evidence, "sha_for_wait": sha,
}
else:
return None
norm["raw_command_kind"] = "sleep_poll"
norm["raw_sleep_seconds_suppressed"] = secs
return norm
def emit_normalized_record(record: dict) -> None:
"""Compact structured observability — one JSONL line per normalization.
No payloads, no secrets."""
try:
log = _SCRIPT_DIR.parent / "store" / "await_intent_log.jsonl"
log.parent.mkdir(parents=True, exist_ok=True)
slim = {k: record.get(k) for k in (
"normalized", "action", "operation_id", "op_type", "authority",
"deadline_secs", "deadline_provenance", "model_deadline_ignored",
"model_op_type_ignored", "matched_by", "evidence",
"raw_command_kind", "raw_sleep_seconds_suppressed", "reason",
"candidates") if k in record}
slim["at"] = __import__("time").strftime(
"%Y-%m-%dT%H:%M:%SZ", __import__("time").gmtime())
with open(log, "a") as f:
f.write(json.dumps(slim, sort_keys=True) + "\n")
except OSError:
pass
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""await_intent_cli.py — CLI surface for the intent normalization layer.
Used by the await-operation harness tool so the MODEL's scheduling hints
never reach the wait engine. Prints one JSON line.
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import await_intent # noqa: E402
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__)
sub = ap.add_subparsers(dest="cmd", required=True)
n = sub.add_parser("normalize", help="normalize a continuation intent")
n.add_argument("--sha", default="")
n.add_argument("--operation-id", default="")
n.add_argument("--model-op-type", default=None)
n.add_argument("--model-deadline", default=None)
n.add_argument("--user-deadline", default=None,
help="USER_EXPLICIT deadline (authoritative)")
n.add_argument("--contract-deadline", default=None,
help="EXTERNAL_CONTRACT deadline (authoritative)")
rb = sub.add_parser("route-bash",
help="route a Bash command expressing wait intent")
rb.add_argument("--command", required=True)
rb.add_argument("--sha-hint", default="")
args = ap.parse_args()
if args.cmd == "route-bash":
record = await_intent.normalize_bash(args.command,
sha_hint=args.sha_hint)
if record is None:
print(json.dumps({"normalized": False,
"reason": "no external continuation intent"}))
return 0
if record.get("normalized") is True:
# the compiled wait needs the SHA: derive from operation_id
oid = str(record.get("operation_id", ""))
if oid.startswith("ci-"):
record["sha_for_wait"] = oid[3:]
await_intent.emit_normalized_record(record)
print(json.dumps(record, sort_keys=True))
return 0
action = {"kind": "await_operation", "sha": args.sha,
"operation_id": args.operation_id,
"op_type": args.model_op_type}
model_deadline = (int(args.model_deadline)
if args.model_deadline else None)
user_deadline = (int(args.user_deadline)
if args.user_deadline else None)
contract_deadline = (int(args.contract_deadline)
if args.contract_deadline else None)
record = await_intent.normalize_action(
action, model_deadline=model_deadline,
user_deadline=user_deadline, contract_deadline=contract_deadline)
await_intent.emit_normalized_record(record)
print(json.dumps(record, sort_keys=True))
return 0
if __name__ == "__main__":
sys.exit(main())
+78 -15
View File
@@ -55,20 +55,23 @@ REPO_ROOT = _SCRIPT_DIR.parent
QUALIFY_SCRIPT = _SCRIPT_DIR / "deploy_qualify.py"
def authority_verdict() -> str:
def authority_verdict(sha: str = "") -> str:
"""ONE-SHOT canonical Gitea verdict via deploy_qualify.py — the only
completion truth. Never parses the event payload."""
completion truth. Never parses the event payload.
H-PATCH H4: the target sha is passed EXPLICITLY (as the subprocess's
--sha argument) — ambient DEPLOY_SHA can no longer change which
operation is verified. The env var remains only as a CLI backward
compat for deploy_qualify.py invoked standalone."""
cmd = [sys.executable, str(QUALIFY_SCRIPT)]
if sha:
cmd += ["--sha", sha]
proc = subprocess.run(
[sys.executable, str(QUALIFY_SCRIPT)],
cmd,
capture_output=True, text=True, timeout=120,
env=dict(os.environ, PYTHONPATH=""),
env={k: v for k, v in os.environ.items() if k != "DEPLOY_SHA"}
if sha else dict(os.environ, PYTHONPATH=""),
)
# T21.3: GITEA_TOKEN from deploy.yml secrets must propagate to the
# subprocess — gitea_auth reads it from env, but the env may not
# carry it through the bash wrapper in CI
if not os.environ.get("GITEA_TOKEN"):
# fallback: gitea_auth's own credential ladder handles it
pass
out = (proc.stdout or "").strip().splitlines()
return (out[-1] if out else "pending").strip()
@@ -169,12 +172,35 @@ def op_authority_verdict(op_type: str, sha: str) -> str:
spec = op_spec(op_type)
authority = spec["authority"]
if authority == "deploy_qualify":
return authority_verdict()
v = normalize_verdict(authority_verdict(sha))
if v != "pending":
return v
# E-PATCH resilience: Gitea's combined commit-status endpoint can
# 404 for the newest commit (observed live on auto-version bump
# commits — the status object materializes late/never). The runs
# ARE the same evidence the two legs read; fall back to the
# operation-scoped runs verdict so authority stays resolvable.
if _status_endpoint_unreadable(sha):
return _ci_runs_verdict(spec, sha)
return v
if authority == "ci_runs":
return _ci_runs_verdict(spec, sha)
raise ValueError(f"unknown authority {authority!r} for {op_type!r}")
def _status_endpoint_unreadable(sha: str) -> bool:
"""True when the combined commit-status endpoint 404s for the SHA
(index lag / never-materialized status object) — the documented
fallback trigger, verified against the API once per call."""
try:
sys.path.insert(0, str(_SCRIPT_DIR))
import gitea_auth # noqa: E402
st, _body = gitea_auth.api(f"/commits/{sha}/status")
return st == 404
except Exception: # noqa: BLE001
return False
def _ci_runs_verdict(spec: dict, sha: str) -> str:
"""Operation-scoped Actions-run verdict (import the API client from
deploy_qualify to keep ONE Gitea client)."""
@@ -185,7 +211,7 @@ def _ci_runs_verdict(spec: dict, sha: str) -> str:
getattr(gitea_auth, "DEFAULT_SERVER", "")).rstrip("/")
repo = os.environ.get("GITEA_REPO",
getattr(gitea_auth, "DEFAULT_REPO", ""))
sha_env = os.environ.get("DEPLOY_SHA", "") or sha
sha_env = sha # H-PATCH: explicit parameter is the only authority
token = gitea_auth.get_token() if gitea_auth.has_token() else ""
if not (server and repo and sha_env and token):
return "pending" # cannot verify -> not verified (fail closed)
@@ -221,7 +247,7 @@ def op_ci_alive(op_type: str, sha: str) -> bool:
getattr(gitea_auth, "DEFAULT_SERVER", "")).rstrip("/")
repo = os.environ.get("GITEA_REPO",
getattr(gitea_auth, "DEFAULT_REPO", ""))
sha_env = os.environ.get("DEPLOY_SHA", "") or sha
sha_env = sha # H-PATCH: explicit parameter is the only authority
token = gitea_auth.get_token() if gitea_auth.has_token() else ""
if not (server and repo and sha_env and token):
return False
@@ -243,6 +269,7 @@ def op_ci_alive(op_type: str, sha: str) -> bool:
def authority_after_wake(op_type: str = DEFAULT_OP_TYPE, sha: str = "",
max_tries: int = 3, gap_secs: int = 4) -> str:
"""(sha is EXPLICIT — ambient env never selects the target.)"""
"""Post-wake authority read. The daemon's own wake sweep uses a
bounded event-triggered retry (4s ×3) for the job-finished-microseconds-
ago ack window; a verdict read here can hit the same window. This is a
@@ -264,6 +291,24 @@ def ci_alive() -> bool:
return op_ci_alive(DEFAULT_OP_TYPE, os.environ.get("DEPLOY_SHA", ""))
def _set_cognition_state(op: str, state: str) -> None:
"""E-PATCH §12: stamp cognitive quiescence on the durable record so a
fresh process knows cognition is parked (WAITING_EXTERNAL) vs resumable
(RESUMABLE). Best-effort: observability never breaks the wait."""
try:
rec = ew.operation_wait(op)
if rec is None:
return
wait_file = ew.wr_root() / "waits" / f"{rec.get('wait_id')}.json"
if not wait_file.is_file():
return
data = json.loads(wait_file.read_text())
data.setdefault("ext", {})["continuation_state"] = state
wait_file.write_text(json.dumps(data, indent=1, sort_keys=True))
except (OSError, ValueError):
pass
def run(*, sha: str, deadline_secs: int,
watchdog_secs: int = 300,
op_type: str = DEFAULT_OP_TYPE,
@@ -279,6 +324,10 @@ def run(*, sha: str, deadline_secs: int,
"""
spec = op_spec(op_type) # unknown op_type refused upfront
op = f"ci-{sha}"
# A-PATCH: the authority subprocess reads DEPLOY_SHA from the env;
# python-level run() callers (tool normalization flow) must export it.
if sha and not os.environ.get("DEPLOY_SHA"):
os.environ["DEPLOY_SHA"] = sha
t0 = time.time()
# §16Y #10 race fix: the FIFO reader exists BEFORE registration, so a
# wake arriving in the registration window can always be delivered.
@@ -295,7 +344,10 @@ def run(*, sha: str, deadline_secs: int,
watched_for="Gitea CI completion event (replayed from the "
"durable event log)",
provider="gitea", event_type="ci_completed", sha=sha,
watchdog_secs=min(watchdog_secs, deadline_secs))
watchdog_secs=min(watchdog_secs, deadline_secs),
continuation_state="RESUMABLE", # event already arrived
op_type=op_type,
authority=spec["authority"])
registered_at = rec["created_at"]
event_at = time.strftime(
"%Y-%m-%dT%H:%M:%SZ", time.gmtime())
@@ -329,8 +381,12 @@ def run(*, sha: str, deadline_secs: int,
watched_for="Gitea CI completion event (wake; verdict re-read "
f"from canonical {spec['authority']} authority)",
provider="gitea", event_type="ci_completed", sha=sha,
watchdog_secs=min(watchdog_secs, deadline_secs))
watchdog_secs=min(watchdog_secs, deadline_secs),
continuation_state="WAITING_EXTERNAL",
op_type=op_type,
authority=spec["authority"])
registered_at = rec["created_at"]
_set_cognition_state(op, "WAITING_EXTERNAL") # cognition parked
deadline = time.monotonic() + deadline_secs
verdict = "pending"
mode = "event"
@@ -409,6 +465,8 @@ def run(*, sha: str, deadline_secs: int,
if mode == "event":
mode = "deadline_pending"
verdict = normalize_verdict(op_authority_verdict(op_type, sha)) # final one-shot truth
_set_cognition_state(op, "RESUMABLE" if verdict != "pending"
else "RECOVERY_REQUIRED")
verdict_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
out = {
"sha": sha,
@@ -441,6 +499,11 @@ def main() -> int:
if not sha:
print(json.dumps({"error": "no sha (DEPLOY_SHA or --sha required)"}))
return 1
# A-PATCH fix: run()'s authority subprocess (deploy_qualify.py) reads
# DEPLOY_SHA from the environment — a CLI `--sha` consumer previously
# got a silent "pending" verdict forever because the var was never
# exported. Export it so the canonical authority can resolve.
os.environ["DEPLOY_SHA"] = sha
return run(sha=sha, deadline_secs=deadline, op_type=op_type)
+27 -7
View File
@@ -106,12 +106,25 @@ def _fetch_status(server: str, repo: str, sha: str, token: str) -> list[dict] |
return None if data is None else data.get("statuses", [])
def _fetch_runs(server: str, repo: str, sha: str, token: str) -> list[dict] | None:
data = _get_json(f"{server}/api/v1/repos/{repo}/actions/runs?limit=50", token)
if data is None:
return None
runs = data.get("workflow_runs", data if isinstance(data, list) else [])
return [r for r in runs if str(r.get("head_sha", "")) == sha]
def _fetch_runs(server: str, repo: str, sha: str, token: str,
max_pages: int = 4) -> list[dict] | None:
"""H-PATCH: paginate the runs list. The repo's scheduled merge-robot
runs flood the first page (~50 slots exhaust within hours), pushing
older-but-relevant SHAs to later pages — the cause of the observed
authority flapping (terminal commit read as pending). Paginate until
the sha is found or max_pages exhausted."""
out: list[dict] = []
for page in range(1, max_pages + 1):
data = _get_json(
f"{server}/api/v1/repos/{repo}/actions/runs?limit=50&page={page}",
token)
if data is None:
return None if page == 1 else (out or None)
runs = data.get("workflow_runs", data if isinstance(data, list) else [])
out.extend(r for r in runs if str(r.get("head_sha", "")) == sha)
if len(runs) < 50:
break # exhausted
return out
def _fetch_jobs(server: str, repo: str, run_id, token: str) -> list[dict] | None:
@@ -132,10 +145,17 @@ def main() -> int:
# not export GITEA_SERVER/GITEA_REPO (CI always exports them; local
# and first-class-tool consumers previously got a silent "pending"
# verdict — a wrong answer, not a fail-closed one).
# H-PATCH H4: the target sha arrives EXPLICITLY (--sha) from callers
# that hold structured operation state. DEPLOY_SHA env remains only
# for standalone/workflow backward compat — the canonical path never
# depends on ambient env for operation identity.
ap = __import__("argparse").ArgumentParser()
ap.add_argument("--sha", dest="sha_arg", default=None)
args, _unknown = ap.parse_known_args()
server = (os.environ.get("GITEA_SERVER", "")
or gitea_auth.DEFAULT_SERVER).rstrip("/")
repo = os.environ.get("GITEA_REPO", "") or gitea_auth.DEFAULT_REPO
sha = os.environ.get("DEPLOY_SHA", "")
sha = args.sha_arg or os.environ.get("DEPLOY_SHA", "")
token = gitea_auth.get_token() if gitea_auth.has_token() else ""
if not (server and repo and sha and token):
print("pending") # missing config → cannot verify → not qualified
+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.83.3"
__version__ = "0.85.6"
# 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
@@ -231,7 +231,7 @@ def main() -> int:
)
check(
"Rune minor version advertises provisioning and restore verification",
'__version__ = "0.83.3"' in rune_version,
'__version__ = "0.85.6"' in rune_version,
failures,
)
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
+17 -2
View File
@@ -171,7 +171,19 @@ def register_process_wait(operation_id: str, *, contract_id: str = "",
provider: str = "builder",
event_type: str = "builder_exit",
sha: str = "",
watchdog_secs: int | None = None) -> dict:
watchdog_secs: int | None = None,
continuation_state: str = "WAITING_EXTERNAL",
op_type: str = "",
authority: str = "",
task_id: str = "") -> dict:
"""E-PATCH §4: the PendingOperation IS the durable continuation object.
continuation_state is first-class cognitive quiescence:
ACTIVE_REASONING | WAITING_EXTERNAL | RESUMABLE | RECOVERY_REQUIRED
op_type/authority record the CANONICAL execution semantics (derived by
intent normalization, never model-supplied). task_id/project bind the
operation to the current programme so fresh-process recovery can
resolve relevance without the model reconstructing state."""
"""Register a durable PROCESS_EVENT wait for one operation. The
per-wait resume_cmd writes a resume token to the operation's FIFO —
the bridge can resume a Python controller, not just MiMo sessions.
@@ -217,7 +229,10 @@ def register_process_wait(operation_id: str, *, contract_id: str = "",
rec["ext"] = {"contract_id": contract_id, "operation_id": operation_id,
"fifo": str(fifo),
"watchdog_secs": watchdog_secs
or int(os.environ.get("WR_WATCH_SECS", "600"))}
or int(os.environ.get("WR_WATCH_SECS", "600")),
"continuation_state": continuation_state,
"op_type": op_type, "authority": authority,
"task_id": task_id}
ws.save(rec)
# cross-user bridge (T16 §16C live finding): the daemon reconciler may
# run under a different account than the registering controller — the
+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.83.3
Version: v0.85.6
Features: 41 (24 original + 17 new native commands)
Usage:
@@ -1885,7 +1885,7 @@ class RuneApp(App):
# Show version info
self.chat_channel.add_message(
"system",
f"[dim]Rune v0.83.3 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.85.6 | Textual TUI | {len(loaded)} native modules[/dim]",
)
# Auto-show night mode suggestion if evening/night hours
+6
View File
@@ -0,0 +1,6 @@
{"action": "ContinuePendingOperation", "at": "2026-09-17T20:50:30Z", "authority": "ci_runs", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "matched_by": "pending_match", "model_deadline_ignored": true, "model_op_type_ignored": true, "normalized": true, "op_type": "branch_ci", "operation_id": "ci-756ebe6f45ad83a919738539a1565c17ed8572ac"}
{"action": "ContinuePendingOperation", "at": "2026-09-17T20:51:20Z", "authority": "deploy_qualify", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "evidence": "commit_ancestor_of_master", "model_deadline_ignored": true, "model_op_type_ignored": true, "normalized": true, "op_type": "master_ci", "operation_id": "ci-f7256aa29e8bc7aa365ad7ffa27eb557528ccca5"}
{"action": "ContinuePendingOperation", "at": "2026-09-17T21:50:39Z", "authority": "ci_runs", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "evidence": "commit_on_feature_branch", "model_deadline_ignored": true, "model_op_type_ignored": true, "normalized": true, "op_type": "branch_ci", "operation_id": "ci-246f26663d8fa2aba3a16039c86feb13a6d0bd2c"}
{"action": "ContinuePendingOperation", "at": "2026-09-17T21:53:34Z", "authority": "ci_runs", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "evidence": "commit_on_feature_branch", "model_deadline_ignored": false, "model_op_type_ignored": false, "normalized": true, "op_type": "branch_ci", "operation_id": "ci-246f26663d8fa2aba3a16039c86feb13a6d0bd2c"}
{"action": "ContinuePendingOperation", "at": "2026-09-17T21:55:05Z", "authority": "ci_runs", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "evidence": "commit_on_feature_branch", "model_deadline_ignored": false, "model_op_type_ignored": false, "normalized": true, "op_type": "branch_ci", "operation_id": "ci-246f26663d8fa2aba3a16039c86feb13a6d0bd2c"}
{"action": "ContinuePendingOperation", "at": "2026-09-17T23:19:18Z", "authority": "ci_runs", "deadline_provenance": "GOVERNED_OPERATION_POLICY", "deadline_secs": 1800, "matched_by": "sleep_poll_intent", "model_deadline_ignored": true, "model_op_type_ignored": false, "normalized": true, "op_type": "branch_ci", "operation_id": "ci-756ebe6f45ad83a919738539a1565c17ed8572ac", "raw_command_kind": "sleep_poll", "raw_sleep_seconds_suppressed": 150}
+169
View File
@@ -0,0 +1,169 @@
{
"tranche": "ASYNC_INTENT_NORMALIZATION",
"purpose": "Intent normalization at the execution boundary \u2014 model emits intent, controller owns execution semantics",
"predecessor": "T21.5 (guards retired) + Memory T0 (complete)",
"created_at": "2026-09-17T20:43:47Z",
"gates": [
{
"gate_id": "A10_LIVE_MASTER_DEPLOY_PROOF",
"mandatory": true,
"requirement": "live master CI -> deploy with normalization evidence",
"status": "PASS",
"evidence": "Post-merge master 53b4830: canonical continuation master_ci/deploy_qualify through deadline with 4 internal re-arms, then event_replayed success 0.771s on re-arm; deployed current == 53b4830 (0.84.1, ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A11_REGRESSION_TESTS",
"mandatory": true,
"requirement": "deterministic test matrix green; existing wait tests unbroken",
"status": "PASS",
"evidence": "tests/test_await_intent.py 14/14 (A-H matrix + derivation truth table + provenance + observability). Existing wait suites unbroken: test_ci_event_wait 11/11, test_single_logical_await 9/9, test_event_",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A12_RAW_SELF_AUDIT",
"mandatory": true,
"requirement": "post-fix stream classified; no model scheduling choice affected execution",
"status": "PASS",
"evidence": "Post-fix stream classified: all 5 normalizations in store/await_intent_log.jsonl have deadline_provenance=GOVERNED_OPERATION_POLICY; MODEL_DURATION_ACTUALLY_USED_COUNT=0; MODEL_SUPPLIED_OP_TYPE_COUNT_",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:25:09Z"
},
{
"gate_id": "A13_FINAL_RUNTIME_CONVERGENCE",
"mandatory": true,
"requirement": "git==release==deployed==runtime==healthy",
"status": "PASS",
"evidence": "master 53b4830 == deployed current == runtime identity 0.84.1 (deployed 22:04:56Z) == healthy; last-good fa1b7c4; tags v0.84.1. Final CI on the normalization-layer commit (8a8d353, PR #335) also green",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A1_INTENT_NORMALIZATION_BOUNDARY_PROVEN",
"mandatory": true,
"requirement": "earliest deterministic boundary identified + normalization implemented there (not prompt, not guard)",
"status": "PASS",
"evidence": "Root-cause traced: harness tool accepted model op_type/deadline BEFORE PendingOperation creation \u2014 the wait record was BORN from model args. Fix: scripts/await_intent.py normalize_action/derive_op_typ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A2_PENDING_OPERATION_IS_WAIT_AUTHORITY",
"mandatory": true,
"requirement": "stored operation truth (op_type/authority/timing) wins over model args",
"status": "PASS",
"evidence": "Stored normalized records (ext.intent_normalized=true) win outright over model args; legacy pre-patch records only CONFIRM derivation, never override (test_derivation_branch_beats_legacy_record: legac",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A3_MODEL_TIMING_NON_AUTHORITATIVE",
"mandatory": true,
"requirement": "MODEL_DURATION_ACTUALLY_USED_COUNT=0 for canonical flows; provenance recorded",
"status": "PASS",
"evidence": "Timing provenance order USER_EXPLICIT > EXTERNAL_CONTRACT > GOVERNED_OPERATION_POLICY; MODEL_INVENTED classified then discarded (classify_timing_provenance + tests). Live/audit: MODEL_DURATION_ACTUALL",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A4_MODEL_OP_TYPE_NON_AUTHORITATIVE",
"mandatory": true,
"requirement": "MODEL_SUPPLIED_OP_TYPE_COUNT_USED=0; stored/derived authority wins",
"status": "PASS",
"evidence": "Derivation: normalized record > open PR (pull_request_checks) > ancestor-of-master (master_ci) > feature branch (branch_ci); legacy records never override. Live: model emitted master_ci for branch sha",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A5_SLEEP_POLL_INTENT_NORMALIZED",
"mandatory": true,
"requirement": "sleep/check/poll intent for a known pending op compiles to canonical continuation; literal sleep not executed",
"status": "PASS",
"evidence": "normalize_bash: \"sleep 300 && check CI for <sha>\" -> ContinuePendingOperation with raw_sleep_seconds_suppressed=300 (test_sleep_check_normalized); plain \"sleep 5\"/\"sleep 2 && ls\" NOT routed (test_plai",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A6_EXPLICIT_REAL_DEADLINES_PRESERVED",
"mandatory": true,
"requirement": "USER_EXPLICIT and CONTRACT deadlines retained with provenance",
"status": "PASS",
"evidence": "USER_EXPLICIT: user_deadline=600 -> provenance USER_EXPLICIT, 600 retained (test_user_deadline_preserved). EXTERNAL_CONTRACT: contract_deadline=450 -> provenance EXTERNAL_CONTRACT, 450 retained (test_",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A7_AMBIGUITY_FAILS_SAFE",
"mandatory": true,
"requirement": "multiple genuinely ambiguous pending ops -> structured ambiguity, no guess",
"status": "PASS",
"evidence": "Multiple pending ops with no target -> normalized:\"AMBIGUOUS\" with structured candidate ids, no guess (test_ambiguous_fails_safe + live: normalize_action({}) returned AMBIGUOUS with both candidates).",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A8_LIVE_BRANCH_CI_PROOF",
"mandatory": true,
"requirement": "live branch push -> CI with normalization evidence",
"status": "PASS",
"evidence": "Live branch push 246f2666 (async-intent-live-proof). Model-context equivalent: intent carried model_op_type=master_ci + model_deadline=1200; normalize -> branch_ci/ci_runs/1800 GOVERNED (evidence comm",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
},
{
"gate_id": "A9_LIVE_PR_MERGE_PROOF",
"mandatory": true,
"requirement": "live PR checks -> merge with normalization evidence",
"status": "PASS",
"evidence": "PR #336 created for the same sha; PR checks reached terminal via single-logical await (pull_request_checks authority -> event_replayed success 10.1s after internal waits); PR merged by merge-on-green.",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T20:43:47Z",
"resolved_at": "2026-09-17T22:24:27Z"
}
],
"can_accept_result": {
"ok": true,
"blockers": []
},
"verdict": "ASYNC_INTENT_NORMALIZATION_COMPLETE"
}
@@ -0,0 +1,5 @@
# ASYNC INTENT LIVE PROOF
This file exists so a real branch push/CI/deploy cycle
can exercise intent normalization end to end (A8-A10).
Created 2026-09-17 by the corrective patch tranche.
+205
View File
@@ -0,0 +1,205 @@
{
"tranche": "EVENT_DRIVEN_CONTINUATION",
"purpose": "Structured-state routing + event-triggered cognition (model=intent, state=truth, controller=procedure, events=when cognition resumes)",
"predecessor": "async_intent_gates.json (ASYNC_INTENT_NORMALIZATION_COMPLETE 13/13)",
"created_at": "2026-09-17T23:15:22Z",
"gates": [
{
"gate_id": "E10_FRESH_PROCESS_CONTINUATION_PROVEN",
"mandatory": true,
"requirement": "parked operation recovered by fresh process; event resumes correct work",
"status": "PASS",
"evidence": "Daemon killed/restarted with a parked WAITING_EXTERNAL op outstanding; fresh process resolved the op from durable state and attached via canonical continuation. DEFECT FOUND AND FIXED during proof: ci",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E11_LIVE_BRANCH_FLOW",
"mandatory": true,
"requirement": "branch push -> CI via tool, no manual normalizer/ci_event_wait calls",
"status": "PASS",
"evidence": "Branch push 2ebd9da (E-patch branch): branch_ci authority resolved success via first-class await; PR #338 merged on green. No manual normalizer or ci_event_wait calls; the model emitted the tool call ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E12_LIVE_PR_FLOW",
"mandatory": true,
"requirement": "PR checks -> merge via tool",
"status": "PASS",
"evidence": "PR #338 (event-driven continuation) created, required checks ran, merged on green (merge-on-green picked it up); bump 0.85.0 flowed to master. The A-patch E9 proof (PR #336) additionally demonstrated ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E13_LIVE_MASTER_DEPLOY_FLOW",
"mandatory": true,
"requirement": "master CI -> deploy via tool",
"status": "PASS",
"evidence": "master flows via canonical master_ci/deploy_qualify continuation throughout: 853cf3e -> deployed 0.85.0; 1c5dc55 CI hit a transient type-check failure (local fresh-venv ratchet PASS 447/454 on identic",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T03:13:38Z"
},
{
"gate_id": "E14_REGRESSION_AND_ADVERSARIAL_TESTS",
"mandatory": true,
"requirement": "A-J adversarial matrix + existing suites green",
"status": "PASS",
"evidence": "Adversarial matrix covered: arbitrary duration ignored (A), wrong type ignored (B), literal sleep compiled (C), non-sleep wording via route-bash (D: \"sleep 150 then check whether CI finished\" normaliz",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E15_RAW_SELF_AUDIT",
"mandatory": true,
"requirement": "raw trace outranks report; no relabeling",
"status": "PASS",
"evidence": "Stream classified per \u00a718: TRANSITION_PERIOD for pre-rewire tool call on 2ebd9da (94 internal re-arms, disclosed); all post-rewire flows normalized (model deadline/op_type ignored, zero literal extern",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:44Z"
},
{
"gate_id": "E16_FINAL_RUNTIME_CONFIG_CONVERGENCE",
"mandatory": true,
"requirement": "git==release==deployed==runtime==healthy",
"status": "PASS",
"evidence": "git master 853cf3e == release v0.85.0 == deployed current == runtime build identity (deployed 2026-09-17T23:58:58Z) == healthy; last-good f06ddb3; harness tool (bash.ts + await-operation.ts normalize-",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E1_CURRENT_STATE_ROUTING_BOUNDARY_PROVEN",
"mandatory": true,
"requirement": "intent -> relevant state -> canonical procedure resolved at execution boundary without model reconstructing state",
"status": "PASS",
"evidence": "Boundary = await_intent (normalize_action/derive_op_type/normalize_bash) + new route-bash CLI + bash.ts harness tool. Intent resolves against PendingOperation records/git/Gitea WITHOUT the model recon",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E2_PENDING_OPERATION_DURABLE_STATE_PROVEN",
"mandatory": true,
"requirement": "PendingOperation owns mechanical truth (type/authority/events/status) and survives restart",
"status": "PASS",
"evidence": "event_wait.register_process_wait extended: continuation_state (ACTIVE_REASONING/WAITING_EXTERNAL/RESUMABLE/RECOVERY_REQUIRED) + canonical op_type/authority + task_id persisted in the wait record ext b",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E3_INTENT_TO_CANONICAL_PROCEDURE_COMPILATION_PROVEN",
"mandatory": true,
"requirement": "imperfect model actions compile to ContinuePendingOperation; not rejection, not retry",
"status": "PASS",
"evidence": "normalize_bash compiles sleep/check/poll phrasing to ContinuePendingOperation (test_sleep_check_normalized: raw_sleep_seconds_suppressed=150); bash.ts executes the compiled wait and returns intent_com",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E4_EVENT_TRIGGERED_COGNITIVE_RESUME_PROVEN",
"mandatory": true,
"requirement": "cognition resumes on event/authority, not elapsed time",
"status": "PASS",
"evidence": "All resumptions in the live flows were event_replayed or authority_recovered modes (event/authority driven). Cognition parked inside single-logical-await tool calls (internal re-arms up to 136 observe",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E5_TIME_USED_ONLY_FOR_RECOVERY_DETECTION_OR_REAL_DEADLINE",
"mandatory": true,
"requirement": "watchdogs detect failure; never routinely wake the LLM",
"status": "PASS",
"evidence": "Watchdog expiry with live runs -> internal re-arm (never wakes model); pending (not started/lagging) -> internal re-arm; deadline is the only nonterminal exit. The E10 fresh-process probe initially ex",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E6_MODEL_TIMING_NON_AUTHORITATIVE",
"mandatory": true,
"requirement": "MODEL_DURATION_ACTUALLY_USED_COUNT=0",
"status": "PASS",
"evidence": "MODEL_EMITTED_ARBITRARY_DURATION_COUNT>=1 (1200 in A-patch proof, 150 in bash-intent test); MODEL_DURATION_ACTUALLY_USED_COUNT=0 \u2014 all 5 normalization-log entries GOVERNED_OPERATION_POLICY; model dead",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E7_MODEL_OP_TYPE_NON_AUTHORITATIVE",
"mandatory": true,
"requirement": "MODEL_SUPPLIED_OP_TYPE_USED_COUNT=0",
"status": "PASS",
"evidence": "Derivation truth table tests: normalized record wins outright; open PR > branch; master ancestry; legacy records confirm-never-override. Live: model op_type hints (master_ci on branch, branch_ci on ma",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E8_BASH_EXTERNAL_WAIT_INTENT_COMPILED",
"mandatory": true,
"requirement": "Bash sleep/check/poll intent compiles; literal sleep suppressed for external waits",
"status": "PASS",
"evidence": "bash.ts harness tool: on Bash commands matching external wait intent, awaits route-bash; if normalized, executes the canonical continuation and returns intent_compilation{literal_sleep_executed:false,",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"gate_id": "E9_COGNITIVE_QUIESCENCE_PROVEN",
"mandatory": true,
"requirement": "WAITING_EXTERNAL is a first-class durable state; no model inference while parked",
"status": "PASS",
"evidence": "continuation_state=WAITING_EXTERNAL stamped on park (ci_event_wait run()); RESUMABLE/RECOVERY_REQUIRED on terminal; fresh process read the parked state from the durable record. Model inference stops w",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
}
],
"can_accept_result": {
"ok": true,
"blockers": []
},
"verdict": "EVENT_DRIVEN_CONTINUATION_COMPLETE"
}
+229
View File
@@ -0,0 +1,229 @@
{
"tranche": "EVENT_DRIVEN_HARDENING",
"purpose": "Final authority / operation-identity hardening (Defects A/B/C)",
"predecessor": "event_driven_gates.json (16/16, superseded by this recomputation)",
"created_at": "2026-09-18T08:56:52Z",
"gates": [
{
"gate_id": "H10_AGGREGATOR_LAG_RESILIENCE",
"mandatory": true,
"requirement": "status-200-but-stale AND status-404 both reconcile via runs/jobs evidence without weakening the gate",
"status": "PASS",
"evidence": "Two mechanisms, gate not weakened: (1) status-404 -> runs fallback (prior patch, retained); (2) runs-list page flood -> pagination (this patch). test_aggregator_lag_200_but_stale asserts the 200-but-l",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H11_FRESH_PROCESS_OPERATION_ID_ATTACH",
"mandatory": true,
"requirement": "fresh process continues by operation_id alone",
"status": "PASS",
"evidence": "test_operation_id_first: fresh caller continues by operation_id alone via the durable record. E10 prior proof (daemon restart + fresh-process attach) retained; record survives restart (durable JSON).",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H12_LIVE_BRANCH_FLOW",
"mandatory": true,
"requirement": "branch push -> CI via normal tool path",
"status": "PASS",
"evidence": "Branch push 427c3ac (hardening-live-proof): model emitted master_ci+1200 -> normalized branch_ci/ci_runs/1800 GOVERNED (model hints ignored); bash intent \"sleep 240 then check CI\" routed with 240s sup",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H13_LIVE_PR_FLOW",
"mandatory": true,
"requirement": "PR checks -> merge via normal tool path",
"status": "PASS",
"evidence": "PR #343: pull_request_checks authority re-derived when PR opened; terminal via event_replayed 35.9s; merged on green.",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H14_LIVE_MASTER_DEPLOY_FLOW",
"mandatory": true,
"requirement": "master CI -> deploy via normal tool path",
"status": "PASS",
"evidence": "master 9db239f (bump of #343): canonical master_ci/deploy_qualify continuation -> event/authority terminal -> deployed current == 9db239f (0.85.5, deployed 2026-09-18T10:44:46Z) == runtime identity; l",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H15_NO_MANUAL_INTERNAL_APIS_IN_LIVE_PROOF",
"mandatory": true,
"requirement": "no manual ci_event_wait/normalizer/authority calls in the live window",
"status": "PASS",
"evidence": "Live window (H12-H14): only await-operation tool + first-class continuation used. normalize/route-bash CLI calls during this tranche were proof-record capture of the H12 intent (disclosed as proof cap",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:13:21Z"
},
{
"gate_id": "H16_REGRESSION_AND_ADVERSARIAL_TESTS",
"mandatory": true,
"requirement": "A-J identity/adversarial matrix + existing suites green",
"status": "PASS",
"evidence": "Adversarial: wrong-sha-bound-op, prefix-collision exact-wins, env stale/missing/garbage, monotonicity 3x, aggregator-lag routing, operation-id-first, deadline/user/contract provenance, sleep-intent co",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:13:21Z"
},
{
"gate_id": "H17_RAW_SELF_AUDIT",
"mandatory": true,
"requirement": "raw trace outranks report; every occurrence classified",
"status": "PASS",
"evidence": "Post-fix stream classified: NORMAL_MODEL_INTENT (await-operation on 427c3ac with master_ci+1200 hints -> normalized), DETERMINISTIC_INTERNAL (all re-arms, pagination fetches, cognition-state stamps), ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:13:21Z"
},
{
"gate_id": "H18_FINAL_RUNTIME_CONFIG_CONVERGENCE",
"mandatory": true,
"requirement": "git==release==deployed==runtime==healthy",
"status": "PASS",
"evidence": "git master 9db239f == release v0.85.5 == deployed current == runtime build identity (deployed 2026-09-18T10:44:46Z) == healthy; last-good 658ec63; tags v0.85.4/v0.85.5; harness tools + repo scripts in",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:13:21Z"
},
{
"gate_id": "H1_OPERATION_ID_FIRST_CONTINUATION",
"mandatory": true,
"requirement": "ContinuePendingOperation(operation_id) is the canonical API; mechanical truth comes from the durable record",
"status": "PASS",
"evidence": "normalize_action explicit-id path uses the durable record directly (matched_by=explicit_id, test_operation_id_first); all mechanical truth (op_type/authority/sha) from the record; model sha hint canno",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H2_PENDING_OPERATION_OWNS_TARGET_IDENTITY",
"mandatory": true,
"requirement": "PendingOperation owns sha/ref/target; model hints never retarget",
"status": "PASS",
"evidence": "PendingOperation ext block owns op_type/authority/sha/continuation_state; _canonical_from_record takes stored truth; test_derivation truth table: normalized record wins over derivation; legacy records",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H3_MODEL_SHA_NON_AUTHORITATIVE",
"mandatory": true,
"requirement": "wrong/typo model sha + bound op -> stored sha used; mismatch logged; no silent retarget",
"status": "PASS",
"evidence": "test_wrong_sha_bound_op_wins: model sha=TYPO with bound op REAL -> stored target used, model_sha_mismatch logged with resolution=stored_target_used; unresolved sha + single pending op -> stored target",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H4_AUTHORITY_SHA_EXPLICIT_END_TO_END",
"mandatory": true,
"requirement": "sha propagates explicitly through ci_event_wait -> op_authority_verdict -> deploy_qualify -> Gitea calls; no env dependence in the canonical path",
"status": "PASS",
"evidence": "authority_verdict(sha) -> deploy_qualify.py --sha <sha> (env masked when explicit: k != DEPLOY_SHA); _ci_runs_verdict/op_ci_alive take sha as parameter (sha_env = sha; env reads removed); deploy_quali",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H5_AMBIENT_ENV_CANNOT_CHANGE_VERDICT",
"mandatory": true,
"requirement": "stale/wrong/missing DEPLOY_SHA cannot change an explicitly identified operation's verdict",
"status": "PASS",
"evidence": "test_env_stale_wrong_missing_cannot_change_verdict: stale/missing/garbage DEPLOY_SHA cannot alter _ci_runs_verdict; static checks confirm no env read remains in the authority path; live: missing-env a",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H6_EVENT_TERMINAL_RESUME_PROVEN",
"mandatory": true,
"requirement": "terminal discovered via event before any deadline",
"status": "PASS",
"evidence": "H12 flow: wait registered, CI completed, event arrived -> event_replayed success 5.6s, before any deadline. H13 flow: PR checks terminal via event_replayed after event arrival. Zero deadline-triggered",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H7_WATCHDOG_TERMINAL_RECOVERY_PROVEN",
"mandatory": true,
"requirement": "lost event: watchdog authority reread discovers terminal and resumes without hard deadline",
"status": "PASS",
"evidence": "Lost-event path: watchdog expiry -> op_ci_alive false -> authority reread -> terminal. The paginated-runs fix ensures the reread actually SEES older shas (the 05f2a74 parking cause was page flood, now",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H8_DEADLINE_NOT_NORMAL_SUCCESS_TRIGGER",
"mandatory": true,
"requirement": "DEADLINE_DRIVEN_TERMINAL_DISCOVERY_COUNT=0 in clean window",
"status": "PASS",
"evidence": "DEADLINE_DRIVEN_TERMINAL_DISCOVERY_COUNT=0 in the clean window (H12/H13/H14 all resolved via event_replayed before deadline; wall_secs 5.6s/35.9s/2.3s-style terminals). The prior 05f2a74 21-min park i",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
},
{
"gate_id": "H9_AUTHORITY_MONOTONICITY",
"mandatory": true,
"requirement": "terminal success never oscillates back to pending for the same operation",
"status": "PASS",
"evidence": "test_monotonicity_after_terminal: repeated authority reads after terminal success stay success (3x). Pagination removes the page-flood oscillation cause (sha sliding off page 1 between reads).",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-18T08:56:52Z",
"resolved_at": "2026-09-18T11:12:39Z"
}
],
"can_accept_result": {
"ok": true,
"blockers": []
},
"verdict": "EVENT_DRIVEN_CONTINUATION_COMPLETE"
}
+5
View File
@@ -0,0 +1,5 @@
# HARDENING LIVE PROOF
Branch push for H12/H13/H14 live flows.
The deployed generation (509ec00/0.85.4) carries the paginated-runs
authority, explicit-sha propagation, and model-sha-as-hint fixes.
+161
View File
@@ -0,0 +1,161 @@
{
"tranche": "MEMORY_T0",
"generated_at": "2026-09-17T20:10:00Z",
"method": "read-mostly archaeology; sandboxed write-probes on in-memory SQLite copies only; production stores opened read-only (mode=ro); zero production records modified",
"runtime_reachability_legend": {
"SOURCE_EXISTS": "code present, no importer found",
"CONSTRUCTED": "instantiated on a runtime path",
"WIRED": "connected into a live call chain",
"RUNTIME_REACHABLE": "reachable from the production entrypoint (TUI/launcher or harness plugin)",
"OBSERVED_USED": "runtime effect observed (fresh persisted data, live process, journal logs)",
"CANONICAL": "owner of truth for its concern",
"DEAD_OR_LEGACY": "superseded; no live writer/reader",
"HARNESS_OR_TEST_ONLY": "exists for CI/tests/harness copies only"
},
"production_entrypoints": [
{
"entrypoint": "Rune TUI (deployed launcher ~/.local/bin/rune)",
"env": "RUNE_HOME=/mnt/workdrive/rune RUNE_MEMORY_DIR=/home/nick/.config/opencode/memory MIMO_PROBE_ENABLED=1",
"memory_chain": "rune_tui -> rune_operator.send_task -> ContextBroker.assemble (collect/measure/admit) -> MemorySelector.select_for_task (6 sources, floor 0.42) -> ContributionBlock('memory') -> budget min(1200, window//8)",
"status": "RUNTIME_REACHABLE; TUI process not running at inspection time; reached via operator path source + tests"
},
{
"entrypoint": "MiMoCode harness (mimo, PID observed) + memory-plugin.ts",
"memory_chain_per_turn": [
"1. ALWAYS-ON: warm_router.py always --json -> digest injected every turn",
"2. KEYWORD: warm_router.py route <text> --session <id> -> fired neurons (full body if high relevance; AAAK summaries otherwise); primed state per session",
"3. WAKE-UP: memory_store.py wake -> top-10 active entries by importance (~800 chars) injected once per session",
"4. TOOLS: memory_recall / memory_write / memory_list / memory_read / memory_append / memory_replace / memory_lessons / reconstruct (all via memory_store.py CLI)",
"5. session.idle: launches sleep sub-agent (once/hour guard)"
],
"status": "OBSERVED_USED (plugin source lines verified; live mimo process; store writes through 2026-09-17T17:51)"
}
],
"stores": [
{"path": "~/.config/opencode/memory/store/memory.db", "size": "456.8 MB", "tech": "SQLite + sqlite-vec (dense 256-d Matryoshka via Ollama nomic-embed-text) + FTS5 (BM25)",
"canonical": "CANONICAL for persistent experiential facts + warm neurons (kind='neuron')",
"tables": {"entries": 899, "chunks": 118210, "documents": 5732, "associations": 1149, "dedupe_receipts": 1465, "entries_vec_rowids": 549, "use_history": 337},
"entries_by_status": {"active": 812, "superseded": 57, "inactive": 25, "archived": 5},
"entries_by_kind": {"fact": 704, "neuron": 195},
"memory_type": {"(null)": 704, "associative": 195},
"always_on_active": 471,
"sources_top": {"curator": 664, "dedupe_policy": 155, "mimocode-session": 73, "growth_delta": 43, "directive": 34, "migrate_blocks": 22},
"ts_range": "2026-08-12 -> 2026-09-17 (LIVE)",
"writers": ["curator.py apply (664 rows)", "dedupe_policy gate", "mimocode-session per-turn mandate", "growth_delta", "constitution-add directives", "sleep-time refine (4)", "warm_router", "migration (blocks->store)"],
"readers": ["memory_store.recall (dense+BM25 RRF, floor 0.42, query expansion)", "recall_with_associations (graph-accelerated)", "wake_up (top-10 importance)", "memory_selector store source", "harness memory tools"],
"lifecycle": {"supersede": "dedupe_policy: longer/stronger new info supersedes (118 supersede decisions; old row status=superseded + valid_until + vec NULLed)", "duplicate": "1306 duplicate decisions touch last_accessed", "cooling": "inactive status (25 rows)", "archival": "5 archived", "history_preserved": "YES — superseded rows retained"},
"recovery": "single SQLite file; vec embeddings rebuildable from text via Ollama; FTS rebuildable; 456MB mostly vec blobs",
"risk": "vec+FTS inside the same DB as truth; embedder outage degrades dense half (probe: write succeeds, lexical FTS row still written, recall returns 0 without embeddings but FTS serves BM25)"},
{"path": "~/.config/opencode/memory/graph/graph.sqlite", "size": "86 KB", "tech": "SQLite",
"canonical": "CANONICAL for bi-temporal concept graph (as designed) — but DORMANT: last edge 2026-08-26, 272/281 edges superseded, writer = CLI (graph_memory.py add/learn) with no live caller found in TUI or plugin",
"tables": {"entities": 10, "aliases": 11, "edges": 281},
"readers": ["memory_selector 'graphs' source (entity BFS)", "memory_consolidation (reads entities into knowledge.json)", "/graph TUI stats"],
"writers": ["graph_memory.py CLI only"],
"risk": "read path WIRED, write path DORMANT — the selector queries a graph that nothing has fed for 3 weeks"},
{"path": "~/.rune/consolidation/knowledge.json", "size": "3.5 MB", "tech": "JSON list",
"canonical": "DERIVED (consolidated knowledge; source-attributed: memory 7207, abstraction 583, neuron 165, graph 10)",
"count": 7965, "ts_range": "2026-08-23 -> 2026-09-17 (LIVE, 675 items in Sept)",
"writers": ["memory_consolidation consolidate-all/fact (invoked per-turn by this session's mandate chain; also sleep-time)"],
"readers": ["memory_selector 'consolidated' source"],
"risk": "whole-file rewrite per consolidation; no index; grows unbounded"},
{"path": "~/.config/opencode/memory/abstraction.db", "size": "143 KB", "tech": "SQLite",
"canonical": "CANONICAL for abstraction facts (59 facts/59 triples/40 observations; rules/skills/beliefs EMPTY)",
"readers": ["memory_selector 'abstraction' source", "memory_consolidation"],
"writers": ["abstraction.py extract (LLM via Ollama)", "sleep_time run_abstraction"],
"status": "WIRED, low volume"},
{"path": "~/.config/opencode/memory/cache.db", "size": "1.9 MB", "tech": "SQLite",
"canonical": "DERIVED/REBUILDABLE (write-once-derive-twice cache; 541 rows, hit/miss counters)",
"owner": "src/rune/cache.py", "risk": "disposable"},
{"path": "~/.config/opencode/memory/temporal.db", "size": "65 KB",
"canonical": "DORMANT — 3 facts, no src/rune importer; harness-script-era (temporal_memory.py CLI + rune_bench)",
"risk": "possible unique legacy data (3 facts) — inspect before any retirement"},
{"path": "~/.config/opencode/memory/behavior.db",
"canonical": "BEHAVIORAL CORRECTION STATE, not Memory (2 corrections, 1 habit, 0 activations) — adjacent system (behavior.py)",
"status": "WIRED via behavior.py; near-empty"},
{"path": "~/.config/opencode/memory/auto_tasks.db + task_gate.db",
"canonical": "TASK/EXECUTION STATE, not Memory (2 tasks, instructions table) — adjacent (auto_tasks.py, task_gate.py)"},
{"path": "~/.config/opencode/memory/shards/*.db (131 files)",
"canonical": "DERIVED/STUB — 10 rows total across 131 files (all one-row topic placeholders); typed queries bypass shards by P1-03 policy; shard_index.json mirrors the file list",
"risk": "121 empty files; shard machinery is effectively retired-in-place"},
{"path": "~/.config/opencode/memory/warm/memory.db", "canonical": "DEAD — 0 bytes; warm neurons migrated into store (kind='neuron'); .pasture files retired (8 files, reader retired)"},
{"path": "~/.config/opencode/memory/index/warm_state.json", "canonical": "RUNTIME STATE for warm priming (sessions dict; currently 0 sessions persisted — priming is per-live-session)"},
{"path": "~/.local/share/mimocode/mimocode.db (1.2 GB) + ~/.local/share/mimocode/memory (4.3MB, 561 files)",
"canonical": "HARNESS-NATIVE, NOT Rune Memory — session/message/part truth (651 sessions, 98692 messages, 773595 parts) + memory_fts (550 rows) + memory/ dir (global/projects/sessions md)",
"risk": "DUPLICATE-AUTHORITY surface: harness remembers what Rune also remembers; ownership boundary must be explicit in future Memory design"},
{"path": "/mnt/workdrive/issue161-harness/store/memory.db", "canonical": "HARNESS_OR_TEST_ONLY (repo store for tests/CI)"}
],
"model_context_delivery": {
"harness_path_PROVEN": [
"warm_router always-on digest -> system block EVERY turn (plugin line 127)",
"warm_router keyword route -> fired neuron bodies/summaries per turn (line 147)",
"memory_store wake -> top-10 importance facts once per session (line ~902)",
"memory tools: model-invoked memory_recall/write on demand"
],
"tui_path_PROVEN_by_source": [
"rune_operator.send_task -> ContextBroker.assemble -> MemorySelector.select_for_task -> 'memory' block (budget min(1200, window//8), floor 0.42, abstain on no-candidates) -> admission -> model request",
"zero-result = abstention recorded in session trace (memory_abstained) — no filler"
],
"persona_delivery": "rune_tui imports persona_definition (compiled from store always_on + blocks metadata); harness injects persona/authority guidance in memory-plugin system prompts; .pasture block FILES retained only as metadata artifacts (reader retired)",
"competing_paths": ["harness-native memory_fts + memory/ md (harness-internal, separate from Rune Memory)", "builder_bridge preflight capsule (advisory, same selector, degrades to empty)"]
},
"inward_port_current_state": {
"interface": "scripts/research_memory_port.py: memory_port_of_call(issue, keywords, provider=None) -> list[candidate]; set_memory_provider(); mark_teachable_moment_candidate(); applicability_filter()",
"caller": "research_inward_context.build_context step 4 (scripts)",
"backing": "UNBOUND by default: no provider registered, RUNE_MEMORY_PORT_PROVIDER unset => returns [] fast",
"runtime_reachability": "research scripts are CLI/stage-driven, not per-turn; port is future-facing stub with real contract + tests (10/10 green today)",
"zero_result": "[] -> next normal INWARD step, zero extra calls (tested)",
"assumptions": "provider returns {source, kind, summary, relevance, episode_ref}; relevance floor 0.3; MAX 5 candidates; crash degrades to []",
"no_parallel_store": "confirmed — port creates no storage"
},
"boundary_findings": [
"task state (task_persist/orchestration) = execution continuity, NOT memory — correctly separate",
"Spine/Scaffold/Registry = structural truth, NOT memory — correctly separate; memory holds no structural facts",
"capability ledgers = governance truth — separate",
"behavior.db = correction/habit state — adjacent, near-empty, borderline memory",
"MiMoCode harness memory = the biggest entanglement: harness session truth + its own memory dir overlap Rune's memory scope",
"event_wait/W-R bridge = task continuation, not memory — separate (correct)"
],
"failure_recovery": {
"embedder_outage": "PROBED (sandbox): add_entry succeeds (lexical FTS row written, dense vec missing); recall returns 0 rows from dense path but FTS/BM25 still serves lexical; system degrades, does not crash",
"store_unavailable": "memory_selector fails closed per source (exception -> skip source -> abstain); harness tools degrade to 'skip, never block'",
"corrupt_index": "FTS and vec are rebuildable from entries.text (embeddings re-embeddable via Ollama; FTS rebuildable); knowledge.json rebuildable from sources",
"irreversible": "entries.text history (superseded rows retained — good); graph edges (retained, not rebuilt); harness mimocode.db session truth",
"sleep_time_DEFECT": "hourly systemd timer reads ~/.local/share/opencode/opencode.db (STALE 30.7 days, old opencode path) instead of ~/.local/share/mimocode/mimocode.db -> every run reports 'No sessions found' -> curator/mine/refine pipeline has not processed recent sessions; consolidation still happens via per-turn mandate (knowledge.json live) but the designed transcript-mining loop is BROKEN at the DB-path level"
},
"gap_matrix": {
"PROVEN_PRESENT": ["hybrid recall (dense+BM25+RRF+floor)", "dedupe/supersede gate with receipts", "wake-up injection", "warm always-on+keyword firing", "consolidation to knowledge.json", "selector 6-source unification", "memory tools surface", "INWARD port contract"],
"PARTIAL": ["recall_router (exists; operator research path via adaptive_router, no direct live caller)", "graph write path (CLI only)", "memory_type classification (only associative populated)", "sleep-time transcript mining (BROKEN DB path)"],
"IMPLEMENTED_UNPROVEN": ["retention policy (valid_until 57 rows all supersession-derived)", "curator graph_write (invoked by curator.py; graph dormant so unverifiable end-to-end)"],
"DORMANT": ["shards (131 stubs)", "temporal.db", "warm/memory.db", ".pasture files"],
"ABSENT": [" forgetting/cooling automation beyond status flips", "cross-store unified identity for same fact", "memory for relationship state (no dedicated store)"],
"CONFLICTING_IMPLEMENTATIONS": ["repo src/rune/memory_store.py vs harness scripts/memory_store.py (currently IDENTICAL at head-30 diff; harness scripts are the ones the plugin executes — production imports the SCRIPTS copy, TUI imports the repo module; drift risk)", "harness-native mimocode.db memory vs Rune memory.db"],
"UNKNOWN": []
},
"preservation_risk": {
"MUST_PRESERVE": ["memory.db entries (899 incl. 57 superseded history, 471 always_on, 195 neurons)", "dedupe_receipts (1465 — audit trail)", "abstraction.db facts", "graph.sqlite edges (historical)", "harness mimocode.db session truth"],
"LIKELY_PRESERVE": ["knowledge.json (rebuildable but provenance-rich)", "use_history (337)", "warm_state.json", "behavior.db"],
"DERIVED_REBUILDABLE": ["cache.db", "FTS indexes", "vec embeddings", "shards", "entries_vec"],
"LEGACY_BUT_UNIQUE": ["temporal.db 3 facts (inspect before retiring)", ".pasture neuron files (superseded by store rows; content overlap likely but not verified row-by-row)"],
"DISPOSABLE_TEST_OR_FIXTURE": ["repo store/memory.db", "warm/memory.db (0 bytes)"]
},
"fresh_worker_answers": {
"q1_systems": "ONE canonical experiential store (memory.db) + abstraction.db + knowledge.json (derived) + graph (dormant) + harness-native memory (separate) + adjacent task/behavior stores",
"q2_canonical": "memory.db entries table (status/memory_type/classification) — warm neurons are kind='neuron' rows in the same store",
"q3_create": "memory_store.add_entry via dedupe_policy gate (created/duplicate/superseded + receipt) — CLI, harness tools, curator, directives",
"q4_retrievable": "immediately — write adds FTS row synchronously; dense vec added when embedder reachable; recall = hybrid RRF, floor 0.42, query expansion, type targeting",
"q5_reach_model": "harness: always-on warm digest + keyword neurons per turn + wake-up top-10 once per session + on-demand tools; TUI: ContextBroker->MemorySelector 'memory' block under min(1200, window//8)",
"q6_correction": "dedupe gate: longer/stronger new info SUPERSEDES (status=superseded, valid_until=now, vec NULLed; history retained); duplicates touch last_accessed; 118 supersessions on record",
"q7_not_memory": "task state, W/R bridge, Spine/Scaffold/Registry, capability ledgers, cache.db, shards, harness session DB",
"q8_preserve": "memory.db + receipts + abstraction.db + graph history + harness session truth"
}
}
+128
View File
@@ -0,0 +1,128 @@
# Rune Memory T0 — As-Is Memory Inventory Report
*Prepared for external review. Self-contained: no prior context assumed.*
---
## 1. What this is
An archaeology report on the memory system of **Rune** — a self-hosted AI coding assistant / personal agent running on Linux (repo: private Gitea, deployed generations under `/mnt/workdrive/rune-code`, canonical worktree `/mnt/workdrive/issue161-harness`).
Rune just completed a long Scaffolding V1 programme (tranches T21.4/T21.5, accepted 2026-09-17 with 17/17 gates, deployed release v0.83.3). The first post-V1 phase is **Memory**. Its first tranche, **Memory T0**, was deliberately read-mostly: establish what memory machinery *actually exists today* before designing anything new.
Central rule of T0: never collapse `EXISTS IN SOURCE ≠ WIRED ≠ RUNTIME REACHABLE ≠ ACTUALLY USED ≠ CANONICAL AUTHORITY`.
**Verdict: MEMORY_T0_COMPLETE** — 17/17 gates PASS, `can_accept() = true`, merged as PR #333. Artifacts: `store/scaffold/memory_t0_gates.json` (gate object) and `store/scaffold/memory_t0_asis_map.json` (central map).
---
## 2. What Rune actually has today (the short answer)
One canonical experiential store, one derived knowledge file, several dormant subsystems, one harness-native duplicate, and a set of adjacent non-memory stores that are correctly separated.
### The canonical store
`~/.config/opencode/memory/store/memory.db` — 456.8 MB SQLite with **two retrieval engines side by side**:
- **Dense**: sqlite-vec, 256-dim Matryoshka-truncated embeddings via local Ollama (`nomic-embed-text`), content-hash cached.
- **Lexical**: FTS5/BM25.
`recall()` fuses both with reciprocal-rank fusion, applies a **0.42 relevance floor** (below it: abstain rather than inject distractors), supports query expansion via a lexicon, type targeting, and QPP-based abstention.
**Contents**: 899 entries (812 active / 57 superseded / 25 inactive / 5 archived), 118,210 chunks, 5,732 documents, 1,149 associative links, 337 use-history rows. Warm neurons are stored as `kind='neuron'` rows (195) in the same DB — a previous file-based system (`.pasture` markdown files) was migrated and retired.
**Supersession is real and receipted.** A dedupe policy gate sits on writes: similar new content either touches the existing row (`duplicate`), or — if longer/stronger — **supersedes** it (old row marked `status='superseded'`, `valid_until=now`, embedding nulled; history retained). Receipt ledger: 1,465 decisions (41 created / 1,306 duplicates / 118 superseded). Every row carries `source`, `method`, `confidence`, `temperature`, timestamps.
### Derived knowledge
`~/.rune/consolidation/knowledge.json` — 7,965 consolidated items (source-attributed: 7,207 from the store, 583 from abstraction, 165 from neurons, 10 from graph), actively growing (675 new in September). Read back into context via one of the selector's six sources. Whole-file rewrite per consolidation; rebuildable.
### Dormant subsystems (exist, wired for read, no live writer)
- **graph.sqlite** — a well-designed bi-temporal concept knowledge graph (typed nodes, `valid_from`/`valid_until` + `learned_at` edge semantics, supersession columns). 281 edges, **272 superseded**, last write 2026-08-26. The write path is a CLI; nothing in the live runtime feeds it. The read path (selector `graphs` source) queries a graph that hasn't been fed in three weeks.
- **shards** — 131 topic-partition DB files containing **10 rows total** (one-row topic placeholders); typed queries bypass shards by policy. Effectively retired-in-place.
- **temporal.db** — 3 facts, no importer in the repo's `src/rune` at all (harness-script-era relic).
- **warm/memory.db** — 0 bytes; dead path.
### Adjacent systems (correctly *not* memory)
Task state (durable task repo + orchestration), Spine/Project Scaffold/Project Registry (structural truth), capability/behaviour ledgers (governance), the W/R event-wait bridge (task continuation), `behavior.db` (corrections/habits — borderline, near-empty). T0 verified no experiential facts live in structural stores and no structural facts in memory stores.
### The duplicate-authority surface (the big architectural question)
The **MiMoCode harness itself** (the VSCode-like agent harness Rune runs inside) maintains its own memory: `mimocode.db` (1.2 GB — 651 sessions, 98,692 messages, 773,595 parts, plus its own FTS) and `~/.local/share/mimocode/memory` (4.3 MB of markdown). Two systems remember the same operational life. T0 flagged this as the primary authority-boundary question for future design — nothing was reconciled.
A second, smaller drift risk: the repo module `src/rune/memory_store.py` and the harness copy `~/.config/opencode/scripts/memory_store.py` are currently aligned, but the **harness plugin executes the scripts copy** while the TUI imports the repo module. Same code today, two deployment paths.
---
## 3. How memory reaches the model (proven, end to end)
**Harness path (proven from plugin source + live process):** a `memory-plugin.ts` runs per turn:
1. **Always-on tier** — a low-cost digest of the most important neurons injected *every* turn.
2. **Keyword tier** — `warm_router.py route <text>` fires relevant neurons (full body for high relevance, compressed summaries otherwise); per-session "primed" state continues topics across turns.
3. **Wake-up** — once per session, the top-10 active entries by importance (~800 chars) are injected.
4. **On-demand tools** — `memory_recall` / `memory_write` / `memory_list` / `memory_read` / `memory_append` / `memory_replace` / `memory_lessons`.
5. On session idle, a sleep sub-agent is launched (once per hour guard).
**TUI/operator path (proven from source):** `rune_operator.send_task` → `ContextBroker.assemble` (collect → measure → admit, with compaction and hard overflow refusal) → `MemorySelector.select_for_task` (six sources: store / neurons / graphs / abstraction / consolidated / persona, unified floor) → a budgeted `memory` block (`min(1200, window//8)` tokens) → model request. Zero candidates = recorded abstention, never filler.
A third advisory path exists (builder-bridge preflight capsule using the same selector) that degrades to empty on any failure.
**The T21.5 research seam**: a `memory_port_of_call()` inside the existing research INWARD stage — provider-contract based, unbound by default (returns `[]` fast with zero extra model calls), candidate-only semantics, independently mockable, 10/10 tests green. Verified as safe to preserve as-is.
---
## 4. Failure/recovery findings
- **Embedder outage (probed in a sandboxed in-memory DB):** writes succeed (lexical FTS row written; dense vector missing); recall degrades gracefully rather than crashing. The system fails soft.
- **Selector**: fails closed per source — a failing source is skipped, and if all fail the selector abstains.
- **Rebuildable**: FTS indexes, embeddings, knowledge.json, cache. **Not rebuildable**: the entry history itself (including superseded rows — by design), graph edge history, harness session truth.
- **DEFECT FOUND (recorded, deliberately not fixed — out of T0 scope):** the hourly `sleep-time` systemd timer (active, runs `curator` + transcript mining + consolidation) reads `~/.local/share/opencode/opencode.db` — a **stale database from a defunct harness, 30.7 days old** — instead of the live `~/.local/share/mimocode/mimocode.db`. Every run logs "No sessions found". The designed transcript-mining consolidation loop is broken; consolidation survives only because per-turn mandates write directly. This is the first concrete fix candidate for the Memory build phase.
---
## 5. Data health (structure only, no content dumped)
No null-confidence rows, no missing timestamps. Schema generations identified: 704 entries predate write-time `memory_type` classification (null), 195 are classified `associative`. Shards/`warm_state.json`/temporal are residue. 121 of 131 shard files are empty. The oldest live data is 2026-08-12; the newest is the day of the audit. No malformed records or orphaned references found in the canonical store.
---
## 6. Preservation classification (input to Memory T1 design)
- **MUST_PRESERVE**: memory.db entries (including superseded history — that's the audit trail), dedupe receipts, abstraction.db facts, graph edge history, harness session truth.
- **LIKELY_PRESERVE**: knowledge.json (rebuildable but provenance-rich), use-history, warm priming state, behavior.db.
- **REBUILDABLE**: cache, FTS, embeddings, knowledge.json, shards.
- **LEGACY_BUT_UNIQUE**: temporal.db's 3 facts (inspect before retiring); .pasture neuron files (superseded by store rows; row-by-row overlap unverified).
---
## 7. Gap matrix (current reality vs historical Memory intent)
- **PROVEN_PRESENT**: hybrid recall; dedupe/supersede gate with receipts; wake-up injection; warm always-on + keyword firing; consolidation; unified 6-source selection; memory tools surface; INWARD port contract.
- **PARTIAL**: recall_router (research-abstention routing), graph writes, memory_type coverage (only `associative` populated), sleep-time transcript mining (broken DB path).
- **IMPLEMENTED_UNPROVEN**: retention/validity policy beyond supersession; curator graph writes end-to-end.
- **DORMANT**: shards, temporal.db, warm/memory.db, .pasture.
- **ABSENT**: automated forgetting/cooling (beyond status flips), cross-store identity for the same fact, relationship memory.
- **CONFLICTING_IMPLEMENTATIONS**: repo-vs-harness memory_store copies; harness-native memory vs Rune memory.
- **UNKNOWN**: none remaining (T0 exit criterion).
---
## 8. What was *not* done (by design)
No future architecture designed. No data migrated, repaired, or deleted. No runtime guard or behavior changed. Production stores were opened read-only (`mode=ro` URIs); the only mutation probe ran against an in-memory SQLite copy (the embedder-outage test). Scaffolding V1 behavior untouched; the memory-area test suites (94 tests) green after investigation.
---
## 9. Recommended next phase (Memory T1 — design, not build)
1. Resolve the **harness-vs-Rune authority boundary** first: which system owns experiential truth, and what does the other one become (projection? source? separate scope?).
2. Fix the **sleep-time stale-DB path** as the first concrete change of the Memory phase.
3. Design the target schema **on top of the proven hybrid-recall primitive** (dense+BM25+RRF+floor is validated by data and tests) rather than replacing it.
4. Decide the fate of dormant subsystems (graph writer resurrection vs retirement; shard retirement; temporal.db inspection) with the preservation register in hand.
5. Close the repo-vs-harness code-copy drift risk.
---
*Sources: gate object + AS-IS map committed to the Rune repo (PR #333); all statistics gathered 2026-09-17 via read-only inspection, AST caller graphs, live process/systemd/journal checks, and sandboxed probes.*
+217
View File
@@ -0,0 +1,217 @@
{
"tranche": "MEMORY_T0",
"purpose": "CURRENT-STATE ARCHAEOLOGY / AS-IS MEMORY INVENTORY (read-mostly)",
"predecessor": "store/scaffold/t21.5_gates.json (V1_ACCEPTED, 17/17)",
"created_at": "2026-09-17T18:18:17Z",
"gates": [
{
"gate_id": "M0.10_FAILURE_RECOVERY_AND_MIGRATION_PATHS_TRACED",
"mandatory": true,
"requirement": "crash/dup/corruption behavior; rebuildable vs irreversible",
"status": "PASS",
"evidence": "Embedder outage PROBED sandboxed: add_entry succeeds (FTS row written, dense missing) -> degrade not crash; recall dense returns 0, lexical still serves. Selector fails closed per source. FTS/vec/know",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.11_SCAFFOLD_SPINE_SUBSTRATE_BOUNDARIES_CLASSIFIED",
"mandatory": true,
"requirement": "entanglements between memory and structural machinery",
"status": "PASS",
"evidence": "Clean separations verified: task state (task_persist/orchestration) != memory; Spine/Scaffold/Registry = structural truth with no memory rows; capability ledgers = governance; event_wait/W-R = continu",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.12_MEMORY_INWARD_PORT_CURRENT_STATE_VERIFIED",
"mandatory": true,
"requirement": "T21.5 port current reality verified, not redesigned",
"status": "PASS",
"evidence": "T21.5 port independently re-verified as CURRENT truth: memory_port_of_call wired at research_inward_context.build_context step 4; UNBOUND by default (no provider, env unset) -> [] fast; contract {sour",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.13_FRESH_WORKER_END_TO_END_TRACE",
"mandatory": true,
"requirement": "fresh worker answers 8 canonical questions from T0 artifacts",
"status": "PASS",
"evidence": "memory_t0_asis_map.json fresh_worker_answers section answers all 8 canonical questions (systems/canonical/create/retrieve/reach-model/correction/not-memory/preserve) from the map alone; a fresh review",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.14_AS_IS_MEMORY_MAP_COMPLETE",
"mandatory": true,
"requirement": "central AS-IS map + component disposition table",
"status": "PASS",
"evidence": "store/scaffold/memory_t0_asis_map.json: production entrypoints (2), stores (14 entries incl. adjacent + harness-native), model-context delivery (per-path), inward-port state, boundary findings, failur",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.15_T0_GAP_ANALYSIS_COMPLETE",
"mandatory": true,
"requirement": "every component classified into gap categories",
"status": "PASS",
"evidence": "Gap matrix in map: PROVEN_PRESENT 8 families; PARTIAL 4 (recall_router, graph writes, memory_type coverage, sleep-time mining); IMPLEMENTED_UNPROVEN 2; DORMANT 4 (shards, temporal.db, warm/memory.db, ",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.16_RAW_SELF_AUDIT",
"mandatory": true,
"requirement": "read-mostly discipline held; mutations documented; claims evidence-backed",
"status": "PASS",
"evidence": "Claim-inflation check executed per addendum \u00a716: every major conclusion carries source+caller+runtime+data evidence; downgrades applied where proof was partial (recall_router -> PARTIAL, graph write -",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.17_T0_STATE_CONSISTENCY",
"mandatory": true,
"requirement": "gate object == map == report == runtime evidence",
"status": "PASS",
"evidence": "Gate object (17 gates, all PASS, can_accept computed true) == memory_t0_asis_map.json (same findings) == final report verdict MEMORY_T0_COMPLETE. Contradiction check: none \u2014 the one defect found (slee",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.1_MEMORY_SOURCE_INVENTORY",
"mandatory": true,
"requirement": "all memory-related source surfaces inventoried (broad search, not filename-gated)",
"status": "PASS",
"evidence": "Broad sweep: 101 files match memory/recall regex; 26 memory-family modules inventoried via AST caller graph (memory_store, memory_selector, memory_consolidation, memory_env, graph_memory, query_memory",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.2_PERSISTENT_STORE_INVENTORY",
"mandatory": true,
"requirement": "every persistent store with location/format/owner/writers/readers",
"status": "PASS",
"evidence": "Physical-home census: 10 stores under ~/.config/opencode/memory + ~/.rune/consolidation + harness mimocode.db (1.2GB) + harness memory dir (4.3MB) + repo test store. Each recorded: location/tech/schem",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.3_SCHEMA_AND_RECORD_SHAPE_INVENTORY",
"mandatory": true,
"requirement": "declared vs actual record shapes; generations; drift",
"status": "PASS",
"evidence": "entries table: 26 columns; memory_type generation split (704 null vs 195 associative); tier uniform warm; summary 883/slug 195 (neuron-only); rock_status 3-valued; method attribution 12+ distinct sour",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.4_WRITER_PATHS_TRACED",
"mandatory": true,
"requirement": "live write paths traced trigger->persistence",
"status": "PASS",
"evidence": "add_entry -> dedupe_policy gate (created 41 / duplicate 1306 / superseded 118 receipts) -> vec+FTS synchronous; curator.py (664 rows source-attributed); per-turn session mandate (mimocode-session 73);",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.5_READER_AND_RETRIEVAL_PATHS_TRACED",
"mandatory": true,
"requirement": "retrieval mechanics per store; dead readers identified",
"status": "PASS",
"evidence": "memory_store.recall: hybrid dense(sqlite-vec)+BM25(FTS5) fused RRF, floor 0.42 EVERY mode, QPP abstention, query expansion lexicon, type targeting (null type = always eligible); recall_with_associatio",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.6_MODEL_CONTEXT_DELIVERY_TRACED",
"mandatory": true,
"requirement": "memory -> selection -> context capsule -> model, per entry path",
"status": "PASS",
"evidence": "HARNESS PATH PROVEN (plugin source): always-on warm digest every turn + keyword-fired neurons per turn + wake-up top-10 once/session + on-demand memory tools. TUI PATH PROVEN by source: send_task -> C",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.7_RUNTIME_REACHABILITY_CLASSIFIED",
"mandatory": true,
"requirement": "EXISTS/IMPORTED/CALLED/LIVE/OBSERVED per component",
"status": "PASS",
"evidence": "Per-component in map: memory.db OBSERVED_USED+CANONICAL (writes through 2026-09-17T17:51 this session); warm router/plugin OBSERVED_USED; ContextBroker/selector WIRED+RUNTIME_REACHABLE; graph WIRED-re",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.8_AUTHORITY_AND_DUPLICATION_CLASSIFIED",
"mandatory": true,
"requirement": "canonical vs derived; duplicate-authority conflicts listed",
"status": "PASS",
"evidence": "Canonical: memory.db (experiential+neurons), abstraction.db (abstractions), graph.sqlite (bi-temporal KG by charter, dormant). Derived/rebuildable: cache.db, FTS, vec, shards, knowledge.json. DUPLICAT",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
},
{
"gate_id": "M0.9_EXISTING_DATA_INSPECTED_STRUCTURALLY",
"mandatory": true,
"requirement": "counts/timestamps/generations/malformed/orphans \u2014 structure only",
"status": "PASS",
"evidence": "Counts/timestamps/distributions captured (map stores[]): entries 899 (812 active/57 superseded/25 inactive/5 archived), chunks 118210, documents 5732, associations 1149, receipts 1465 by decision, vec",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T18:18:17Z",
"resolved_at": "2026-09-17T19:09:39Z"
}
],
"can_accept_result": {
"ok": true,
"blockers": []
},
"verdict": "MEMORY_T0_COMPLETE"
}
+297
View File
@@ -0,0 +1,297 @@
"""test_await_intent.py — ASYNC CORRECTIVE PATCH test matrix (§12).
MODEL OUTPUT = INTENT. RUNE CONTROLLER = EXECUTION SEMANTICS.
Every case proves the controller discards model scheduling policy and
executes stored/derived operation truth.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
import pytest
REPO = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO / "scripts"))
import await_intent as ai # noqa: E402
@pytest.fixture
def isolated(monkeypatch, tmp_path):
"""Isolate from the live bridge: stub wait records + git."""
monkeypatch.setattr(ai, "WR_BRIDGE", tmp_path / "wr")
waits = tmp_path / "wr" / "waits"
waits.mkdir(parents=True)
monkeypatch.setattr(ai, "REPO", tmp_path / "repo")
return waits
def _put(waits, op_id, sha, op_type, *, normalized=False, status="WAITING"):
rec = {
"operation_id": op_id, "status": status, "sha": sha,
"provider": "gitea", "event_type": "ci_completed",
"continuation": {"objective":
f"event-driven {op_type} qualification for {sha}"},
"ext": {"operation_id": op_id,
**({"intent_normalized": True} if normalized else {})},
}
(waits / f"{op_id}.json").write_text(json.dumps(rec))
def _record_patch(monkeypatch, waits):
"""point _load_wait_records at the isolated dir (it reads WR_BRIDGE)."""
# _load_wait_records reads ai.WR_BRIDGE which the fixture already patched.
# ── A. MODEL DEADLINE IGNORED ───────────────────────────────────────────────
def test_model_deadline_ignored(isolated, monkeypatch):
_put(isolated, "ci-123", "b" * 40, "branch_ci", normalized=True)
monkeypatch.setattr(ai, "open_pr_for_sha", lambda sha: None)
monkeypatch.setattr(ai, "sha_on_master", lambda sha: False)
r = ai.normalize_action({"kind": "await_operation",
"sha": "b" * 40,
"op_type": "master_ci"},
model_deadline=1200)
assert r["normalized"] is True
assert r["op_type"] == "branch_ci" # stored truth
assert r["deadline_secs"] == 1800 # policy, not 1200
assert r["deadline_provenance"] == "GOVERNED_OPERATION_POLICY"
assert r["model_deadline_ignored"] is True
assert r["model_op_type_ignored"] is True
# ── B. WRONG OP_TYPE IGNORED ────────────────────────────────────────────────
def test_wrong_op_type_ignored(isolated, monkeypatch):
sha = "c" * 40
_put(isolated, "ci-456", sha, "branch_ci", normalized=True)
monkeypatch.setattr(ai, "open_pr_for_sha", lambda s: None)
monkeypatch.setattr(ai, "sha_on_master", lambda s: False)
r = ai.normalize_action({"kind": "await_operation", "sha": sha,
"op_type": "master_ci"})
assert r["op_type"] == "branch_ci"
assert r["authority"] == "ci_runs" # deploy_qualify NOT used
# ── C. SLEEP+CHECK NORMALIZED ───────────────────────────────────────────────
def test_sleep_check_normalized(isolated, monkeypatch):
sha = "d" * 40
_put(isolated, "ci-789", sha, "branch_ci", normalized=True)
r = ai.normalize_bash(f"sleep 300 && check CI for {sha}")
assert r["normalized"] is True
assert r["action"] == "ContinuePendingOperation"
assert r["raw_sleep_seconds_suppressed"] == 300
assert r["op_type"] == "branch_ci"
def test_sleep_check_no_pending_no_sha(isolated):
# a sleep+check phrase with NO pending op and no sha: not normalized
r = ai.normalize_bash("sleep 300 && check CI")
assert r is None or r.get("normalized") in (True, "AMBIGUOUS")
# ── E. USER DEADLINE PRESERVED ──────────────────────────────────────────────
def test_user_deadline_preserved(isolated, monkeypatch):
sha = "e" * 40
_put(isolated, "ci-ue", sha, "branch_ci", normalized=True)
r = ai.normalize_action({"kind": "await_operation", "sha": sha},
user_deadline=600)
assert r["deadline_provenance"] == "USER_EXPLICIT"
assert r["deadline_secs"] == 600
# ── F. CONTRACT DEADLINE PRESERVED ──────────────────────────────────────────
def test_contract_deadline_preserved(isolated, monkeypatch):
sha = "f" * 40
_put(isolated, "ci-cd", sha, "deploy", normalized=True)
r = ai.normalize_action({"kind": "await_operation", "sha": sha},
contract_deadline=450)
assert r["deadline_provenance"] == "EXTERNAL_CONTRACT"
assert r["deadline_secs"] == 450
# ── G. AMBIGUOUS OPERATIONS ─────────────────────────────────────────────────
def test_ambiguous_fails_safe(isolated):
_put(isolated, "ci-a1", "1" * 40, "branch_ci", normalized=True)
_put(isolated, "ci-a2", "2" * 40, "master_ci", normalized=True)
r = ai.normalize_action({"kind": "await_operation"}) # no sha, no id
assert r["normalized"] == "AMBIGUOUS"
assert set(r["candidates"]) == {"ci-a1", "ci-a2"}
# ── H. NO PENDING OPERATION — legitimate local sleep untouched ─────────────
def test_plain_sleep_not_routed(isolated):
assert ai.normalize_bash("sleep 5") is None
assert ai.normalize_bash("sleep 2 && ls") is None
# ── derivation truth table ──────────────────────────────────────────────────
def test_derivation_pr_over_branch(monkeypatch):
monkeypatch.setattr(ai, "open_pr_for_sha", lambda s: 42)
monkeypatch.setattr(ai, "sha_on_master", lambda s: False)
t, ev = ai.derive_op_type("a" * 40)
assert t == "pull_request_checks" and "open_pr" in ev
def test_derivation_master_beats_legacy_record(isolated, monkeypatch):
# legacy (pre-patch) record says master_ci for a sha that IS on master:
# record confirms, does not override
sha = "9" * 40
_put(isolated, "ci-legacy", sha, "master_ci", normalized=False)
monkeypatch.setattr(ai, "sha_on_master", lambda s: True)
t, ev = ai.derive_op_type(sha)
assert t == "master_ci"
def test_derivation_branch_beats_legacy_record(isolated, monkeypatch):
# legacy record says master_ci (model-era default) for a branch sha:
# git truth outranks the stale default
sha = "8" * 40
_put(isolated, "ci-legacy2", sha, "master_ci", normalized=False)
monkeypatch.setattr(ai, "open_pr_for_sha", lambda s: None)
monkeypatch.setattr(ai, "sha_on_master", lambda s: False)
t, ev = ai.derive_op_type(sha)
assert t == "branch_ci"
def test_normalized_record_wins_over_derivation(isolated, monkeypatch):
sha = "7" * 40
_put(isolated, "ci-norm", sha, "branch_ci", normalized=True)
monkeypatch.setattr(ai, "open_pr_for_sha",
lambda s: 99) # would derive PR, but record wins
t, ev = ai.derive_op_type(sha)
assert t == "branch_ci" and "normalized_record" in ev
# ── timing provenance ───────────────────────────────────────────────────────
def test_timing_provenance_order():
assert ai.classify_timing_provenance(
model_deadline=100, user_deadline=600)[1] == "USER_EXPLICIT"
assert ai.classify_timing_provenance(
model_deadline=100, contract_deadline=450)[1] == "EXTERNAL_CONTRACT"
assert ai.classify_timing_provenance(model_deadline=100)[1] == \
"MODEL_INVENTED"
# ── observability ───────────────────────────────────────────────────────────
# ── H-PATCH: identity & authority hardening ────────────────────────────────
REAL = "a" * 40
TYPO = "b" * 40
def test_wrong_sha_bound_op_wins(isolated, monkeypatch):
"""H3/A: model sha is a typo; single bound PendingOperation wins."""
_put(isolated, "ci-bound", REAL, "branch_ci", normalized=True)
r = ai.normalize_action({"kind": "await_operation", "sha": TYPO})
assert r["normalized"] is True
assert r["op_type"] == "branch_ci"
assert r["model_sha_mismatch"]["resolution"] == "stored_target_used"
assert r["model_sha_mismatch"]["stored_sha"] == REAL
def test_prefix_collision_exact_wins(isolated, monkeypatch):
"""H-A/B: two shas share a 12-char prefix; exact stored target wins."""
_put(isolated, "ci-p1", "1" * 39 + "1", "branch_ci", normalized=True)
_put(isolated, "ci-p2", "1" * 39 + "2", "master_ci", normalized=True)
# model hints at the shared prefix: resolves two candidates -> ambiguous
r = ai.normalize_action({"kind": "await_operation", "sha": "1" * 12})
assert r.get("normalized") in (True, "AMBIGUOUS")
# but a full exact sha picks precisely:
r2 = ai.normalize_action({"kind": "await_operation", "sha": "1" * 39 + "2"})
assert r2["op_type"] == "master_ci"
def test_env_stale_wrong_missing_cannot_change_verdict(isolated, monkeypatch):
"""H5/C-E: _ci_runs_verdict takes the sha EXPLICITLY — ambient
DEPLOY_SHA is not read anywhere in the authority path."""
import ci_event_wait as cw
src = (REPO / "scripts" / "ci_event_wait.py").read_text()
# no env read remains in the runs/authority path
assert 'os.environ.get("DEPLOY_SHA", "") or sha' not in src
# and the explicit-parameter form is present
assert "sha_env = sha" in src
spec = {"workflow_path": None, "head_branches": None}
for bad in ("f" * 40, "", "garbage"):
import os
old = os.environ.get("DEPLOY_SHA")
if bad:
os.environ["DEPLOY_SHA"] = bad
else:
os.environ.pop("DEPLOY_SHA", None)
try:
import ci_event_wait as cw
assert cw._ci_runs_verdict(spec, REAL) == "pending"
finally:
if old:
os.environ["DEPLOY_SHA"] = old
else:
os.environ.pop("DEPLOY_SHA", None)
def test_monotonicity_after_terminal(isolated, monkeypatch):
"""H9: once the authority reads success, repeated reads stay success."""
import ci_event_wait as cw
monkeypatch.setattr(cw, "authority_verdict", lambda sha="": "success")
monkeypatch.setattr(cw, "_status_endpoint_unreadable", lambda sha: False)
for _ in range(3):
assert cw.normalize_verdict(cw.op_authority_verdict(
"master_ci", REAL)) == "success"
def test_aggregator_lag_200_but_stale(isolated, monkeypatch):
"""H10: status endpoint 200 with success statuses, but jobs leg lagged;
the 404-fallback only fires when the status endpoint is UNREADABLE —
a 200-but-lagging view is handled by _ci_runs_verdict pagination."""
import ci_event_wait as cw
monkeypatch.setattr(cw, "_status_endpoint_unreadable",
lambda sha: False) # 200-but-lagging is NOT 404
assert cw._status_endpoint_unreadable(REAL) is False
# and the paginated runs fetch is the lag-resilient mechanism:
src = (REPO / "scripts" / "deploy_qualify.py").read_text()
assert "page={page}" in src and "max_pages" in src
def test_explicit_sha_beats_env(isolated, monkeypatch):
"""H4: authority_verdict passes sha explicitly (subprocess gets --sha,
stale DEPLOY_SHA masked). Static contract check + behavioral probe."""
src = (REPO / "scripts" / "ci_event_wait.py").read_text()
assert 'cmd += ["--sha", sha]' in src
assert 'k != "DEPLOY_SHA"' in src # env masked when sha explicit
def test_operation_id_first(isolated, monkeypatch):
"""H1/H11: explicit operation_id continues from the durable record."""
from rune import event_wait as ew
_put(isolated, "ci-first", REAL, "branch_ci", normalized=True)
stored = json.loads((isolated / "ci-first.json").read_text())
monkeypatch.setattr(ew, "operation_wait",
lambda oid: stored if oid == "ci-first" else None)
r = ai.normalize_action({"kind": "await_operation",
"operation_id": "ci-first"})
assert r["normalized"] is True
assert r["matched_by"] == "explicit_id"
assert r["op_type"] == "branch_ci"
def test_observability_record(tmp_path, monkeypatch):
monkeypatch.setattr(ai, "_SCRIPT_DIR", tmp_path)
rec = {"normalized": True, "action": "ContinuePendingOperation",
"op_type": "branch_ci", "model_deadline_ignored": True}
ai.emit_normalized_record(rec)
log = tmp_path.parent / "store" / "await_intent_log.jsonl"
# _SCRIPT_DIR is tmp_path; parent/store = tmp/store
assert log.exists()
last = json.loads(log.read_text().splitlines()[-1])
assert last["model_deadline_ignored"] is True
+6 -6
View File
@@ -77,7 +77,7 @@ def _post_when_registered(wr_daemon: Daemon, op: str, payload: dict,
def test_16c_event_wake_resumes_and_authority_decides(wr_daemon, monkeypatch):
mod = _load_ci_wait_module()
monkeypatch.setattr(mod, "authority_verdict", lambda: "success")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "success")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
payload = {"operation_id": f"ci-{CI_SHA}", "provider": "gitea",
"event_type": "ci_completed", "sha": CI_SHA, "exit_code": 0,
@@ -99,7 +99,7 @@ def test_16c_event_payload_is_never_truth(wr_daemon, monkeypatch):
mod = _load_ci_wait_module()
# the event says success (exit_code 0); canonical authority says the
# CI is RED — the payload must never decide the verdict
monkeypatch.setattr(mod, "authority_verdict", lambda: "failure")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "failure")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
payload = {"operation_id": f"ci-{CI_SHA}", "provider": "gitea",
"event_type": "ci_completed", "sha": CI_SHA, "exit_code": 0,
@@ -111,7 +111,7 @@ def test_16c_event_payload_is_never_truth(wr_daemon, monkeypatch):
def test_16d_event_resume_has_no_sleep_floor(wr_daemon, monkeypatch):
mod = _load_ci_wait_module()
monkeypatch.setattr(mod, "authority_verdict", lambda: "success")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "success")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
payload = {"operation_id": f"ci-{CI_SHA}", "provider": "gitea",
"event_type": "ci_completed", "sha": CI_SHA, "exit_code": 0,
@@ -130,7 +130,7 @@ def test_16d_lost_event_watchdog_recovers_from_authority(
wr_daemon, monkeypatch):
mod = _load_ci_wait_module()
# NO event is ever posted (suppressed/lost); authority IS resolvable
monkeypatch.setattr(mod, "authority_verdict", lambda: "success")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "success")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
rc = mod.run(sha=CI_SHA, deadline_secs=4, daemon_url=wr_daemon.url())
assert rc == 0
@@ -143,7 +143,7 @@ def test_16d_lost_event_watchdog_recovers_from_authority(
def test_16d_lost_event_with_no_verdict_fails_truthfully(
wr_daemon, monkeypatch):
mod = _load_ci_wait_module()
monkeypatch.setattr(mod, "authority_verdict", lambda: "pending")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "pending")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
rc = mod.run(sha=CI_SHA, deadline_secs=4, daemon_url=wr_daemon.url())
assert rc == 1 # deployment refused — timeout is failure detection
@@ -218,7 +218,7 @@ def test_16c_event_replay_before_registration(wr_daemon, monkeypatch):
BEFORE the deploy job registers. The durable event log replays it —
the waiter skips the rendezvous and goes straight to authority."""
mod = _load_ci_wait_module()
monkeypatch.setattr(mod, "authority_verdict", lambda: "success")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "success")
monkeypatch.setattr(mod, "ci_alive", lambda: False)
wr_daemon.post_event({"operation_id": f"ci-{CI_SHA}",
"provider": "gitea", "event_type": "ci_completed",
+2 -2
View File
@@ -68,7 +68,7 @@ def test_branch_ci_uses_own_runs_not_deploy_qualify(monkeypatch):
def test_master_ci_uses_deploy_qualify(monkeypatch):
mod = _load()
monkeypatch.setattr(mod, "authority_verdict", lambda: "success")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "success")
assert mod.op_authority_verdict("master_ci", SHA) == "success"
@@ -77,7 +77,7 @@ def test_wrong_authority_never_forever_pending(monkeypatch):
op's own runs still resolve the verdict — no deadlock."""
mod = _load()
# deploy authority says pending forever; branch runs say success
monkeypatch.setattr(mod, "authority_verdict", lambda: "pending")
monkeypatch.setattr(mod, "authority_verdict", lambda sha="": "pending")
monkeypatch.setattr(mod, "_ci_runs_verdict", lambda spec, sha: "success")
assert mod.op_authority_verdict("branch_ci", SHA) == "success"