Compare commits

..
Author SHA1 Message Date
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
15 changed files with 1114 additions and 13 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.83.4**
**Current release: v0.85.2**
**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.4"
version = "0.85.2"
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
+375
View File
@@ -0,0 +1,375 @@
"""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
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:
return _canonical_from_record(candidates[0], model_deadline_ignored,
model_op_type_ignored, "pending_match",
user_deadline, contract_deadline)
# 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)
else:
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,
}
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())
+62 -3
View File
@@ -169,12 +169,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())
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)."""
@@ -264,6 +287,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 +320,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 +340,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 +377,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 +461,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 +495,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)
+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.4"
__version__ = "0.85.2"
# 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.4"' in rune_version,
'__version__ = "0.85.2"' 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.4
Version: v0.85.2
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.4 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.85.2 | 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 853cf3e (bump) -> canonical master_ci/deploy_qualify continuation -> event_replayed success 6.6s -> deployed current == 853cf3e (0.85.0, deployed 2026-09-17T23:58:58Z) == runtime identity; last",
"blocker": "",
"waiver_reason": "",
"waived_by": "",
"declared_at": "2026-09-17T23:15:22Z",
"resolved_at": "2026-09-18T00:14:02Z"
},
{
"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"
}
+197
View File
@@ -0,0 +1,197 @@
"""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 ───────────────────────────────────────────────────────────
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