From ada1112c0dc7ba0cd12e9da7ea7d82cc9a9a58c9 Mon Sep 17 00:00:00 2001 From: Rick Hightower Date: Sat, 19 Sep 2026 16:42:51 -0500 Subject: [PATCH] ops: ci-local.sh proves the workflows parse; drop stray CHANGELOG heading The v0.9.4 CI outage (#82) was an unparseable ci.yml. GitHub failed the run at startup with zero jobs, so `test` and `okf-interop` stopped running for a week while pull requests still looked green. A workflow that cannot start cannot report its own breakage, so the check belongs where it runs before the push. tools/ci-local.sh already claims to run what the workflows run. Adds one step that yaml.safe_load parses every .github/workflows/*.yml and fails when the glob finds none. Negative-tested by reinjecting the exact #82 shape, a multi-line `python3 -c` at column 1 inside a `run: |` block: the step fails. Single-line `python3 -c` here for the same reason. Also removes the second `## Unreleased` heading in CHANGELOG.md. It dated from the 0.7.2 era and sat between the 0.7.3 and 0.7.2 sections. Its two bullets describe host manifests reaching 0.7.2, which shipped in 0.7.3, so they fold into the 0.7.3 list above them. The placeholder at the top stays. No assertion and no released behavior changes. Items 01M2XSTB63SP54A482P7GF95VD and 01M2XSTB8K5DMTPHVX3WR8QXSM. Co-Authored-By: Claude Opus 5 --- .work/todo.jsonl | 4 ++++ CHANGELOG.md | 3 --- docs/roadmap.md | 4 ++-- tools/ci-local.sh | 6 ++++++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.work/todo.jsonl b/.work/todo.jsonl index ca924f2..019752e 100644 --- a/.work/todo.jsonl +++ b/.work/todo.jsonl @@ -128,3 +128,7 @@ {"actor":"claude-code","ev":"01M2XDT6Y8NRP4DMNB1WJKNZXX","item":"01M2XCVAWFZ005YCP1VDQX0GNV","op":"close","set":{"resolution":"shipped in v0.9.5 via #81","status":"done"},"ts":"2026-09-19T18:10:47Z"} {"actor":"claude-code","ev":"01M2XDT704G4WFH1PWBJFJF5W8","item":"01M2XCVAY85DP4XJD8F2Y5CV6G","op":"close","set":{"resolution":"shipped in v0.9.5 via #81","status":"done"},"ts":"2026-09-19T18:10:47Z"} {"actor":"claude-code","ev":"01M2XDT71WQRN2VGPQJG1BA7G1","item":"01M2XDNSSH9CY0BYKQCB87E9A3","op":"close","set":{"resolution":"shipped in v0.9.5 via #81","status":"done"},"ts":"2026-09-19T18:10:47Z"} +{"actor":"richardhightower","ev":"01M2XSTB633ADW4VPHQWFQCQV1","git":"f7134f8","item":"01M2XSTB63SP54A482P7GF95VD","op":"create","set":{"body":"The v0.9.4 CI outage (#82) was an unparseable ci.yml: GitHub failed the run at startup with zero jobs, so the test and okf-interop jobs silently stopped running for a week while pull requests still looked green. A workflow that cannot start cannot report its own breakage, so the check has to live somewhere that runs before the push. tools/ci-local.sh already claims to run everything the workflows run. Add a step that yaml.safe_load parses every .github/workflows/*.yml and fails when none are found.","kind":"ops","level":"task","milestone":"v0.9.6","priority":"P1","status":"todo","title":"ci-local.sh proves the workflows parse before you push"},"ts":"2026-09-19T21:40:35Z"} +{"actor":"richardhightower","ev":"01M2XSTB8K77AKXWD160QM4XTJ","git":"f7134f8","item":"01M2XSTB8K5DMTPHVX3WR8QXSM","op":"create","set":{"body":"CHANGELOG.md carries two '## Unreleased' headings: the intentional placeholder at the top and a leftover from the 0.7.2 era sitting between the 0.7.3 and 0.7.2 sections. Its two bullets describe host manifests reaching 0.7.2, which shipped in 0.7.3, so they belong in the 0.7.3 section above them. A second Unreleased heading makes a release-notes reader think unreleased work is pending.","kind":"bug","level":"task","milestone":"v0.9.6","priority":"P3","status":"todo","title":"Remove the stray Unreleased heading from CHANGELOG"},"ts":"2026-09-19T21:40:35Z"} +{"actor":"richardhightower","ev":"01M2XSY20ZHBEVCZTTGZ90W0BH","item":"01M2XSTB63SP54A482P7GF95VD","op":"close","set":{"resolution":"tools/ci-local.sh parses every .github/workflows/*.yml; negative-tested against the #82 breakage","status":"done"},"ts":"2026-09-19T21:42:36Z"} +{"actor":"richardhightower","ev":"01M2XSY22P112RB524KRYMRTY6","item":"01M2XSTB8K5DMTPHVX3WR8QXSM","op":"close","set":{"resolution":"stray Unreleased heading removed; its bullets folded into 0.7.3","status":"done"},"ts":"2026-09-19T21:42:36Z"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 604db3b..8ae8a68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -177,9 +177,6 @@ Retrieval ladder: Git + Markdown stays source of truth. Accelerators are disposa ## 0.7.3 — 2026-08-17 - **Cursor host.** `.cursor-plugin/plugin.json` (Cursor Plugins) plus `.cursor/rules/second-brain.mdc`. Docs: `docs/CURSOR.md`. `docs/GROK_BOT.md` now covers Grok Bot spawning Cursor cloud agents. - -## Unreleased - - Host manifests (`.claude-plugin`, `.codex-plugin`, Grok marketplace) now match root `plugin.json` **0.7.2**. Claude Code was still labeled 0.7.1. diff --git a/docs/roadmap.md b/docs/roadmap.md index 02bca3d..3bbb37f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -2,8 +2,8 @@ wiki_key: roadmap doc_type: roadmap truth_state: current -source_hash: f503417c -generated_at: 2026-09-19T18:10:47Z +source_hash: eb13176e +generated_at: 2026-09-19T21:42:36Z --- diff --git a/tools/ci-local.sh b/tools/ci-local.sh index 58f62d6..169ae84 100755 --- a/tools/ci-local.sh +++ b/tools/ci-local.sh @@ -24,6 +24,12 @@ step() { BUNDLE=sample-knowledge TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT +# #82: an unparseable workflow fails at startup with zero jobs, so CI reports +# nothing and every PR still looks green. The workflow cannot check itself -- +# this is the only gate that runs before the push. +echo "== workflows ==" +step "workflows parse" python3 -c "import glob,yaml; fs=sorted(glob.glob('.github/workflows/*.yml')); assert fs, 'no workflows found'; [yaml.safe_load(open(f)) for f in fs]" + echo "== unit tests ==" step "test_pkc.py" python3 tests/test_pkc.py step "test_isolation.py" python3 tests/test_isolation.py