| name | sync-docs |
| description | Check llmgps documentation against the current implementation and report or fix drift. Use after changing src/lib/gps.ts, src/lib/server-state.ts, src/lib/app-config.ts, src/lib/llm.ts, the API routes, or package.json — or whenever asked to verify the docs are still accurate. |
sync-docs
Verify that llmgps's documentation still describes the code as it exists now, and fix what drifted.
The docs in this repo make specific, checkable claims — function names, file paths, event names,
call counts, npm scripts. That precision is the point, and it is also what rots. This skill checks
the claims that are cheap to verify and likely to be wrong.
Read the code, don't trust the docs. The whole purpose here is finding places where the docs
are wrong, so a doc statement is never evidence that something is true.
Scope
Documents to check:
| File | What it claims |
|---|
README.md | Value proposition, mode behaviour, retrieval pipeline, setup commands, env vars |
README.zh.md | Chinese translation of the same — must stay structurally in sync |
CONTRIBUTING.md | Setup commands, architecture map, workflow walkthrough, checklists |
AGENTS.md | Repository invariants, validation commands |
docs/ARCHITECTURE.md | Everything, in detail — the largest drift surface |
CLAUDE.md | Local, git-ignored briefing (may be absent) |
Do not rewrite prose that is still accurate. This is a correction pass, not an editing pass.
Checks
Run these against the current tree. Each one has caught a real error before.
1. Do the referenced paths exist?
Extract every src/..., .github/... and docs/... path mentioned in the docs and confirm it
exists. Also check relative Markdown links resolve:
python3 - <<'EOF'
import re, os
for f in ["README.md","README.zh.md","CONTRIBUTING.md","AGENTS.md","docs/ARCHITECTURE.md","CLAUDE.md"]:
if not os.path.exists(f): continue
base = os.path.dirname(os.path.abspath(f))
for m in re.finditer(r'\[([^\]]*)\]\(([^)]+)\)', open(f).read()):
link = m.group(2)
if link.startswith(('http','#','mailto:')): continue
t = os.path.normpath(os.path.join(base, link.split('#')[0]))
if link.split('#')[0] and not os.path.exists(t):
print(f"BROKEN {f}: {link}")
EOF
2. Do the referenced symbols still exist, with those names?
The docs name many functions. Grep for each one you see mentioned; a rename is the most common
silent break. High-traffic examples:
runGpsWorkflowStreaming · runGpsWorkflow · runSynthesisOnly · checkConsensus ·
checkMemoryRelevance · maybeInjectWebSearch · fetchWebSearchResults · buildOpinionMessages ·
injectMemoriesIntoMessages · buildSynthesisMessage · buildCompressionMessage ·
createFanOutQueue · estimateTokens · ensureValidRequest · proxyFetch · getExecutionSettings ·
encryptSecrets · decryptSecrets · getAppStatus · saveOwnerSettings · sanitizeGpsResponsePayload
3. npm scripts
Docs must never name a script that doesn't exist. Compare the docs against:
node -e "console.log(Object.keys(require('./package.json').scripts))"
CONTRIBUTING.md and AGENTS.md both assert there is no test framework. If scripts.test
appears, or a test runner shows up in devDependencies, that assertion is now false in several
places — including the cost-awareness and PR-checklist sections.
4. The streaming event contract
GpsStreamEvent in src/lib/gps.ts is enumerated in CONTRIBUTING.md, AGENTS.md (invariant 4)
and docs/ARCHITECTURE.md §7 (as a table). Compare the union members against all three lists:
sed -n '/export type GpsStreamEvent/,/^$/p' src/lib/gps.ts
A new event type that isn't in the §7 table is drift. So is a changed payload field.
5. OwnerSecrets field parity
The most dangerous invariant in the repo. Verify that encryptSecrets and decryptSecrets still
enumerate fields by hand and still agree with each other:
sed -n '/^async function encryptSecrets/,/^}/p' src/lib/server-state.ts
sed -n '/^async function decryptSecrets/,/^}/p' src/lib/server-state.ts
Report any field present in one and missing from the other as a bug, not as doc drift — that
is a live persistence failure. If the manual enumeration is ever replaced by something type-safe,
the warnings in CLAUDE.md, AGENTS.md invariant 1, CONTRIBUTING.md and ARCHITECTURE.md §8
all need rewriting.
6. Provider list
README.md claims 12 providers and four request shapes. Check:
sed -n '/^export type ProviderId/,/;/p' src/lib/llm.ts
grep -o 'requestShape: "[a-z-]*"' src/lib/llm.ts | sort -u
Both READMEs list the providers by name — update both if this changed.
7. Workflow behaviour
The most valuable and most expensive check. Re-read runGpsWorkflowStreaming and compare against
CONTRIBUTING.md "Core workflow" and ARCHITECTURE.md §4–§6, §10. Specifically confirm:
MAX_DEBATE_ROUNDS is still 2 (docs say 2 in five places, including the ~19-call cost estimate)
- Consensus is still a
startsWith("YES") string match
checkMemoryRelevance still fails open
- Evidence refresh still happens before round 2 only
- Memories are still injected inside the last user message, not as a message pair
- The failure-handling table in §10 still matches the actual try/catch behaviour
runGpsWorkflow still has no caller (grep -rn "runGpsWorkflow\b" src/ | grep -v gps.ts)
8. Cost claims
Docs state a Debate run with 5 responders is "up to ~19 model calls". Recount if the loop changed:
5 initial + 10 debate + 2 consensus + 1 compression + 1 synthesis + 1 memory relevance +
1 query generation. This number appears in README.md, README.zh.md, CONTRIBUTING.md,
AGENTS.md and the PR template.
9. Issue pointers
CONTRIBUTING.md "Potential contribution areas" links to GitHub issues instead of describing
them. Check whether any have been closed:
gh issue list --state closed --limit 20
A closed issue still listed under "Currently open" should be removed from the table. If it was a
bug that ARCHITECTURE.md §13 also warns about, remove that warning too.
10. Bilingual parity
README.zh.md mirrors README.md's structure. Compare heading lists:
grep '^#' README.md; echo ---; grep '^#' README.zh.md
Sections added to one and not the other are drift. Also verify the zh table-of-contents anchors
still match its own headings.
Reporting
Group findings as:
- Wrong — the docs state something the code contradicts. Fix these.
- Stale — the code gained behaviour the docs don't mention. Fix if it's material to a
contributor; skip trivia.
- Code bugs found while checking — do not fix these as part of a doc sync. Report them and
offer to file an issue.
Then state plainly what you changed and what you checked but left alone. If nothing drifted, say
so — "checked, no drift" is a valid and useful result, and padding it with cosmetic edits is not.
Rules
- Documentation only. Do not change application code, even to fix a bug you found — that is a
separate, reviewable change.
- Do not add dependencies.
- Do not make live provider API calls. Every check here is static.
- Keep the existing voice: concise, specific, no marketing language, no invented certainty.
- Never claim answers are "verified" — llmgps supplies models with retrieved evidence, it does not
fact-check. Preferred wording: evidence-grounded, web-grounded, synthesized, multi-model
deliberation.
- Run
git status first and leave unrelated uncommitted work alone.
- If you edit
CONTRIBUTING.md or README.md in a way that affects the Chinese README, update
both in the same pass.