myco:skill-reference-and-manifest-drift-maintenance
Skill979 starsChanged 19 days agoMITView on GitHub
Use when adding, changing, or reviewing tool categories, tool parameters, or tool docstrings in unifi-mcp apps (apps/access, apps/network, apps/protect) whose behavior surfaces through generated artifacts: each app's generated tool manifest (e.g. apps/protect/src/unifi_protect_mcp/tools_manifest.json) and the plugin skill reference docs with AUTO:tools:<category> marker blocks. Applies even if the user only asks to "add a tool" and doesn't mention manifests or docs — generated artifacts are a deterministic function of Python source and CI's drift-check gate only verifies rendered content matches disk, never that a new category/tool got a section, marker, or full-depth description. Covers: regenerating manifests/skill-references after source changes, the new-tool-category checklist (ToC + AUTO markers + generator run), resolving generated-manifest merge conflicts by regeneration (never by hand), and catching pre-existing drift surfaced when an unrelated PR trips the reference-check CI gate.
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 8 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 87
Run the manifest generator for every affected app (make manifest at the app level, or make generate at the repo root for all apps).
- Distinctive: line 93
If a parameter's default or type changed, confirm the manifest description string was regenerated *after* the docstring update — an …
- Distinctive: line 103
Treat "the description field exists" as insufficient review signal.
- Distinctive: line 135
When merging main into a working branch (fork-edit, rebase, or a long-lived branch catching up), a conflict in the app's generated manifest …
- Distinctive: line 147
Do this inside a worktree venv synced to locked dependencies so the output is byte-identical to what CI would produce — a stale venv can …
- Distinctive: line 151
Never resolve a manifest conflict by manually editing either side of the diff — because the manifest is a deterministic function of source, …
- Distinctive: line 170
When the gate fires unexpectedly (or during any manifest/reference review), check whether the flagged gap actually originates from the …
- Distinctive: line 173
If pre-existing: bundle the drift fix into the PR that tripped the gate rather than filing a separate fix — it's faster and unblocks the …
- Very specific: line 176
Add the missing section header + AUTO:tools:<category> markers, then run scripts/generate_skill_references.py (or the app-level make …
- Distinctive: line 181
Treat this as confirmation of the Procedure B checklist for whichever earlier PR introduced the category — the fix strategy is the same …
- Very specific: line 187
Presence ≠ parity, everywhere in this pipeline: Every drift-check gate here (--check flags, manifest diffs, check-skill-references CI) only …
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Skill Reference & Generated Manifest Drift Maintenance
Each app has a generated tool manifest (e.g.
apps/protect/src/unifi_protect_mcp/tools_manifest.json) and a generated
skill reference doc under the corresponding plugin (e.g.
plugins/unifi-network/skills/unifi-network/references/network-tools.md,
plugins/unifi-access/skills/unifi-access/references/access-tools.md)
that uses <!-- AUTO:tools:<category> --> marker blocks. Both are
generated artifacts — a pure function of the Python source
(docstrings, parameter signatures, tool registrations).
packages/unifi-mcp-shared/src/unifi_mcp_shared/manifest_generator.py
implements the shared manifest-generation logic that each app's own
generator wrapper script calls (e.g.
apps/network/scripts/generate_tool_manifest.py, invoked via that app's
make manifest target). Nothing about these generated files should ever
be hand-authored. The recurring failure mode in this codebase is not that
regeneration is hard — it's that CI's drift-check only diffs
already-rendered content against disk. It cannot detect a missing
section, a missing marker, or a description that's technically present
but shallower/staler than the source. Those gaps are only caught by a
human applying the checklists below.
Prerequisites
- Locate the generator scripts for this repo before starting — search
scripts/(e.g.Grep -r "tools_manifest" scripts/andGrep -r "generate_tool_manifest\|generate_skill_references" scripts/) rather than assuming a fixed filename, since generator script names can move between refactors. Verified examples in this repo:scripts/generate_skill_references.py, the sharedpackages/unifi-mcp-shared/src/unifi_mcp_shared/manifest_generator.pymodule, and the per-app wrapper it documents (e.g.apps/network/scripts/generate_tool_manifest.py, run via that app'smake manifesttarget). - Locate the skill reference doc(s) for the category you're touching by
searching repo-wide for
AUTO:tools:markers (Grep -rl "AUTO:tools:" .) rather than assuming a fixed path. These live under each plugin's own skill references directory (plugins/<plugin>/skills/<plugin>/references/*.md) — not underapps/— and the exact category set can vary per plugin. - Regenerate inside a worktree venv synced to the locked dependencies. Using system Python or a stale venv can produce output that's subtly different from what CI would generate, defeating the point of regenerating at all.
make pre-commitdoes regenerate manifests when it's actually run — both the root Makefile (pre-commit: format generate lint test check-generated worker-typecheck, wheregenerateincludesmanifest) and each app's own Makefile (e.g.apps/network/Makefile:pre-commit: format manifest server-manifest lint test). But there is no.pre-commit-config.yamlwiring it into a git hook — it's a manualmaketarget. Don't assume a branch's manifest is current just because its author "probably ran pre-commit"; check explicitly (Procedure A) whenever behavior-relevant source changed.
Procedure A: Regenerate after any behavior/schema-relevant source change
Any change to a meta-tool's documented behavior, or a tool parameter's type/default, requires regenerating the manifest and manually diffing the generated text — not just confirming a description field exists.
- Make the source change (docstring, parameter signature, etc.) in the
Python source — e.g. a shared meta-tool module like
packages/unifi-mcp-shared/src/unifi_mcp_shared/meta_tools.py, or an app's own tool module. - Run the manifest generator for every affected app (
make manifestat the app level, ormake generateat the repo root for all apps). - Diff the app's regenerated manifest for content parity, not just presence: does the new manifest text actually carry the same depth of detail as the docstring (edge cases, defaults, caps, thresholds), or did it fall back to abbreviated legacy text?
- If a parameter's default or type changed, confirm the manifest
description string was regenerated after the docstring update — an
ordering bug (regenerate-then-edit-docstring, instead of
edit-docstring-then-regenerate) silently ships mismatched schema even
though runtime behavior stays correct. Example seen in this codebase:
a parameter changed from
list[str] = []toOptional[list[str]] = Noneat runtime coalesces identically (value or None), but a manifest generated before the docstring update still described the old "empty list" default — confusing for any LLM client reading the JSON schema directly instead of the Python source. - Treat "the description field exists" as insufficient review signal. The CI drift-check only fails on differing rendered content for fields/markers that already exist — it will pass even when the content is stale or abbreviated, because presence ≠ parity.
Procedure B: New tool category checklist (skill reference docs)
Adding a new tool category (e.g. a new settings category surfaced in a plugin's skill reference doc) requires three things, and bumping a tool count is not one of them:
- ToC entry for the category in the relevant plugin's skill
reference file (
plugins/<plugin>/skills/<plugin>/references/*.md). - Section block with
<!-- AUTO:tools:<category_name> -->/ closing marker comments (match the exact naming convention used by neighboring sections in the same file — e.g. thedoors,policies,credentialssections inplugins/unifi-access/skills/unifi-access/references/access-tools.md, or theclients,devices,firewallsections inplugins/unifi-network/skills/unifi-network/references/network-tools.md). - Run the generator and confirm the section is actually populated with tool entries — not just that the total tool count changed.
Why this matters: the drift-check flag only fails when re-rendered content differs from what's on disk for markers that already exist. A PR that adds tools but skips the ToC/section/markers entirely will pass CI cleanly while leaving the new tools completely undiscoverable in the reference doc — the count goes up, but an agent reading the doc body never finds them. This must be caught in review, not by the pipeline.
Procedure C: Resolve generated-manifest merge conflicts by regeneration
When merging main into a working branch (fork-edit, rebase, or a
long-lived branch catching up), a conflict in the app's generated
manifest file is the expected failure mode whenever both branches
touched any tool in that app — it is not a real content conflict, it's
two independent generation runs colliding.
- Accept the merge with conflict markers present in the manifest file (don't try to hand-resolve the diff).
- Regenerate the manifest from the now-merged Python source tree, using
the exact same generation command CI uses (the app's
make manifesttarget). - Stage the freshly regenerated file in place of the conflicted one.
- Do this inside a worktree venv synced to locked dependencies so the output is byte-identical to what CI would produce — a stale venv can produce a "regenerated" file that still diffs from CI's expectation.
Never resolve a manifest conflict by manually editing either side of the
diff — because the manifest is a deterministic function of source, manual
resolution only looks plausible; regeneration is the only version
guaranteed correct by construction. This class of conflict is enabled by
make pre-commit being a manual target rather than an enforced git hook:
a branch that never re-ran make pre-commit (or make manifest) after
main moved forward will carry a stale manifest that then conflicts on
merge.
Procedure D: Catch dormant drift when an unrelated PR trips the CI gate
The reference-check CI gate (the root Makefile's check-skill-references
/ check-generated targets) only fires when the generated manifest or a
reference file changes in the current PR. That means a category
shipped months earlier with a skipped documentation step (missing ToC
entry, missing AUTO:tools:<category> markers) can sit silently broken
until some unrelated PR happens to touch the same generated files and
trips the gate.
- When the gate fires unexpectedly (or during any manifest/reference review), check whether the flagged gap actually originates from the current change or is pre-existing drift from an earlier PR.
- If pre-existing: bundle the drift fix into the PR that tripped the gate rather than filing a separate fix — it's faster and unblocks the triggering PR immediately.
- Add the missing section header +
AUTO:tools:<category>markers, then runscripts/generate_skill_references.py(or the app-levelmake skill-referencesequivalent) to repopulate all sections, and sanity-check the resulting tool/section counts look right for the whole file, not just the category you fixed. - Treat this as confirmation of the Procedure B checklist for whichever earlier PR introduced the category — the fix strategy is the same checklist, applied retroactively.
Cross-Cutting Gotchas
- Presence ≠ parity, everywhere in this pipeline. Every drift-check
gate here (
--checkflags, manifest diffs,check-skill-referencesCI) only validates that already-rendered content matches disk. None of them validate that a new category, tool, or behavior actually got a section, marker, or full-depth description — that's a structural gap in the tooling, not a one-off bug, so don't rely on CI green to mean "the docs are complete." make pre-commitregenerates manifests, but only if someone runs it. Both the root Makefile (pre-commit: format generate lint test check-generated worker-typecheck) and each app's Makefile (e.g.apps/network/Makefile'spre-commit: format manifest server-manifest lint test) do include manifest regeneration — but there's no.pre-commit-config.yamlforcing it automatically on commit. This is the recurring enabler behind stale manifests, both as isolated drift (Procedure A) and as merge conflicts (Procedure C). If a contributor's branch is more than a few commits behindmainand touches any tool file, assume the manifest needs a manual regen check before merge — don't assumemake pre-commitwas ever run.- Never hand-edit a generated artifact, even to "quickly fix" a
conflict or a one-line description mismatch. Any manual edit to a
generated manifest or a skill reference file's
AUTO:block will be silently overwritten or drift again at the next regeneration — fix the Python source and regenerate instead. - A "correct behavior, wrong schema text" gap is still worth fixing.
Even when runtime behavior is unaffected (e.g.
value or Nonecoalescing masks a default-value mismatch), the generated schema is what LLM clients and downstream integrators actually read — treat schema/doc drift as a real defect, not cosmetic, even at low severity. - Out of scope: the runtime tool-index/registration-mode catalog is a
different "manifest" from the ones this skill covers.
docs/tool-index.mdandapps/worker/worker/src/relay-object.tsdescribe a discovery-time catalog keyed byUNIFI_TOOL_REGISTRATION_MODE(eager/lazy/meta_only) — it is hand-authored documentation of runtime behavior, not a generated artifact frompackages/unifi-mcp-shared/src/unifi_mcp_shared/manifest_generator.py. A known divergence hadmeta_onlymode's index initially behaving likelazymode instead of themeta_onlybehavior documented indocs/tool-index.md. Regenerating an app's generated manifest (e.g. the one underapps/protect/src/unifi_protect_mcp/) or skill-reference docs does not touch this code path — treat registration-mode divergence as a separate bug class from the generated-artifact drift this skill addresses.
Other versions1 project uses a version of this.
Word for word · 1
- sirkirby/unifi-mcp★ 978100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- docs/llms.txtllms.txt
- add-integration-api-toolSkill
- myco:api-endpoint-serializer-authoringSkill
- community-pr-batch-reviewSkill
- myco:community-pr-reviewSkill
- myco:extend-unifi-apiSkill
- myco:live-smoke-testingSkill
- myco:mcp-response-redaction-governanceSkill
- myco:monorepo-release-pipelineSkill
- myco:runtime-bootstrap-and-test-isolationSkill
- test-pruningSkill
- myco:unifi-client-data-correctnessSkill
- code-reviewSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

