Compare commits

..
Author SHA1 Message Date
Nick da61fd7d44 docs: webhook delivery test marker 2
CI Pipeline / lint (push) Failing after 24s
CI Pipeline / best-practices (push) Successful in 5s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 30s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / unit-tests (push) Successful in 57s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:31:12 +01:00
Nick 7342d77e6f docs: webhook delivery test 2
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 6s
CI Pipeline / lint (push) Failing after 31s
CI Pipeline / canary (push) Successful in 33s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / unit-tests (push) Successful in 1m0s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:31:02 +01:00
Nick 436f760675 docs: webhook delivery test marker
CI Pipeline / lint (push) Failing after 26s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / gitea-offline (push) Successful in 15s
deploy / deploy (push) Skipped
CI Pipeline / canary (push) Successful in 48s
CI Pipeline / best-practices (push) Successful in 3s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / unit-tests (push) Successful in 58s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:28:42 +01:00
Nick d62b717542 test: deliberate lint failure (wait/resume Part 14)
CI Pipeline / lint (push) Failing after 26s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 29s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / type-check (push) Successful in 29s
CI Pipeline / unit-tests (push) Successful in 58s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:14:41 +01:00
Nick 97de570b27 test: deliberate lint failure fixture (wait/resume failure experiment)
CI Pipeline / lint (push) Failing after 27s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / canary (push) Successful in 31s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / unit-tests (push) Successful in 54s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:13:41 +01:00
Nick 22aebbb102 test: intentionally broken syntax for W/R failure experiment
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / lint (push) Failing after 27s
CI Pipeline / canary (push) Successful in 30s
deploy / deploy (push) Skipped
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 59s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:13:27 +01:00
Nick 7e33294527 docs: wait/resume live experiment marker (branch)
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / lint (push) Successful in 40s
deploy / deploy (push) Skipped
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Successful in 58s
CI Pipeline / required-checks (push) Successful in 1s
2026-09-12 00:07:52 +01:00
conductor fcc9989393 chore(release): auto-bump version to 0.66.14 — earned by # (patch: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 16s
CI Pipeline / required-checks (push) Successful in 2s
CI Pipeline / lint (push) Successful in 34s
CI Pipeline / unit-tests (push) Successful in 55s
CI Pipeline / canary (push) Successful in 27s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 15s
deploy / deploy (push) Successful in 1m9s
Promotion record: (unknown)
2026-09-11 22:54:16 +01:00
Nick ead4a24866 fix(ci): allow the reconciliation JSON authority in top-level docs henxel
Auto-version and Release / release (push) Successful in 48s
CI Pipeline / best-practices (push) Successful in 6s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / canary (push) Successful in 32s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / unit-tests (push) Successful in 1m0s
CI Pipeline / lint (push) Successful in 33s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 3m10s
2026-09-11 22:53:48 +01:00
conductor cf51f7fd7c chore(release): auto-bump version to 0.66.13 — earned by # (minor: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 10s
deploy / deploy (push) Successful in 1m17s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / lint (push) Failing after 35s
CI Pipeline / unit-tests (push) Successful in 54s
CI Pipeline / canary (push) Successful in 27s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / gitea-offline (push) Successful in 15s
Promotion record: (unknown)
2026-09-11 22:51:10 +01:00
Nick f182ab8601 feat(reconciliation): canonical issue reconciliation artifact + consistency checker (T15 Parts J/K/L)
CI Pipeline / best-practices (push) Successful in 9s
CI Pipeline / documentation (push) Successful in 5s
Auto-version and Release / release (push) Successful in 30s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / lint (push) Failing after 42s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 1m2s
CI Pipeline / required-checks (push) Successful in 4s
deploy / deploy (push) Successful in 3m11s
- docs/GITEA_ISSUE_RECONCILIATION.md: human-readable projection (states,
  bug-label audit with per-issue evidence, open-issue reconciliation table)
