chore(agents): make local checks targeted and setup non-destructive - #706
Merged
Conversation
The policy still carried a mandatory comprehensive step: check.sh ran once before every pull request, every commit was to leave the full check table green, and two change categories escalated straight to the whole gate. Each of those reads as an instruction to run the entire repository locally, which is CI's job. The policy now says one thing in one place: choose the smallest set of checks that gives real feedback on the change, read what CI answered after pushing, and never claim a check passed without running it. High-risk changes escalate to the *relevant* suites — the real-server cycle scenario for state, gating and progress, the drift checks and stub-driven browser specs for a published wire shape — not automatically to everything. check.sh keeps every group and stays the comprehensive local run for the moments a developer deliberately chooses its cost: reproducing a CI failure, debugging an integration problem, validating a high-risk change.
setup_agents.sh deleted a regular CLAUDE.md and replaced it with the AGENTS.md symlink. A CLAUDE.md that is not the generated symlink is a developer's own file, possibly carrying local configuration, and a setup script has no business converting it by force. The symlink is now created only where nothing exists. The expected symlink is recognized and left alone; a regular file, a directory, or a symlink to any other target is left exactly as found, with a notice naming what was found and the manual command that adopts the canonical text. A regression test runs the real script in a throwaway repository layout and holds all five cases: creation, idempotence, the preserved regular file, the preserved foreign symlink, and the pruning of a deleted skill's link.
Preserving an unexpected CLAUDE.md while exiting 0 was the quieter half of the failure the last commit removed: a caller reads "setup succeeded" while Claude is still reading a divergent file. A conflicting CLAUDE.md — a regular file, a directory, or a symlink to any other target — now aborts the run with an ERROR on stderr and a non-zero exit, and the check happens before any skill symlink is created or pruned, so a conflict leaves the tree exactly as it found it and never prints the success message. The missing-file and expected-symlink paths are unchanged: create, or recognize and succeed. The regression suite flips the file and foreign-symlink cases to expect failure, asserts the conflict performed no setup at all, and adds the directory case.
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.
The agent-policy consolidation that merged as the one-home-per-rule change (#705) left two gaps on
main. The check policy still required a full localbash scripts/check.shrun once before every pull request, kept "every commit leaves the checks above green", and escalated two whole change categories straight to the full gate — each of which reads, to a coding agent, as an instruction to run the entire repository locally before ordinary work is allowed to complete. Andscripts/setup_agents.shdeleted a regularCLAUDE.mdto replace it with theAGENTS.mdsymlink, which is destructive toward a file that may carry a developer's local configuration.What changed
The policy now says one thing, in
AGENTS.md## Checks, and the other documents point at it: local development runs the smallest set of checks that gives real feedback on the change, GitHub Actions runs the exhaustive matrix on every pull request, and reading what CI answered is part of pushing. High-risk changes escalate to broader relevant checks — the real-server cycle scenario for anything touching state, gating or progress, the generation/drift checks and stub-driven browser specs for a published wire shape — never automatically to every test in the repository.scripts/check.shkeeps all of its groups and remains the comprehensive local run for the moments a developer deliberately chooses its cost: reproducing a CI failure, debugging an integration problem, validating a high-risk change locally. It is no longer described as a routine step before a commit, push, or pull request.CONTRIBUTING.md,refactor-protocol,python-setupandnodejs-setupwere reconciled to the same statement; "Report failures verbatim. Never claim a check passed without running it" stands unchanged.setup_agents.shnow creates theCLAUDE.md → AGENTS.mdsymlink only where noCLAUDE.mdexists, and the expected symlink is recognized and left alone on re-runs. A conflictingCLAUDE.md— a regular file, a directory, or a symlink to any other target — is preserved exactly as found and fails the run: the script prints anERRORnaming what it found and the manual command that adopts the canonical text, exits non-zero, and does so before creating or pruning any skill symlink, so a conflict performs no setup at all and never prints the success message. A new regression suite,tests/scripts/setup_agents.test.mjs, runs the real script in a throwaway repository layout and holds six cases: the symlink is created where nothing exists, both runs of an idempotent pair succeed, a regularCLAUDE.mdsurvives byte-for-byte and fails the run with nothing created, a directory survives whole and fails the run, a foreign symlink keeps its target and the error names both targets, and a deleted skill's dangling link is pruned.Test plan
Targeted validation, which is the policy this pull request states; the exhaustive matrix is delegated to this pull request's own CI by design.
Found, not fixed
.gitignorelists.codex/among the generated agent directories, butsetup_agents.shhas never created it; the entry is either anticipatory or stale. Nothing in this change depends on it.