Skip to content

chore(claude-md): fix stale agent docs and the verification wrapper that passed on failures - #2175

Merged
datlechin merged 2 commits into
mainfrom
chore/agent-rewrite
Aug 18, 2026
Merged

chore(claude-md): fix stale agent docs and the verification wrapper that passed on failures#2175
datlechin merged 2 commits into
mainfrom
chore/agent-rewrite

Conversation

@datlechin

Copy link
Copy Markdown
Member

Two commits. The first restores the agent configuration to 7f9adefc1 and 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 parse on a lint log containing 7 SwiftLint errors printed all 7 and then reported status: 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.md named 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.

Case Before After
Lint log with 7 errors PASS, exit 0 FAIL, exit 1
Wedged test host, zero cases executed PASS INCONCLUSIVE, exit 2
Locked build database during a test run FAIL INCONCLUSIVE, exit 2
--root pointing at a missing directory ran on, reported PASS exit 3 with a message
--run with no value $2: unbound variable exit 3
tail on a missing log exit 0 exit 3
--help exit 3 exit 0

The root causes were that report_errors printed findings without setting the status, that the zero-cases guard was unreachable from parse because it keyed on case lines a wedged host never prints, and that the test path called diagnose_environment and 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 INCONCLUSIVE appears.

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 $name must 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 real TabPersistenceCoordinator.saveAggregatedSync() opens with guard !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.
  • "PR CI never compiles the registry-only plugins" is false. The Compile every plugin step in macos-tests.yml builds -scheme AllPlugins whenever the change touches Plugins/. 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.
  • "Never publish bundled plugins to the registry" is contradicted by the tooling: six bundled plugins have registry arms in build-plugin.yml, and scripts/build-plugin.sh:10 exists for exactly that case.
  • SQLCompletionAdapter is QueryCompletionAdapter. DataChangeUndoManager does not exist. TabPersistenceService and TabStateStorage are TabPersistenceCoordinator and TabDiskActor. TabStateStorage.saveLastQuery() is TabQueryContent.maxPersistableQuerySize.
  • Counts: 31 plugin bundles not 30, 17 registry-only not 16 (Dameng was missing), 51 coordinator extension files not "7+", SWIFT_VERSION = 5.0 not 5.9.
  • scripts/build-plugin.sh takes positional arguments, not -scheme.
  • A bare swiftlint lint never sees Plugins/, Packages/ or the test targets, because .swiftlint.yml sets included: [TablePro].
  • The release job needs test and registry-readiness as 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-push missed the newline-separated form, which is the shape a multi-line Bash block actually arrives in. grep works a line at a time, so .* never crossed the newline.
  • writing-style had no word boundaries, so robustness and comprehensiveCheck() in ordinary Swift tripped it on every write.
  • changelog-intact compared heading counts, so renaming a released heading in place passed. It now compares the heading set.
  • regenerate-note fired 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.md opened with "It runs to completion with no approval gate" while also documenting the Phase 2 gate. The two statements are now one.
  • The three Phase 2 critics passed no schema, so their final messages were uncapped. That is the exact failure the DIGEST_RULES block immediately above warns about. They now return a capped objection schema.
  • references/quality-bar.md was 65% restatement. Its two unique sections, the refactor-versus-patch criteria and the native bar, moved into SKILL.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.
  • The swift-lsp plugin is not enabled, so the LSP row no longer claims it is.
  • TodoWrite is not present in every session, so the skill no longer depends on it.
  • The four force_unwrapping disables are five, and they are inline comments rather than config entries.
  • evals/evals.json graded against ConnectionSwitcherSheet.swift, which does not exist. The component is ConnectionSwitcherPopover.swift.

Verification

  • bash -n on all five shell scripts
  • .claude/hooks/guard-test.sh: 30 passed, 0 failed
  • Both embedded workflow scripts parse under node --check
  • evals.json parses
  • scripts/check-doc-symbols.sh: clean, 251 references
  • verify.sh parse on the failing lint log: exit 1
  • Writing-style grep on the staged diff: clean apart from the deliberate test fixtures

No xcodebuild was 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.json is updated and ready for it.

@mintlify

mintlify Bot commented Aug 18, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Aug 18, 2026, 5:07 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit 25380a7 into main Aug 18, 2026
9 checks passed
@datlechin
datlechin deleted the chore/agent-rewrite branch August 18, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant