Repository navigation
Escalate stale spec drift issues, and open a pull request for each new one - #11
Merged
Merged
Conversation
An issue still open after 14 days gets the spec-drift-overdue label and a comment for a maintainer. Each new drift issue starts spec-drift-fix.yml, where Claude rechecks the page, moves the pins and opens a pull request for review (it needs a Claude key secret and skips without one). A failed watch run opens its own issue, closed by the next good run. The shared script gains these commands and a json-field source kind for poppy.ax. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
Rework spec-drift-fix.yml into three jobs after a security review: a read-only job gathers the issue and what changed upstream (spec-drift.mjs context), Claude drafts the fix with file tools only and no GitHub token, and a job with no model refuses any patch outside content/standards (spec-drift.mjs vet-patch) before opening the pull request. The dispatch now runs after the status publish and may fail without costing it, cancelled runs no longer count as failures, and escalation tolerates runs that start a little early and posts its comment before the label. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
A new --plain option refuses added lines with <, { or } or import/export lines in matching files. poppy.ax uses it for its .md and .mdx content, which a site build (Vercel previews included) would run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
Review found that vet-patch read the patch as text, so a path with a space or a line starting with ++ slipped past it, and the job that ran the checks held the write token. vet-staged now applies the patch and asks git what changed (only added or modified regular files, pin lines only in pin files, only string pin values in manifest JSON, no markup or code in MDX). A new verify job with no token vets and runs the checks; propose runs only git with hooks off and gh. The agent's description is cleaned (pr-body), a failed run comments on its issue, branch names carry the run id, and the dispatch step runs unless the run was cancelled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
…e pull request A third security review showed that gates judging agent-written files keep leaking (removed MDX lines, any constant with a pin-shaped line). So nothing a model writes is committed any more. Claude writes only a review; code moves the pins (spec-drift.mjs apply-pins, from values the watch already shape-checked), git confirms only manifest-named pin values changed (vet-staged, now pairing pins by name), and the pull request carries the review for a person to act on, as a draft when a check failed. The propose job keeps no stored credentials and uses the token only for the push and gh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
From the fourth security review: the draft job deletes .git before the agent runs and later jobs check the pack's hash; poppy.ax's prepared catalog must match the profile the watch saw and use https links only; cleanPrBody escapes raw HTML, drops link reference lines and invisible characters, and catches more closing-keyword forms; apply-pins searches a manifest pin only in its own entry, reads every pin back afterwards, and leaves a newer dated revision for a person to adopt (the run then posts the review on the issue). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VeACDNmxsBifFG4eSqRsUi
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
4 of 5 tasks
This branch was successfully deployed
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.
What changed
Spec drift issues now lead to action instead of waiting for someone to notice:
spec-drift-overduelabel and one comment that mentions @liady. To change who is mentioned, edit--escalate-mentioninspec-drift-watch.yml.spec-drift-watchissue, which the next good run closes. Cancelled runs don't count.spec-drift-fix.yml. It opens a pull request that moves the pins and carries Claude's review of the upstream change: what changed, which claims on the page still hold, and suggested edits with sources. A maintainer makes those edits on the branch and merges.How the fix workflow stays safe. Spec text is written by whoever controls the upstream sites, so nothing a model writes is ever committed, and the review is the only thing the agent produces. The workflow has five jobs:
.git): Claude Code 2.1.290 runs with--restrictedand file tools only, with no shell, web, subagents, hooks or MCP. I tested this locally with the pinned version and a hostile prompt. Shell, web fetch, writes outside the checkout, reads of/proc/self/environ, subagents, a project hook and a project MCP server were all refused.spec-drift.mjs apply-pinsmoves the pins from values the watch already shape-checked.vet-stagedthen asks git whether only pin values changed, after which the checks run. A failing check turns the pull request into a draft; it is not hidden.pr-body.A newer dated revision (ACP's spec folders) is never adopted automatically. The review goes on the issue instead.
It needs an
ANTHROPIC_API_KEY(preferably from a workspace with a spend limit) orCLAUDE_CODE_OAUTH_TOKENrepository secret, and skips without one. Each run is capped at 40 turns and USD 5 of estimated spend. Pull requests opened with the workflow token don't start CI, so close and reopen one to run it.scripts/spec-drift.mjsgainscontext,apply-pins,vet-staged,pr-body,health, escalation,--opened-outand ajson-fieldsource kind; poppy.ax uses the last one.spec-pins.jsongainspin_file. The script stays byte-identical in all three repos. The dispatch step runs after the status publish and is allowed to fail.Sources
No page content changed. The fix workflow follows the
anthropics/claude-code-actionand Claude Code CLI documentation (--restricted,--tools,--permission-mode dontAsk,--permission-prompts none,disableAllHooks,--max-turns,--max-budget-usd). I used the CLI directly, not the action, so the agent's job never holds a GitHub token.Checklist
status, the evidence meets the rules incontent/contribute.md. (No status changed.)last_verifiedon pages where I rechecked every claim. (None changed.)Reviews.
@ora-security-reviewerran four rounds. The first three blocked: the agent had a shell and a write token; then the patch-text gate could be bypassed; then MDX and pin-shape gates could be beaten. The fourth approved the design in which no model output is committed, and its hardening points are fixed in the last commit. A correctness review's findings are also fixed.Verification
npm run typecheck,npm run lintandnpm test(17 tests) pass.contextandapply-pinsran on the real Poppy drift (open issue Poppy: the spec changed since ax.guide last checked it #10). They moved exactly the three pins incontent/standards/poppy.mdandspec-pins.json,vet-stagedpassed, the tests passed, and the watcher then read Poppy as clean.gh: escalation fires once, health issues open and close, and opened issues are recorded. Every workflowrun:block passesbash -n.Merge order: merge this first. The Ora and poppy.ax PRs compare their script copies with this repo's
main.Generated by Claude Code