Skip to content

Guard the agent-config topology with a unit test - #728

Merged
kasnder merged 1 commit into
masterfrom
claude/agent-setup-patterns-8ux4sp
Aug 20, 2026
Merged

Guard the agent-config topology with a unit test#728
kasnder merged 1 commit into
masterfrom
claude/agent-setup-patterns-8ux4sp

Conversation

@kasnder

@kasnder kasnder commented Aug 19, 2026

Copy link
Copy Markdown
Member

Follow-up to #727. That PR made AGENTS.md a short entry point with agents/docs/ read on demand; nothing yet stops that structure decaying back into one long file, or a pointer going stale without anyone noticing. This adds the mechanical half, modelled on DuckDuckGo's AiConfigChecker Gradle gate.

What it checks

app/src/test/java/net/kollnig/missioncontrol/AgentConfigTest.java — plain JUnit, no Android or Robolectric dependency, so it runs inside the existing unit-test job.

Check Failure it prevents
everyAgentDocIsReachableFromAnAlwaysLoadedFile nothing loads agents/docs/, so a doc AGENTS.md does not point at will never be read
everyPathReferenceResolves a mistyped pointer silently removes guidance instead of failing loudly
agentsMdDoesNotRestateVolatileVersions a tool version copied into AGENTS.md drifts from the build files without anything failing
agentsMdStaysShortEnoughToLoadEverySession the entry point is paid for in every session by every tool; 150-line budget (currently 112)
vendorWiringPointsAtSharedScripts CLAUDE.md growing its own copy of the guidance, or .claude/settings.json pointing at a script that no longer exists

Reference scanning skips fenced code blocks, globs, placeholders and absolute paths, and only treats a path as a repo reference when its first segment exists at the repo root — so package paths (src/main/java/) and build outputs (app/build/outputs/apk/…) don't produce false positives.

Testing

The container has no Android SDK, so Gradle couldn't run the suite here. Instead the test was compiled with javac and run under JUnitCore directly:

  • Passes from both working directories the repoRoot() helper supports (module dir and repo root), matching the existing assetPath() pattern in BlockingBaselineSubsetTest.
  • Each check was mutation-tested against a fixture copy of the tree, and each one fails on exactly the defect it targets: an unreferenced doc, agents/docs/triage.mdtriaging.md, an injected NDK 27.2.12479018 and JDK 17 line, 60 filler lines, and a renamed hook script. The tree is clean and green afterwards.

Worth confirming the suite passes under ./gradlew :app:testGithubDebugUnitTest in CI, since I couldn't run it locally.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TL2vW7nHBGUqkA55wCHRqj


Generated by Claude Code

AGENTS.md is loaded in every agent session; agents/docs/ is loaded by
nothing and is only read because an always-loaded file points at it.
Three failure modes are therefore silent: a doc nothing points at, a
pointer that stops resolving, and a fact restated in AGENTS.md that has
drifted from the build files it was copied from.

AgentConfigTest checks all three, plus a line budget on AGENTS.md and
that .claude/settings.json only ever points at scripts that exist in the
shared agents/ directory. Plain JUnit, no Android dependencies, so it
runs in the existing unit-test job.
@kasnder
kasnder marked this pull request as ready for review August 20, 2026 12:21
@kasnder
kasnder merged commit 6a7d7c2 into master Aug 20, 2026
2 checks passed
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.

2 participants