- docs/gitea_issue_reconciliation.json: machine-readable authority
  (72 records; all open issues covered; single live defect #324).
  Placed under docs/ because state/ is the gitignored runtime dir.
- scripts/gitea_reconciliation_check.py: deterministic drift check —
  state/label/coverage invariants; bug-label invariant applies to OPEN
  issues (closed labels are historical); exit 1 with itemized drift.
- Part K audit: closed #139 #157 (FIXED_VERIFIED with evidence comments);
  bug labels removed from #204 #145 #126 #37 #16 (not defects) and the
  stuck label on closed #314. Open bug-labelled: 8 → 1.
- 1289 tests green; ratchet 352/80; henxels clean.
2026-09-11 22:50:44 +01:00
conductor 5f9ba5784c chore(release): auto-bump version to 0.66.12 — earned by # (patch: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 9s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / lint (push) Successful in 35s
CI Pipeline / unit-tests (push) Successful in 54s
CI Pipeline / canary (push) Successful in 29s
CI Pipeline / best-practices (push) Successful in 3s
CI Pipeline / documentation (push) Successful in 5s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 15s
deploy / deploy (push) Successful in 37s
Promotion record: (unknown)
2026-09-11 22:33:27 +01:00
Nick 9a05fdfa1f fix(convergence): decision JSON omits boundary_sha — consumers re-derive it from git
CI Pipeline / best-practices (push) Successful in 7s
CI Pipeline / documentation (push) Successful in 5s
Auto-version and Release / release (push) Successful in 25s
CI Pipeline / canary (push) Successful in 36s
CI Pipeline / lint (push) Successful in 43s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Successful in 1m3s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 2m40s
Every debug session of the release pipeline (T15 Part F forensics included)
had to re-derive the release boundary by hand. The decision JSON now
carries boundary_sha on every return path.
2026-09-11 22:33:10 +01:00
Nick 2298768353 docs: D7 resolved — release-pipeline root causes recorded (experiment B trigger)
Auto-version and Release / release (push) Successful in 14s
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / canary (push) Successful in 39s
CI Pipeline / lint (push) Successful in 42s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / unit-tests (push) Successful in 1m6s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 38s
Records the three root causes (corrupted shell fragment, unwired release
boundary, per-surface commit granularity) with live proof of the fix.
2026-09-11 22:23:52 +01:00
conductor a4afc77d53 chore(release): auto-bump version to 0.66.11 — earned by # (patch: converged release (push-to-master bump))
Auto-version and Release / release (push) Successful in 11s
CI Pipeline / lint (push) Successful in 34s
CI Pipeline / unit-tests (push) Successful in 51s
CI Pipeline / canary (push) Successful in 26s
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 3s
CI Pipeline / type-check (push) Successful in 26s
CI Pipeline / gitea-offline (push) Successful in 14s
CI Pipeline / required-checks (push) Successful in 2s
deploy / deploy (push) Successful in 39s
Promotion record: (unknown)
2026-09-11 22:14:49 +01:00
Nick d68fd1e94d fix(release): ChangeFiles content must be base64 (ContentBase64)
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 4s
Auto-version and Release / release (push) Successful in 34s
CI Pipeline / canary (push) Successful in 35s
CI Pipeline / lint (push) Successful in 41s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 1m0s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 2m41s
2026-09-11 22:14:17 +01:00
Nick 470d82f307 fix(release): single-commit bump via ChangeFiles (blob API 404 on Gitea 1.27)
CI Pipeline / best-practices (push) Successful in 8s
Auto-version and Release / release (push) Failing after 16s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / lint (push) Successful in 41s
CI Pipeline / type-check (push) Successful in 26s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 57s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 38s
git-data blob/tree creation endpoints are not implemented on this Gitea
build (404). ChangeFiles (POST /contents with files[] = ChangeFilesOptions)
is the supported multi-file single-commit primitive. One bump = one commit.
2026-09-11 22:08:10 +01:00
Nick 7a988cbaff fix(release): refs API returns a list — take the master entry
Auto-version and Release / release (push) Failing after 13s
CI Pipeline / best-practices (push) Successful in 8s
CI Pipeline / documentation (push) Successful in 4s
CI Pipeline / canary (push) Successful in 31s
CI Pipeline / lint (push) Successful in 39s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 59s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 37s
2026-09-11 22:00:57 +01:00
Nick 12c3c488be fix(release): commit all version surfaces as ONE commit (phantom duplicate bumps root-caused)
CI Pipeline / documentation (push) Successful in 5s
Auto-version and Release / release (push) Failing after 22s
CI Pipeline / lint (push) Successful in 36s
CI Pipeline / canary (push) Successful in 38s
CI Pipeline / type-check (push) Successful in 27s
CI Pipeline / best-practices (push) Successful in 3s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 53s
CI Pipeline / required-checks (push) Successful in 1s
deploy / deploy (push) Successful in 37s
The per-file contents PUT created one commit per version surface — five
same-version bump commits per real bump. Every 'duplicate bump cascade'
since 0.66.2 was this: 5 surface-commits per bump, misread as queue
drain/recursion. Root-caused T15 Part F via run 6791 log forensics
(5 'committed <surface>' lines, one AUTO_BUMPED). Now: Git data API
(ref → blobs → tree → commit → CAS ref update) — one bump commit.
Loop guard makes any losing race converge instead of re-bumping.
2026-09-11 21:54:15 +01:00
17 changed files with 1496 additions and 26 deletions

No files matched your search

+22 -12
View File
@@ -185,18 +185,28 @@ jobs:
print(f" - {d}")
sys.exit(1)
# Commit each surface DIRECTLY to master (bookkeeping, not reviewable code)
msg_prefix = f"chore(release): auto-bump version to {NEW} — earned by #{PR_NUMBER}"
for path, (content, sha) in edited.items():
status, r = api(f"/contents/{path}", "PUT", {
"message": f"{msg_prefix} ({PR_TITLE[:80]})\n\nPromotion record: {promoting_url}",
"content": base64.b64encode(content.encode()).decode(),
"sha": sha,
"branch": "master",
})
if status not in (200, 201):
print(f" commit {path} failed ({status}): {str(r)[:200]}"); sys.exit(1)
print(f" committed {path} to master")
# Commit ALL surfaces as ONE commit via ChangeFiles
# (POST /contents with a files[] array). The per-file contents PUT
# created one commit per version surface — five same-version "bump
# commits" per release (the phantom duplicate-bump cascade,
# misdiagnosed as queue drain since 0.66.2; root-caused T15 Part F
# 2026-09-11). Git-data blob/tree creation is 404 on this Gitea
# build; ChangeFiles is the supported single-commit primitive.
msg = f"chore(release): auto-bump version to {NEW} — earned by #{PR_NUMBER} ({PR_TITLE[:80]})\n\nPromotion record: {promoting_url}"
ops = [{
"operation": "update",
"path": path,
"content": base64.b64encode(content.encode()).decode(), # ChangeFileOperation.content is ContentBase64
} for path, (content, _old_sha) in edited.items()]
status, r = api("/contents", "POST", {
"branch": "master",
"message": msg,
"files": ops,
})
if status not in (200, 201):
print(f"change-files failed ({status}): {str(r)[:300]}"); sys.exit(1)
commit_sha = (r.get("commit") or {}).get("sha", "?") if isinstance(r, dict) else "?"
print(f" committed {len(ops)} surfaces as ONE commit {str(commit_sha)[:7]}")
print(f"AUTO_BUMPED=true — version {NEW} live on master; TUI footer will render v{NEW}")
with open(os.environ["GITHUB_ENV"], "a") as env:
+1 -1
View File
@@ -1,6 +1,6 @@
# Rune
**Current release: v0.66.10**
**Current release: v0.66.14**
**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.**
+113
View File
@@ -0,0 +1,113 @@
# Gitea Issue Reconciliation — canonical record
_Generated T15 Part J/K/L (2026-09-11). Machine-readable companion:
`docs/gitea_issue_reconciliation.json` (single authority; this doc is the
human-readable projection). Consistency checker: `scripts/gitea_reconciliation_check.py`
compares live Gitea state against the JSON and fails on drift._
Reconciliation states (closed vocabulary):
`VALID_OPEN | FIXED_VERIFIED | SUPERSEDED | DUPLICATE | HISTORICAL_EVIDENCE |
ACCEPTED_LIMITATION | NEEDS_REVALIDATION | DEFERRED_FUTURE`
## Bug-label audit (Part K)
`bug` = demonstrated currently incorrect behavior. Nothing else.
### Issues labelled `bug` at audit time
| # | live defect | evidence | final label | reconciliation state |
|---|---|---|---|---|
| 324 | **YES** | MessageAbortedError reproduces every aborted worker session (15+ checkpoints, including this session's predecessor) | bug (kept) | VALID_OPEN |
| 204 | NO | Forge-orchestrated pipeline = feature request (P1 feature); no demonstrated incorrect behavior | bug removed | VALID_OPEN (feature) |
| 157 | NO | capture_failure.py + tests/fixtures/production/ + manifest.json shipped and exercised (plan 2026-09-07-157) | bug removed | FIXED_VERIFIED (closed) |
| 145 | NO | P0-07 follow-up work item (tracing coverage), not a defect report | bug removed | VALID_OPEN (work item) |
| 139 | NO | Hand-maintained allowlist replaced by declarative classification (tui_validator.py cites #139); `tui_validator.py check` → passed, exit 0 | bug removed | FIXED_VERIFIED (closed) |
| 126 | NO | Silent-handler sweep = refactor program (S110/BLE001 ratchet governs), not a defect | bug removed | VALID_OPEN (work item) |
| 37 | NO | Personality corpus compilation = P2 feature | bug removed | VALID_OPEN (feature) |
| 16 | NO | v1 course-correction EPIC | bug removed | VALID_OPEN (epic) |
### Issues whose `bug` label was removed in the prior cleanup (Part D, earlier session)
16 targeted: #301 #300 #292 #284 #314 #181 #166 #165 #163 #159 #154 #141 #40 #32 #31 #27.
Verification (live API, this session): all confirmed bug-free EXCEPT #314 — its
removal had failed (the API-False defect) and the label persisted on a closed
issue. Removed this session by label-ID DELETE (204). #314 is closed
FIXED_VERIFIED (mode:association_merged regression shipped in 2bf43ea).
### Totals
- bug-labelled before audit: 8 open (+ #314 closed-but-labelled)
- bug-labelled after audit: **1** (#324, live defect, evidence above)
- issues closed by this audit: #139, #157 (both FIXED_VERIFIED with evidence comments)
- NEEDS_REVALIDATION count: 0 among bug-labelled issues (each resolved on evidence)
## Open-issue reconciliation (Part J)
Subsystems derived from labels. States per closed vocabulary. `next action` is
the single next concrete step; `_` = none until its tranche opens.
| # | subsystem | state | current evidence | next action |
|---|---|---|---|---|
| 324 | engine/checkpoint | VALID_OPEN | live repro (15+ sessions) | fix writer abort handling |
| 316 | ADAPT-1/research | VALID_OPEN | B3-v2 research task | await ADAPT tranche |
| 315 | ADAPT-1/wiring | VALID_OPEN | B2-v2 standard task | await ADAPT tranche |
| 311 | ADAPT-1/wiring | VALID_OPEN | superseded-by #315 (kept open as spec anchor until 315 delivers) | close when #315 closes |
| 301 | FINAL-12/benchmarks | NEEDS_REVALIDATION | dependency list silently grew (operator-path telemetry, bridge overhead) without issue update | re-scope before PL1 metrics work |
| 300 | ADAPT-11 | VALID_OPEN | acceptance = real escalation demo; blocked on ADAPT-LIVE telemetry | demo after PL1 held-out |
| 299 | ADAPT-10 | VALID_OPEN | harness legibility audit | _ |
| 297 | ADAPT-8 | VALID_OPEN | deterministic-first QUALIFY | _ |
| 296 | ADAPT-7 | VALID_OPEN | DESIGN consolidation experiment | _ |
| 295 | ADAPT-6 | VALID_OPEN | evidence capsule / context minimization | _ |
| 294 | ADAPT-5 | VALID_OPEN | budgets + stop conditions | _ |
| 293 | ADAPT-4 | VALID_OPEN | DESIGN-LITE shipped (STANDARD_CHANGE lane live) | acceptance demo, then close |
| 292 | ADAPT-3 | VALID_OPEN | LOCAL_FIX lane shipped | acceptance demo, then close |
| 284 | ADAPT epic | VALID_OPEN | epic tracks ADAPT-LIVE + PL1; body updated with detour record | update after PL1 |
| 259 | Scaffolding | VALID_OPEN | redefined: safe repeatable construction protocol (T15 §C) | Scaffolding v1 after PL1 |
| 258 | State-aware processes | VALID_OPEN | redefined: low-compute architectural self-awareness; SA1-8 superseded by distributed concerns | deferred research |
| 204 | forge/pipeline | VALID_OPEN | P1 feature: forge-orchestrated coordination | _ |
| 183–176 | memory-foundation futures | DEFERRED_FUTURE | P3 research futures (typed temporal semantics, prior-art audit, curiosity, lineage) | memory-foundation tranche |
| 175/181 | memory epics | DEFERRED_FUTURE | evidence-grounded continuity epics | same |
| 166 | research watchlist | DEFERRED_FUTURE | external research tracking | periodic review |
| 165/164 | research spikes | DEFERRED_FUTURE | SimpleMem/A-MEM, HippoRAG 2 | memory-foundation tranche |
| 163 | graph backend spike | NEEDS_REVALIDATION | P1 spike; LadybugDB evaluation partially done in prior research artifacts | revalidate against current graph.db-missing state |
| 162 | Qdrant spike | NEEDS_REVALIDATION | P1 spike; prior research artifacts exist (issue-162/) | revalidate after #316 outcome |
| 159 | conceptual topology | DEFERRED_FUTURE | P3 future | _ |
| 158 | wiring-status report | VALID_OPEN | P2: generated architecture-truth report | _ |
| 156 | mutation guards | VALID_OPEN | P1: cognitive-state mutation guards | _ |
| 155 | e2e activation trace | VALID_OPEN | P1: credit-assignment trace | overlaps PL1 outcome work — potential duplicate of #300's telemetry; review at PL1 close |
| 154/153 | learned-state / experience encoding | VALID_OPEN | P2 | PL1-adjacent |
| 152/151 | break-it / adversarial | VALID_OPEN | P0: adversarial procedures after nominal green | post-PL1 tranche |
| 145 | P0-07 follow-up | VALID_OPEN | tracing coverage gaps | _ |
| 141 | ContextBroker compaction | VALID_OPEN | P1: rolling-compaction persistence | _ |
| 139 | tui_validator drift | FIXED_VERIFIED | declarative classification shipped; check passes | closed |
| 131/130/129 | reviewer program | VALID_OPEN | P0: local reviewer + calibration + rubric | post-PL1 tranche |
| 126 | silent-handler sweep | VALID_OPEN | P0 refactor program; ratchet enforces ceiling | ongoing |
| 125 | decompose monoliths | VALID_OPEN | P2 | _ |
| 49–35 | v1-course-correction P2/P3 | DEFERRED_FUTURE | epic #16 manifest items (P2-01..09, P3-01..06) | per epic #16 sequencing |
| 33–27 | v1-course-correction P1 | VALID_OPEN | epic #16 manifest P1 items | per epic #16 sequencing |
| 16 | v1 epic | VALID_OPEN | consolidation epic; 33 manifest issues | per epic sequencing |
| 13 | TUI message graph | VALID_OPEN | P1 | _ |
| 3 | financial tracking | NEEDS_REVALIDATION | non-Rune issue (different project era) | transfer to correct repo or close |
| 2 | cognitive loop wiring | NEEDS_REVALIDATION | predates current TUI architecture | revalidate against current TUI |
| 1 | personality injection | NEEDS_REVALIDATION | overlaps #37's newer scope | merge into #37 or close |
## Reconciliation decisions this session (Part K deltas)
- CLOSED: #139, #157 (FIXED_VERIFIED, evidence comments posted)
- BUG LABEL REMOVED: #204, #145, #126, #37, #16 (audit: not defects)
- BUG LABEL REMOVED (stuck from prior cleanup): #314 (closed issue)
- OPEN BUGS: 8 → 1 (#324 only — genuine live defect)
## Part L — consistency check
`scripts/gitea_reconciliation_check.py` (deterministic, no governance
subsystem): fetches live issue state, compares to
`docs/gitea_issue_reconciliation.json`, flags:
- closed issue recorded VALID_OPEN / DEFERRED_FUTURE / NEEDS_REVALIDATION (open states)
- open issue recorded FIXED_VERIFIED / SUPERSEDED / DUPLICATE / HISTORICAL_EVIDENCE without being closed
- `bug` label present on any issue not recorded as a live defect (or missing on #324)
- issue missing from the artifact
- record lacking a required field
Exit 0 = consistent; exit 1 = drift listed. CI-eligible (read-only).
+25 -7
View File
@@ -151,11 +151,29 @@ Then: **PL1** (T9), with the intent-continuity spine as PL1's first or second de
Part A-J executed. 15 issues closed (HISTORICAL_EVIDENCE/SUPERSEDED/ACCEPTED_LIMITATION) with evidence. Bug label cleaned: 16 misleading labels removed (open bugs 24→8). #259/#258 updated to current architecture. Remote tracking fixed (master tracks gitea/master, not stale origin). PL1 metrics corrected (NOT_YET_MEASURABLE where evidence doesn't support numbers). D7: bump works, release job fails on Pi — ROOT_CAUSE_UNKNOWN_DEFERRED. Automation noise: 5 duplicate bump commits per logical change (queue-drain artifact, not live recursion — version converges, commit history doesn't).
## DEFERRED DEFECT D7 (2026-09-11): Auto-version release job fails on Pi runner
## DEFECT D7 (2026-09-11): RESOLVED — release-job failures root-caused
Observed: push-convergence version bumping works (deployed identity advances:
0.66.0 → 0.66.6 with loop guard), but the release job's status flips to
failure after the bump. Pi-side backup step logs "Failed to connect to
127.0.0.1:3000". Impact: version bumping + deployment PROVEN; the release
TAG may lag. Not blocking PL1 (PL1 consumes task.outcome, not git tags).
Destination: INFRA follow-up on the Pi runner.
History: the release job failed on every push since 03:16 (c2528c1).
Superseded diagnosis: "Pi-side backup step logs Failed to connect to
127.0.0.1:3000" was a red herring — the Pi backup step was never the
failing job.
Root causes (live-proven T15 Part F, 2026-09-11 evening):
1. c2528c1 left a corrupted shell fragment after the converged-check fi
in auto-version.yml — the release job died at bash parse time (exit 2)
before any bump. Fixed in c35b604.
2. release_convergence() never assigned the release boundary — all 959+
commits classified as unreleased, so the warranted bump never
converged and queued runs each wrote their own bump commit. Fixed in
e395ee1 (boundary wiring) + 9e0b855 (boundary grep must match subjects
only, not bodies) + c35018f (numeric semver comparison: '0.66.9' <
'0.66.10' is False lexicographically, which silently skipped warranted
bumps as version_ahead_of_target).
3. The per-file contents PUT committed one commit per version surface —
five same-version bump commits per real bump (the "duplicate bump
cascade" since 0.66.2, misdiagnosed as queue drain). Fixed in 470d82f
+ d68fd1e (single ChangeFiles commit).
Live proof: experiment A (trigger d68fd1e, warranted patch) → exactly one
bump commit a4afc77 (0.66.11), all five surfaces in one commit, queue
drained, zero delayed duplicates, zero workflow failures.
File diff suppressed because it is too large. Load diff
+4
View File
@@ -0,0 +1,4 @@
wait/resume experiment marker 23:07:52
wr delivery test 23:28:42
delivery test 2 23:31:02
wr delivery test 2 23:31:12
+1
View File
@@ -0,0 +1 @@
def broken(:
+1 -1
View File
@@ -20,7 +20,7 @@ henxels:
- henxel: "Top-level docs are markdown or yaml references"
in: ./docs/*
allowed_filetypes: [.md, .yaml]
except: ["./docs/v1/**", "./docs/wiki/**"]
except: ["./docs/v1/**", "./docs/wiki/**", "./docs/gitea_issue_reconciliation.json"]
- henxel: "The known giant stays visible — file-size debt is tracked, not silent"
in: ./src/rune/*
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "rune"
version = "0.66.10"
version = "0.66.14"
description = "Rune — a stateful coding assistant with persistent memory, orchestration, and TUI"
requires-python = ">=3.10"
+110
View File
@@ -0,0 +1,110 @@
#!/usr/bin/env python3
"""gitea_reconciliation_check.py — Part L consistency check (deterministic).
Compares live Gitea issue state against the canonical reconciliation
artifact (docs/gitea_issue_reconciliation.json). Flags:
1. closed issue recorded in an open-only state
(VALID_OPEN / DEFERRED_FUTURE / NEEDS_REVALIDATION)
2. open issue recorded in a terminal state
(FIXED_VERIFIED / SUPERSEDED / DUPLICATE / HISTORICAL_EVIDENCE /
ACCEPTED_LIMITATION)
3. `bug` label present on any issue not recorded live_defect
(or missing on a recorded live defect)
4. open issue missing from the artifact
5. record missing required fields
Exit 0 = consistent. Exit 1 = drift (each item printed). Read-only.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "scripts"))
ARTIFACT = ROOT / "docs" / "gitea_issue_reconciliation.json"
OPEN_ONLY_STATES = {"VALID_OPEN", "DEFERRED_FUTURE", "NEEDS_REVALIDATION"}
TERMINAL_STATES = {"FIXED_VERIFIED", "SUPERSEDED", "DUPLICATE", "HISTORICAL_EVIDENCE", "ACCEPTED_LIMITATION"}
REQUIRED_FIELDS = {"number", "tracker_state", "reconciliation_state", "labels", "live_defect", "last_revalidated"}
def main() -> int:
import gitea_auth
if not ARTIFACT.is_file():
print(f"reconciliation artifact missing: {ARTIFACT}")
return 1
artifact = json.loads(ARTIFACT.read_text())
records = {r["number"]: r for r in artifact["records"]}
drift: list[str] = []
# Fetch live issues (open + recently closed via both pages)
issues: list[dict] = []
for page in (1, 2):
status, batch = gitea_auth.api(f"/issues?state=all&limit=50&page={page}")
if status != 200:
print(f"Gitea API failed ({status}): {str(batch)[:200]}")
return 1
if isinstance(batch, list):
issues.extend(batch)
live = {i["number"]: i for i in issues}
for num, rec in sorted(records.items()):
for field in REQUIRED_FIELDS:
if field not in rec:
drift.append(f"#{num}: record missing required field {field!r}")
state = rec.get("reconciliation_state")
if state in OPEN_ONLY_STATES and rec.get("tracker_state") == "closed":
drift.append(f"#{num}: closed issue recorded {state}")
if state in TERMINAL_STATES and rec.get("tracker_state") == "open":
drift.append(f"#{num}: open issue recorded terminal {state}")
has_bug = "bug" in (rec.get("labels") or [])
# The bug-label/live-defect invariant applies to OPEN issues only:
# a closed issue's labels are historical record; its reconciliation
# state governs (FIXED_VERIFIED issues legitimately keep the label).
if rec.get("tracker_state") == "open":
if has_bug and not rec.get("live_defect"):
drift.append(f"#{num}: bug label present but not recorded as live defect")
if not has_bug and rec.get("live_defect"):
drift.append(f"#{num}: recorded live defect but bug label missing")
if state == "FIXED_VERIFIED" and rec.get("tracker_state") == "open":
drift.append(f"#{num}: FIXED_VERIFIED but still open without closure note")
# Live vs artifact sync (only for issues present in the live window)
for num, li in sorted(live.items()):
if num not in records:
continue
rec = records[num]
live_state = li["state"]
if live_state == "closed" and rec["tracker_state"] == "open" and rec["reconciliation_state"] in OPEN_ONLY_STATES:
drift.append(f"#{num}: live state closed but artifact says open/{rec['reconciliation_state']}")
if live_state == "open" and rec["tracker_state"] == "closed" and rec["reconciliation_state"] in TERMINAL_STATES:
drift.append(f"#{num}: live state open but artifact says closed/{rec['reconciliation_state']}")
live_bug = "bug" in [l["name"] for l in li.get("labels", [])]
if live_bug and not rec.get("live_defect"):
drift.append(f"#{num}: live bug label present but artifact records no live defect")
if not live_bug and rec.get("live_defect"):
drift.append(f"#{num}: artifact records live defect but live bug label absent")
# Live defects in the artifact must all be OPEN in the tracker
for num in artifact.get("live_defects", []):
li = live.get(num)
if li is not None and li["state"] != "open":
drift.append(f"#{num}: live defect but tracker state is {li['state']} — close the defect or update the artifact")
if drift:
print(f"RECONCILIATION DRIFT ({len(drift)}):")
for d in drift:
print(f" - {d}")
return 1
print(f"reconciliation consistent ({len(records)} records, {len(live)} live issues in window)")
return 0
if __name__ == "__main__":
sys.exit(main())
+11
View File
@@ -287,6 +287,7 @@ def release_convergence(
"current_version": current_version,
"target_version": current_version,
"reason": "no release-worthy commits since last boundary",
"boundary_sha": "",
}
target_version = next_version(current_version, warranted)
if current_version == target_version:
@@ -299,6 +300,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": "current version already equals warranted target",
"boundary_sha": "",
}
elif _version_lt(current_version, target_version):
return {
@@ -310,6 +312,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": f"bump required: {current_version} → {target_version}",
"boundary_sha": "",
}
else:
return {
@@ -321,6 +324,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": f"ANOMALY: current {current_version} > target {target_version}",
"boundary_sha": "",
}
if _boundary_subject:
result = subprocess.run(
@@ -361,6 +365,9 @@ def release_convergence(
# Exclude chore(release) commits from bump classification (they ARE releases)
substantive = [s for s in subjects if not is_release_commit(s)]
warranted = highest_warranted_bump(substantive)
# Expose the boundary in the decision JSON: consumers (release step,
# debug sessions) otherwise re-derive it from git history.
decision_boundary = {"boundary_sha": (boundary or "")[:12]}
if not warranted:
return {
@@ -372,6 +379,7 @@ def release_convergence(
"current_version": current_version,
"target_version": current_version,
"reason": "no release-worthy commits since last boundary",
**decision_boundary,
}
target_version = next_version(current_version, warranted)
@@ -386,6 +394,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": "current version already equals warranted target",
**decision_boundary,
}
elif _version_lt(current_version, target_version):
# Bump needed — but only if not already converged by a prior bump
@@ -399,6 +408,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": f"bump required: {current_version} → {target_version}",
**decision_boundary,
}
else:
return {
@@ -410,6 +420,7 @@ def release_convergence(
"current_version": current_version,
"target_version": target_version,
"reason": f"ANOMALY: current {current_version} > target {target_version}",
**decision_boundary,
}
+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.66.10"
__version__ = "0.66.14"
# 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.66.10"' in rune_version,
'__version__ = "0.66.14"' in rune_version,
failures,
)
# #169 policy update: auto-bump on merge is sanctioned (Nick directive:
+2 -2
View File
@@ -8,7 +8,7 @@ mode system, subject header, shared memory and identity.
This is not an interface. This is how I see, speak, and interact with the world.
Version: v0.66.10
Version: v0.66.14
Features: 41 (24 original + 17 new native commands)
Usage:
@@ -1856,7 +1856,7 @@ class RuneApp(App):
# Show version info
self.chat_channel.add_message(
"system",
f"[dim]Rune v0.66.10 | Textual TUI | {len(loaded)} native modules[/dim]",
f"[dim]Rune v0.66.14 | Textual TUI | {len(loaded)} native modules[/dim]",
)
# Auto-show night mode suggestion if evening/night hours
+39
View File
@@ -0,0 +1,39 @@
"""Reconciliation consistency check (handoff T15 Part L): drift rules.
Pure-logic tests over the checker's decision rules — no network."""
import importlib.util
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "scripts"))
spec = importlib.util.spec_from_file_location(
"grc", ROOT / "scripts" / "gitea_reconciliation_check.py")
grc = importlib.util.module_from_spec(spec)
spec.loader.exec_module(grc)
def test_state_vocabularies_partition():
"""Open-only and terminal states must not overlap."""
assert not (grc.OPEN_ONLY_STATES & grc.TERMINAL_STATES)
def test_required_fields_cover_decision_inputs():
"""The fields the drift rules read must all be required."""
assert {"tracker_state", "reconciliation_state", "labels", "live_defect"} <= grc.REQUIRED_FIELDS
def test_artifact_exists_and_parses():
data = __import__("json").loads(grc.ARTIFACT.read_text())
assert data["records"], "artifact has no records"
nums = [r["number"] for r in data["records"]]
assert len(nums) == len(set(nums)), "duplicate issue records"
for r in data["records"]:
assert r["reconciliation_state"] in (grc.OPEN_ONLY_STATES | grc.TERMINAL_STATES), r["number"]
def test_single_live_defect():
"""The bug audit converged on exactly one live defect: #324."""
data = __import__("json").loads(grc.ARTIFACT.read_text())
assert data["live_defects"] == [324]
+9
View File
@@ -388,3 +388,12 @@ class TestNumericVersionCompare(unittest.TestCase):
self.assertFalse(result["converged"])
self.assertIsNone(result["anomaly"])
self.assertEqual(result["warranted_bump"], "patch")
def test_decision_exposes_boundary_sha(self):
result = vc.release_convergence(
_version="0.66.9",
_boundary_subject="chore(release): 0.66.9",
_subjects=["fix: x"],
)
# Test-injection path: no git, boundary unknown → empty but present.
assert result["boundary_sha"] == ""
+1
View File
@@ -0,0 +1 @@
def broken(: