merge-queue batch q-1785729479 - #730
Closed
matt82198 wants to merge 19 commits into
Closed
Conversation
Add ci_job_status tool to read-only MCP server for querying GitHub Actions run history: status, conclusion, duration, flake signal. Tool spawns gh CLI with 10s timeout (no shell:true), parses deterministic JSON, handles errors gracefully. Includes test fixtures for normal history, empty history (never_executed=true), and gh failure → structured error. All tests pass. - mcp/server.mjs: Add getCIJobStatus() + tool registration - mcp/CLAUDE.md: Document tool contract + test strategy - tests/mcp-ci-status.test.mjs: 4 test cases (init, normal, empty, error) - tests/mcp-fleet.test.mjs: Update tool count from 11 to 12 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s restored The 0.7.2 section was fabricated. Commit 2f52f39 authored it as a near-verbatim copy of the 0.7.1 section's PR list -- #638, #636, #643, #645, #647 all shipped in 0.7.1, none of them in v0.7.1..v0.7.2. The one change that actually shipped in 0.7.2 (the /api/state cache-staleness fix, #668) appeared nowhere in it. Ground truth, `git log v0.7.1..v0.7.2 --oneline`, four commits: e061f2b Merge pull request #669 from matt82198/release/0.7.2 a00deb7 release: 0.7.2 a87c396 Merge pull request #668 from matt82198/fix/api-state-empty-section-cache fa29fb8 fix: /api/state served a collector's empty default instead of real data The section is rewritten from that: one substantive fix plus release metadata. The same commit also rewrote the 0.7.0 section's historical test count from 254 to 266. 254 was the at-tag truth -- the section was authored at 366a7fc as "254 tests (25 Node + 13 Shell + 216 Python)", and PR #644 ("correct test count to 254") had verified it for that release. Rewriting a shipped release's numbers to match a later suite falsifies the record; 254 is restored with a dated footnote pointing currency at the README. 0.7.1 was cross-checked against `git log v0.7.0..v0.7.1` and is substantively accurate, but two citations were wrong and are corrected: #654 was CLOSED (the merge-train UTF-8 change shipped as c6e465b inside batch #667), and the portability-gate/remote-identity work is 502ccfa, not #667 itself (#667 is the integration batch PR). Complexity-reduction claims verified and now cited (#637, #664, #658, #662, #663). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…uts + fail-closed testCmds
The first-wave replay kit documented a command that does not exist and pasted
output nobody ever ran. Three verified defects, all fixed against real runs.
c1 -- broken documented command. Both docs told adopters to run
`python tools/wave_templates.py validate <path>`. That subcommand takes only
`--template {saas,data,library,all}` and exits 2 with "unrecognized arguments"
on a file path, so the walkthrough's own validation step failed as written.
The real standalone-manifest validator is `tools/wave_manifest_lint.py <path>`
(also reachable as `aesop wave manifest-lint <path>`). Both docs now use it,
explain why the old form fails, and keep the `--template all` form where
preset validation is actually what is wanted.
c2 -- fabricated output. The "Expected Output" block claimed a checkmark,
"Items: 5", and per-slug file counts. `validate_manifest` returns None and the
snippet prints one line: "Manifest is valid". Every output block in both docs
is now captured from a real run, or is explicitly labelled an estimate. The
duration tables said "honest expected duration" while reporting numbers nobody
measured; they now say so. The jq inspect step (whose pasted output was not
even jq's format, and which needed a tool the docs never listed) is replaced
with a python one-liner whose real output is pasted.
c4 -- fail-open testCmds. Four of five gates passed before any work was done,
so they would have blessed an empty PR:
- enable-skipped-test echoed "Still skipped" and exited 0 while skipped
- fix-doc-links only ran `test -f` on the two files it was editing
- add-eslint-config grepped package.json for "lint", which already
matches "eslint" in devDependencies
- simplify-util-fns ran a suite that was green before the refactor
All four are rewritten to fail pre-work: assert no .skip marker remains and the
suite passes; resolve every relative markdown link against the filesystem;
require a real `lint` script and run `npm run lint` for real; require the
`Refactor goal:` marker the prompt already asked for plus a green suite.
Prompts updated so each gate is a stated contract, not a surprise.
Rather than assert fail-closedness in prose -- the exact failure mode being
fixed -- examples/first-wave-baseline/verify-testcmds.sh executes it: it builds
a fixture repo in the pre-work state, runs each testCmd verbatim out of
wave-manifest.json, applies the five fixes, and reruns them. Pre-work all 5
exit non-zero, post-work all 5 exit zero. Verified it detects regressions by
restoring an old fail-open testCmd and confirming it reports FAIL-OPEN.
Remaining limitation stated plainly instead of papered over: the refactor item
can prove the file was touched and the tests are green, but not that the
refactor improved anything. That stays a human review call.
Also adds the [ISOLATION: sibling worktree] marker to all 5 prompts, clearing
the linter's prompt_sanity warnings.
Verified: wave_manifest_lint exit 0; validate_manifest exit 0; verify-testcmds
exit 0; secret_scan, claudemd_lint/sync, watcher, portability, subprocess,
prompt-hygiene, coverage, suite-count, gates-wired, ci-gate-runability,
shell-syntax all exit 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gate inventory (PR #709) found four guardrail tools on main invoked by nothing -- unit-tested, documented, grading nothing. Three are wired as real shard-0 CI gates; the fourth is recorded as deliberately unwired. - sibling_import_check.py --check - fixture_intent_check.py --root . - port_fidelity_check.py --check --root . git_identity_check.py stays unwired: its subject is a managed target repo's *local* git identity, and a GitHub Actions runner clone sets only a --global one, so it reports mismatch on every CI run (verified exit 1). Softening it with --mode warn or continue-on-error would recreate the decoration this sweep removes. hooks/CLAUDE.md documented 8 pre-push checks while pre-push-policy.sh runs 9 -- check_test_suite_count() was undocumented. Added and renumbered. tests/test_ci_workflow_lint.py gains four assertions: the steps exist with exact invocations, they are shard-0 scoped and never continue-on-error, and every tool in the orphan inventory is either wired or explicitly excepted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The nightly stats-refresh job had concluded FAILURE on every one of its last four runs (2026-07-30..08-02) with no signal anywhere, letting stats.json drift 200+ commits stale and red-line the stats freshness gate on every open PR in the repo. Three stacked defects, each hidden behind the one before it: 1. `gh pr create --label "chore"` - the repo had no `chore` label and gh resolves labels BEFORE opening the PR, so the command exited 1 and no PR was ever created. Four orphan branches, zero PRs. 2. Actions was not permitted to create pull requests (`can_approve_pull_request_reviews: false`), so even with the label present `gh pr create` failed with "GitHub Actions is not permitted to create or approve pull requests". 3. The date-suffixed branch scheme (`chore/stats-refresh-<date>`) aborted on any re-run: switching to an existing branch is refused while the regenerated stats.json sits dirty in the working tree. Fixes: - Labels are attached best-effort AFTER the PR exists, never passed to `gh pr create`, so a cosmetic label can no longer fail the job. The `merge-queue` label is added too, handing routine stats bumps to the merge-queue advancer instead of a human. - One coalescing branch (`chore/stats-refresh`) replaced in place, so there is exactly one open stats PR at a time and re-runs are idempotent. - The push takes an explicit lease (`--force-with-lease=<ref>:<sha>`) computed from a fetched remote-tracking ref, and falls back to a plain create when the branch does not exist yet. Failure visibility (the wall for the wall): nothing watches a scheduled workflow's conclusion, which is why four failures were silent. The job now opens a deduplicated tracking issue on failure (comments on repeats rather than spamming) and closes it again on success. An issue needs no push access and no branch-protection exception, and it outlives log retention. Repo settings changed in this lane (reversible, one API call): `can_approve_pull_request_reviews` set to true. Branch protection is untouched - `enforce_admins` and all five required status checks stand, and `required_approving_review_count` is 0, so the "approve" half of that setting grants no bypass power. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…pend path) `python tools/cost_ceiling.py --check` on a fresh tree WROTE to the state tree. Call chain: check() -> read_ledger_total_tokens() -> fleet_ledger.parse_ledger_rows() -> ensure_ledger_header(), which mkdir'd <state>/ledger/ and wrote OUTCOMES-LEDGER.md just for asking "how much have we spent?". Check modes must never mutate. Fix is at the source, in fleet_ledger.parse_ledger_rows(): drop the ensure_ledger_header() call and return [] when the ledger is absent. Chosen over patching cost_ceiling because parse_ledger_rows is the shared reader behind cost_ceiling, cost_projection AND state_store/read_api.read_ledger_rows -- all three inherited the write, and all three already document "returns empty list if the file is missing". ensure_ledger_header() is now documented as WRITE-PATH-ONLY and still runs from append_ledger_line/harvest/rotate, so appends create the header exactly as before. TDD: 6 new tests failed first, then passed. - tests/test_cost_ceiling.py::TestCheckModeIsReadOnly -- API + CLI + daily + windowed check() leave a state-tree snapshot byte-identical; plus a "read-only is not blind" test proving an existing ledger is still summed. - tests/test_fleet_ledger_append.py::TestLedgerReadPathIsReadOnly -- reader purity for parse_ledger_rows/summary, and REGRESSION coverage that append_ledger_line + append_wave still create the header (and append_wave stays idempotent) now that the reader no longer materializes it. Contract preserved: a missing ledger is still spend=0 / exit 0 (never trips on a fresh install); an UNREADABLE ledger still raises into the fail-safe path (exceeded=True, tripped=False). Absent means zero; unreadable means stop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tests/test_traps.py::TestCIDriftTrap::test_ci_workflow_files_are_valid_yaml lexes workflow files line by line and rejects any non-comment line holding an odd number of double quotes. It has no notion of YAML block scalars, shell line continuations or heredocs, so the previous revision tripped it on ten lines that were nonetheless valid for Actions: multi-line double-quoted PR/issue bodies, backslash-continued gh invocations, and jq filters with escaped quotes nested inside double quotes. Rewritten so every line balances its own double quotes, with no change in behaviour: - PR body and failure-issue body are built with unquoted heredocs into $RUNNER_TEMP and passed via --body-file, so the prose lines carry no quotes at all and interpolation still works. - gh invocations are single lines; the PR title moved to single quotes. - The issue-dedup jq filter reads the title through jq's env.* rather than nesting escaped quotes, which removes the last odd-quote line. - A comment at the top of the file records the trap's rule so the next editor does not rediscover it the hard way. Verified: the exact failing test passes, the full tests/test_traps.py suite passes (14), ci_workflow_lint / workflow_model_linter / ci_gate_runability / verify_gates_wired / encoding_lint all pass, and both heredocs were dry-run through bash to confirm they render flush-left after YAML dedent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Pipe-join the sub-bullet field lists for fleet_instances, fleet_multibox_summary, and ci_job_status into dense single lines. No contract information removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This PR adds tests/mcp-ci-status.test.mjs; verify_test_suite_count.py expects the documented count to match discovery. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Owner
Author
|
Dissolving merge-queue batch: ci (0) is not green |
This was referenced Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge-queue batch built by tools/merge_queue.py.
Members: #717, #689, #696, #702, #712, #716, #723
Members are closed only after
git merge-base --is-ancestorproves their content landed on main.