chore(claude-md): fix stale agent docs and the verification wrapper that passed on failures - #2175
Merged
Conversation
…les, and the approval gate
…hat passed on failures
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
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.
Two commits. The first restores the agent configuration to
7f9adefc1and re-adds only the parts that earned their place. The second fixes what an audit of that restored state found.Why
An audit of the agent-facing docs and tooling turned up two problems that no check in this repository could catch.
The verification wrapper reported success on failures.
verify.sh parseon a lint log containing 7 SwiftLint errors printed all 7 and then reportedstatus: PASS, exit 0. An agent that trusts the verdict line, which is the whole reason the wrapper exists, would ship lint-broken code and report it as verified.The docs described a repository that had moved. 16 claims in
CLAUDE.mdnamed symbols, paths, counts and CI behaviour that had drifted. The worst had been false for a week and had been copied into three other files.verify.sh
Seven defects, each reproduced before and after.
PASS, exit 0FAIL, exit 1PASSINCONCLUSIVE, exit 2FAILINCONCLUSIVE, exit 2--rootpointing at a missing directoryPASS--runwith no value$2: unbound variabletailon a missing log--helpThe root causes were that
report_errorsprinted findings without setting the status, that the zero-cases guard was unreachable fromparsebecause it keyed on case lines a wedged host never prints, and that the test path calleddiagnose_environmentand discarded its return value while the build path used it correctly.Four cases were re-run to confirm no regression: a clean lint log still passes, a quarantined suite still passes, a real test failure still fails, and no false
INCONCLUSIVEappears.scripts/check-doc-symbols.sh
Correcting 16 claims by hand only resets the clock, so this checks the mechanical half automatically: backticked paths must exist, backticked CamelCase must resolve in this tree or the macOS SDK, named scripts must exist and be executable,
Skill(name)and$namemust resolve, and stated plugin counts must match the tree.Fenced code blocks are stripped first, because a claim in prose is a claim and a symbol inside an example is an example. Gitignored paths pass, since a per-developer file being absent is the expected state. It runs inside
verify.sh lint, so a stale doc now fails the same step a lint violation does.It checks 251 references and the tree is clean. On the state before this branch it found all of the mechanical drift.
CLAUDE.md
All 16 stale claims corrected. The ones that would have caused real harm:
saveOrClearAggregatedSync()did not exist, and the invariant described the opposite of the real behaviour. The realTabPersistenceCoordinator.saveAggregatedSync()opens withguard !tabs.isEmpty else { return }and its doc comment reads "Ending a session is not closing your tabs, so this never clears." This is a data-loss invariant, and following it as written would have reintroduced the bug it was written to prevent.Compile every pluginstep inmacos-tests.ymlbuilds-scheme AllPluginswhenever the change touchesPlugins/. It landed on 2026-08-11 in fix(plugin-mongodb): export ObjectId and dates as mongosh constructors, and compile every plugin in CI #2091. The real remaining gaps are packaging and the unwired ABI check, and those are now stated instead.build-plugin.yml, andscripts/build-plugin.sh:10exists for exactly that case.SQLCompletionAdapterisQueryCompletionAdapter.DataChangeUndoManagerdoes not exist.TabPersistenceServiceandTabStateStorageareTabPersistenceCoordinatorandTabDiskActor.TabStateStorage.saveLastQuery()isTabQueryContent.maxPersistableQuerySize.SWIFT_VERSION = 5.0not 5.9.scripts/build-plugin.shtakes positional arguments, not-scheme.swiftlint lintnever seesPlugins/,Packages/or the test targets, because.swiftlint.ymlsetsincluded: [TablePro].testandregistry-readinessas well as the three the doc listed.The file also now obeys its own writing rule. It banned em dashes "Anywhere" while using them on 42 lines, including in the rule's own section. Two remain, both the character quoted as data.
Hooks
Four defects in
.claude/hooks/guard.sh, plus a 30-case regression suite at.claude/hooks/guard-test.sh.no-commit-pushmissed the newline-separated form, which is the shape a multi-line Bash block actually arrives in.grepworks a line at a time, so.*never crossed the newline.writing-stylehad no word boundaries, sorobustnessandcomprehensiveCheck()in ordinary Swift tripped it on every write.changelog-intactcompared heading counts, so renaming a released heading in place passed. It now compares the heading set.regenerate-notefired on every Swift write. It now fires only for a file git has never seen, which is the only case that needs a regeneration.One reported defect was deliberately not fixed: the git guards match the raw command text, so they fire when a command merely quotes a banned pattern. Stripping quoted spans first would wave through
bash -c '<the banned command>'. A safety net should fail closed, and that is now documented in the file.The test suite builds every banned pattern from parts at runtime, because a suite written the obvious way blocks itself.
Skill
SKILL.mdopened with "It runs to completion with no approval gate" while also documenting the Phase 2 gate. The two statements are now one.schema, so their final messages were uncapped. That is the exact failure theDIGEST_RULESblock immediately above warns about. They now return a capped objection schema.references/quality-bar.mdwas 65% restatement. Its two unique sections, the refactor-versus-patch criteria and the native bar, moved intoSKILL.md; the file is deleted. That also resolved a contradiction where it said "do not stop to ask which one to build" while the skill documents a gate that does exactly that.swift-lspplugin is not enabled, so theLSProw no longer claims it is.TodoWriteis not present in every session, so the skill no longer depends on it.force_unwrappingdisables are five, and they are inline comments rather than config entries.evals/evals.jsongraded againstConnectionSwitcherSheet.swift, which does not exist. The component isConnectionSwitcherPopover.swift.Verification
bash -non all five shell scripts.claude/hooks/guard-test.sh: 30 passed, 0 failednode --checkevals.jsonparsesscripts/check-doc-symbols.sh: clean, 251 referencesverify.sh parseon the failing lint log: exit 1No
xcodebuildwas run. Nothing here touches app or plugin source, and another session was holding the shared checkout for unrelated work, so starting a build would have wedged the test host for both of us.Not done
The interactive eval loop from the skill-creator workflow needs a human at the review viewer, so it is not part of this branch.
evals/evals.jsonis updated and ready for it.