Runs a whole-repo consistency audit of ysonet before a release or after a change. Checks that docs match the code, docs/ARCHITECTURE.md is current, both CLIs expose every gadget and plugin, each gadget and plugin has all required parts, tests exist for everything following the existing test patterns, no test opens a real application and every fired command goes through the test sink, all skills and agent files match the Anthropic skill standard, the git-tracked memory under .claude/memory/ is still true and indexed, no ignored, private, or machine-specific content leaked into tracked files, and the full test suite passes with zero errors. Use when the user asks to check consistency, audit the repo, verify docs and tests are in sync, check for private or local data leaking into the public repo, or confirm the tool is release-ready. Read-only until the user approves fixes.
Verify the whole repo hangs together: code, docs, both CLIs, gadget and plugin
completeness, tests, agent tooling, the shared memory, the public/private seam,
and a green full test run. Report first;
change only what the user approves. Never weaken a test to get a green tick (see
the "Test integrity policy" in CLAUDE.md).
Take the role of a senior .NET developer and maintainer doing a release review.
Say so, then work the checks below in order.
Mode
Default is REVIEW: find and report drift with evidence, change nothing.
Only make fixes the user approves. Clear, evidence-backed doc or comment fixes
can be applied when the user says "fix" or "repair"; anything touching payload
generation, a gadget, a plugin, or a test needs explicit sign-off first.
When two readings are both plausible, ask instead of guessing.
Load the contract first
Read CLAUDE.md and docs/ARCHITECTURE.md (at least its section headers and the
areas in scope). ARCHITECTURE.md is the code map; trust it as a guide but verify
its claims against the code, since it can lag. Note its Last reviewed for vX.Y.Z line near the top.
Read .claude/memory/memory.md and the files it indexes too. They are the shared
knowledge base, and they are also an audit target in check 7, so treat every
entry as a claim to verify rather than as fact.
Fast path: run the bundled scripts first
Two deterministic PowerShell scripts live beside this skill. Run them ONCE at the
start to collect the mechanical facts in one compact report, instead of many
Grep/Read calls. They are read-only and advisory; you still confirm semantic
claims and run the full suite yourself. Both auto-detect the repo root.
Inventory and cross-reference (checks 1-5): run
powershell -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/inventory.ps1".
It prints the authoritative gadget/plugin catalog (from the built exe's
--list, or an APPROXIMATE static scan if there is no Debug build), the
ARCHITECTURE.md declared counts and Last reviewed version vs VERSION,
validates every built gadget's variant sequence, compares formatter-count
suffixes with variant metadata, flags formatter-dependent option axes for
semantic review, audits test fire safety (no fire scope executes a real
application or a literal command; the
sink is wired and staged), and reports catalog gaps across ARCHITECTURE.md,
docs, and tests. Build Debug first so the catalog and metadata are exact.
Skill/agent frontmatter and style (check 6): run
powershell -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/check-skills.ps1".
It validates every .claude/skills/*/SKILL.md against the hard limits in
references/anthropic-skill-standards.md and flags style issues.
Treat every flag as a lead to verify, not a final verdict. A warning can be a
deliberate example (an anti-pattern shown on purpose); confirm before reporting
it. The scripts do not cover the interactive-CLI parity (check 3, part), the
semantic doc review (check 1), the memory audit (check 7), the public/private
seam (check 8), or the test run (check 9): do those yourself.
The nine checks
Run all nine. Track them with TodoWrite so none is dropped. Start from the
script output above, then gather any missing evidence with real tool calls; do
not assert from memory.
1. Docs match what is implemented
Compare every doc under docs/ against the code it describes: README.md,
gadgets-and-plugins.md, getting-started.md, usage-and-examples.md,
minification-savings.md, credits.md, references.md,
dotnet-deserialization-research.md, dependency-security.md.
Run python tools/references/refs.py verify for the reference archive. It is
offline and instant. It checks the archive against what was actually acquired,
that every published file still names its source, and that neither curated
reading list was modified by an archive run. A failure there is a real defect,
not noise.
Check that gadget names, plugin names, option flags, example commands, and
counts in the docs still exist and still behave as written.
Flag stale flags, renamed gadgets, dropped or added options, and example
commands that would now fail.
A PRIVATE module is expected to be absent from every public doc. A gadget with
GadgetTags.Private in Labels(), or a plugin whose IsPrivate() returns
true, must NOT appear in docs/gadgets-and-plugins.md, docs/credits.md, or
any other tracked file, and its absence is never a finding. Never name one in
the report either: say "a private module" and count it. In a clean clone there
are none, which is an empty applicable set, not a skipped check.
docs/dependency-security.md must cover every entry in ysonet/packages.config
and every file under ysonet/dlls/, with the version in the doc matching the
version actually referenced by ysonet/ysonet.csproj. Flag a package or DLL
that was added, removed, or re-versioned without a matching row, and flag a row
whose "shipped" claim disagrees with the CopyToOutputDirectory entries in the
.csproj. Do not propose upgrading a pin the doc marks as gadget side.
2. docs/ARCHITECTURE.md is up to date
Verify the structural claims: the project list and target framework, the
directory map, the gadget table and its count, the plugin table and its count,
the helper map, and the supported serializers/formatters list.
Confirm the gadget count in the "Full gadget table" heading matches the real
number of IGenerator implementations under ysonet/Generators/, and the
plugin count matches the real IPlugin implementations under
ysonet/Plugins/. Discovery is interface-based via
ysonet/Helpers/Discovery/GadgetRegistry.cs and PluginRegistry.cs.
If anything changed, the Last reviewed for vX.Y.Z line should be advanced
and the changed section corrected (only when the user approves the edit).
3. CLI and interactive CLI both support every gadget and plugin
The tool has two front ends and they must expose the same catalog:
Command-line: ysonet/Program.cs (Main), with listings via --list gadgets
and --list plugins, help in ysonet/Helpers/Cli/HelpText.cs, and shell
completion in ysonet/Helpers/Cli/CompletionCommand.cs.
Interactive: ysonet/Interactive/InteractiveMode.cs and the picker, wizard,
and module editor beside it.
Confirm every discovered gadget and plugin is reachable from BOTH front ends and
that neither hard-codes a list that has drifted from the registries. Build Debug
and run ysonet/bin/Debug/ysonet.exe --list gadgets and --list plugins, then
compare those lists to the registry contents and to the interactive catalog.
Flag anything present in one surface but missing from the other, and any
completion or help text that omits a real gadget, plugin, option, or value.
Private modules invert the expectation, so check both directions:
a private module must be ABSENT from the default --list gadgets /
--list plugins output. Present there is a finding;
the same module must be PRESENT in --list gadgets --prv /
--list plugins --prv. Absent there is also a finding, because the flag is
the only way an operator can see it.
Get the private set by diffing --prv against the default listing; do not read
the private source folders to build the list, and never name a private module in
the report. Tab completion is expected not to offer private names: the completion
script calls --list with no flag on purpose.
Static placement guard (the runtime cannot provide this): inspect the production
generator and plugin IMPLEMENTATIONS and report an error if a private
declaration - GadgetTags.Private in a Labels() return, or IsPrivate()
returning true - appears anywhere outside the generic private source folders
(ysonet/Generators/Private/, ysonet/Plugins/Private/). That catches a tracked
public module being marked private, without hardcoding the public module list
anywhere. Do NOT flag the tag declaration itself (IGenerator.cs), the policy
(Helpers/Core/PrivateModulePolicy.cs), the docs, the READMEs, or the test
doubles under a Helpers.TestingArena namespace merely for mentioning
GadgetTags.Private or IsPrivate.
4. Every gadget and plugin has all required parts
For each gadget, hold it to
.claude/skills/ysonet-dev-create-plan/references/making-a-gadget.md.
For each plugin, hold it to
.claude/skills/ysonet-dev-create-plan/references/making-a-plugin.md.
Check the required members are present and wired: the generator/plugin
contract, supported formatters, variants where relevant, labels, additional
info, help text, an architecture-table row, and metadata (facets) where the
facet API exists. For deep gadget-metadata work, defer to
$ysonet-audit-gadget-metadata rather than duplicating it here.
For every new runtime-gated gadget, confirm the plan and implementation name
at least one evidence-backed working target version. If current/latest did not
fire because of runtime compatibility, the highest verified working version
is the WithVersions ceiling and the latest tested non-working version is
documented. A single token must not become a range without evidence for the
contiguous span.
Variant numbers are ordered and contiguous. Every non-empty Variants() list
must contain exactly 1, 2, ..., N in that order: variant 1 is the default,
and there are no gaps, duplicates, zero/negative numbers, or out-of-order
entries. 1, 2, 4 is invalid because it skips 3. A retired number is still a
gap and must be reported, not treated as an exception. Compare the list with
the selector's help text, every formatter-specific branch in Generate(),
the interactive choices, and both docs so renumbering cannot leave one surface
stale.
Formatter display annotations state the real variant count. A (N) suffix in a
SupportedFormatters() token means "this formatter carries N variants"; a bare
name means one. It never counts combinations with an independent option such as
a root/container/carrier selector. Count a variant when that formatter supports
it in at least one valid option setting. Separately audit every option whose value
changes formatter compatibility using
references/formatter-option-matrices.md. Derive the per-formatter count from
Variants(), .Without(...), option guards, and Generate(), then compare it to:
the token in SupportedFormatters();
the row in docs/gadgets-and-plugins.md;
the formatter column of the gadget table in docs/ARCHITECTURE.md.
Report a missing or wrong suffix, a suffix on a single-variant formatter, an
undocumented option restriction, ambiguous help that makes option values look
like variant counts, and any supported/refused matrix boundary with no test.
Counts are per formatter; WindowsClaimsIdentityGenerator.cs is the differing-
count reference. The suffix is display-only, but a wrong count misleads users.
Hosted payloads sit in the right folder with the right tag. The two must agree,
and both must match what the code does. For every gadget, read what reaches
Serialize():
hands another generator's object to Serialize() (for example
TypeConfuseDelegateGenerator.GetXamlGadget(...) or a bare
TextFormattingRunPropertiesMarshal) => must live in
ysonet/Generators/HostedPayloads/ and carry GadgetTags.Hosted;
serializes a type it defines (its own *Marshal class or a real framework
type) => must live in ysonet/Generators/ and must NOT carry
GadgetTags.Hosted, even when it nests another gadget's payload inside.
Report either mismatch as a finding: a hosted gadget outside the folder or
without the tag, and a normal gadget wrongly tagged or filed. A Variants()
list or var/variant option is not evidence either way. Also flag any file in
HostedPayloads/ whose namespace is not ysonet.Generators, and any gadget
file missing from the ysonet.csproj<Compile> list. Contract:
ysonet/Generators/HostedPayloads/README.md.
Every gadget's payload is self-contained. Contract:
ysonet/Generators/README.md. Report as a finding:
a payload template, target type name, member name/order, or surrogate shape
for a specific gadget that lives outside that gadget's own file (a helper, a
shared "payload builder", or another gadget's file);
any class under ysonet/Helpers/ that names a gadget, a gadget's target type,
or a gadget's members. A helper may only hold mechanics that take those as
arguments (MessagePackTypelessTypeSwap, SharpSerializerTypeSwap,
SerializersHelper, the minifiers, the escapers);
a non-gadget class sitting in ysonet/Generators/ (everything there is an
IGenerator, apart from Base/ and the READMEs);
plumbing copied into a gadget that GenericGenerator already provides
(Serialize, or the hand written path in
Generators/Base/GenericGenerator.HandWritten.cs).
The one allowed cross-gadget dependency is reusing another gadget as the inner
payload via GenerateInner, declared with GadgetTags.Bridged/Hosted.
Every gadget and plugin is readable as research material. Same contract
(ysonet/Generators/README.md). Report as a finding:
a payload that is not visible in the source: a base64 blob or byte array
standing in for a document a human could read, a string assembled from
fragments or char codes, reflection used to avoid naming a type that can be
named, or one document split across methods;
an encoded or compressed WIRE payload with no comment saying what the bytes
are and no readable source it is built from (the --compressed assembly chain
and the base64 SerializedValue form are the compliant examples);
cryptic or misleading names where the real target/member name or a
technique-derived name belongs;
comments that restate the syntax while the WHY (the sink, why an order or
member set matters, the target-side condition, what silently breaks) is
missing;
missing or unverifiable credits in Finders()/Contributors()/
AdditionalInfo().
Do NOT report the Release binary's string encryption (ysonet/obfuscar.xml): it
is a deliberate antivirus measure on one shipped executable, documented in
docs/getting-started.md, and unrelated to source readability.
Note any gadget or plugin that is missing a part, or whose parts contradict
each other. Collect these for the closing question to the user (see "Finish").
5. Tests exist for everything, following the existing patterns
Tests live in ysonet.Tests/Tests.cs (a self-contained runner, two tiers:
NORMAL and FULL, gated by the --full arg or the YSONET_FULL_TESTS env var).
First read what kinds of tests already exist and follow the SAME path; do not
invent a new style. Existing coverage includes CLI listing tests
(CliListingBasics, CliListingPerModule), interactive wizard/menu tests,
option and variant tests (GadgetsDeclareVariants, VariantInputTypes), the
per-gadget generation matrix and runtime-effect matrix
(PayloadsFireIntoTestSinks with SampleInputForGadget), and the plugin
coverage guard (EverySafePluginGeneratesAPayload with argvByPlugin and
excluded, plus PluginFullMatrixGenerates).
Confirm the coverage norms from CLAUDE.md hold:
A new gadget/formatter/variant is covered by the generation matrix; if a new
gadget needs an input the runner does not sample, SampleInputForGadget was
extended.
GadgetsDeclareVariants enforces the catalogue-wide 1, 2, ..., N ordering
invariant, rather than checking only a few representative gadgets.
A new gadget's runtime EFFECT has a row in the execution matrix.
A new runtime-gated gadget has evidence for at least one working target
version. A failed current/latest row is followed by an older-version
reproduction, not used as the WithVersions ceiling.
A new plugin MODE is in the curated PluginFullMatrixGenerates table, and the
plugin is in argvByPlugin or excluded (the coverage guard fails the build
otherwise).
Flag any gadget, plugin, plugin mode, option, or new function that has no
matching test, and name where the missing test should go by analogy to the
closest existing one.
Nothing a test runs may open a real application, and a fired shell command comes
from the shared sink. Full contract: references/test-fire-safety.md. In short:
Naming calc.exe or notepad.exe is fine as GENERATION input (the catalogue's
own examples, bytes only compared or encoded). It is a finding the moment that
payload is deserialized, self-tested (-t, InputArgs.Test = true), or run by
a subprocess. Report the path from the literal to the execution call.
A command fire row takes its command from FireBackend.Create(...), passes
fire.Command with IsRawCmd = true, and waits on the target. A hand-written
cmd /c ... command, a private marker, or a copied wait loop is a finding.
A non-command sink (self-closing .cs, loopback listener, temp dir, OOB DNS)
keeps its own evidence; not using FireTarget there is not a finding.
The sink must be wired and staged, or rows drop to the weaker backend without
saying so. Confirm the run reports test-sink (check 9).
When you CREATE a test that writes any file (a fixture, input, payload, or a
marker the payload drops), follow references/test-file-locations.md: write to
the first writable directory in the chain workspace-root temp -> user temp ->
C:\Windows\Temp -> C:\temp, verify the file survived (antivirus can delete a
generated payload as a false positive) and fall through to the next directory if
it vanished, and never hardcode a machine path. Use the WriteTestArtifact /
ResolveTestArtifactDir helpers from that reference. This makes the file
location resilient; it never loosens a behavioral assertion.
6. Skills, agents, instructions, and prompts match the Anthropic standard
The standard is stored at
references/anthropic-skill-standards.md (fetched and distilled, so you do not
need to re-fetch it). Read it, then check every skill and agent file in the repo
against its compliance checklist: all .claude/skills/*/SKILL.md, any
.claude/skills/*/agents/*.yaml, and any agent or prompt files under
.claude/. Verify frontmatter limits, third-person "what and when" descriptions,
body size, one-level-deep references, consistent terminology, forward-slash
paths, the repo ysonet- naming pattern, and the CLAUDE.md plain-ASCII writing
style. Report each violation with the file and the rule it breaks. Only refresh
the stored standard if it has actually changed.
7. The shared memory is still true
.claude/memory/ is git-tracked and loaded into every session, so a wrong entry
misleads every later contributor and agent. Audit it the way check 1 audits the
docs: as claims about the code, not as facts.
memory.md is a complete index. Every file under .claude/memory/ has exactly
one row with a description and a last-updated date. Flag a file with no row, a
row pointing at a file that is gone, and a date older than the newest entry in
the file it names.
Entries follow date - what - why and nothing more, newest first within a
file, in the plain-ASCII writing style from CLAUDE.md.
Verify the CLAIMS. A named file, class, method, test, option, flag, or facet
value must still exist and still behave as written. Report an entry that names
something renamed, moved, or deleted, and an entry the current code
contradicts. Spot-check with a real Grep or Read; do not assert from memory.
Flag an entry that describes work as still outstanding when it has shipped: a
"still on the old X", "not yet wired", or "see dev-kitchen/todo/" clause
whose item is done, and any dev-kitchen/todo/ file it points at that no
longer exists. This is the most common form of drift, because the entry is
written before the follow-up work lands.
Flag a [[link]] that names no memory file, and duplicate entries that say the
same thing in two files (they should be merged).
No local, private, or sensitive data anywhere in it. The memory files are the
easiest place for this to slip in, because an entry is written from whatever
was on screen. Check 8 sweeps them along with every other tracked file.
Report every finding and STOP there. CLAUDE.md requires the user's
confirmation before an existing memory entry is changed or removed, so show the
current text and the proposed replacement and let them decide, even when the
entry is plainly stale.
8. Nothing ignored, private, or machine-specific leaked into tracked files
This repo is PUBLIC, and a contributor may keep private material (research
tooling, datasets, unpublished gadgets, working notes) in a separate private
repo linked in at ignored paths that look like ordinary folders. Read the
"Public and private content (the seam)" and "No local artifacts in commits"
sections of CLAUDE.md first; this check enforces both.
It covers EVERY tracked file, in every shape a name can hide: code, comments and
XML doc comments, string literals, help and completion text, tests and test data,
docs, the skill and agent files, .claude/memory/, .gitignore itself, project
and workflow files, and the commit messages on the current branch.
Derive the private names, never guess them:
Run the seam check script FIRST if there is one. When a private area is set up
it provides one, and .claude/memory/private/index.md names it. Read that
index if it exists. If the script reports a leak, that is an error finding and
the branch is not releasable.
Build the ignored set from git, so nothing has to be hardcoded here:
git status --ignored --short for what exists and is ignored right now, plus
the patterns in .gitignore and in the local, uncommitted .git/info/exclude.
Every folder, tool, dataset, and script name in that set is a name that must
not appear in tracked content.
Search the tracked files (git ls-files) for each of those names with Grep.
A hit is a finding even in a comment, a commented-out line, an example command,
a test fixture, or a memory entry.
Then check the rest of the seam:
.gitignore entries stay generic (local/, dev-kitchen/, **/private/). An
entry naming a private path, tool, or dataset PUBLISHES that name, and is a
finding on its own: the rule belongs in .git/info/exclude, which is local and
never committed.
Tracked text may describe a CAPABILITY in general terms ("if a code graph is
configured, use it") but never the artifact that provides it. Judge by whether
a reader could identify the private thing from the tracked text.
No machine-specific data: an absolute local path (C:\Users\..., C:\root\...,
/Users/, /mnt/c/, a home directory, a scratchpad or temp path), a user or
machine name, a key or token. The quick sweep from CLAUDE.md is
git grep -niE '[A-Z]:\\\\|/Users/|AppData|scratchpad' over tracked files;
everything it returns must be intended gadget or example content.
No temp or build output tracked: bin/, obj/, *.tmp, *.bak, *.user,
*.suo, *.log, editor swap files, .DS_Store, Thumbs.db,
*.FileListAbsolute.txt. Check with git ls-files, not by looking at the
working tree.
History counts, because a push sends the whole branch. Check the commits this
branch adds (git log <main>..HEAD --name-only for paths, and the messages
themselves) for the same leaks. A name scrubbed only in the current tree is
still in the branch and needs a history fix before that branch is pushed.
Reporting rule for this check, and it matters: describe a leak by its LOCATION
and KIND (ysonet.Tests/Tests.cs:120 names an ignored tooling folder), and do
not copy the private name into any tracked file, including
dev-kitchen/todo/ notes you would otherwise write. Naming it in your chat
report to the maintainer is fine; writing it into the repo is the leak itself.
Never resolve a finding by adding the name to .gitignore, and never
git add -f an ignored path. If a fix seems to need private content in a
tracked file, stop and ask.
9. Full tests run with zero errors
Run the FULL suite last, after the reads above. Set YSONET_FULL_TESTS=1 and
build Debug, or run the standalone ysonet/bin/Debug/ysonet.Tests.exe --full.
Redirect output to a file in the scratchpad and read it with the Read/Grep tools
rather than piping, so the safety classifier does not block the run (see
CLAUDE.md, "Running build/test/git commands without getting blocked").
Report the Passed/Failed summary AND the ENVIRONMENT VERDICT: line beside it,
plus the Environment-skipped count. They answer different questions: the
summary says what passed, the verdict says whether this machine could run
everything.
Report the Fire backend: header line too. test-sink (...) is expected;
legacy-cmd (...) means every command fire row used the weaker marker backend
for the reason in the brackets, so name that reason and do not call it equivalent
coverage. An application window appearing during the run is a check-5 finding.
Never call an environment-limited run complete coverage or release-ready.
Name the skipped checks and the capability each one needed.
On environment-suspect or mixed, report the capability evidence and stop:
that is not a defect to fix blind.
When the audit claims that every environment-dependent row really ran, verify
it with ysonet/bin/Debug/ysonet.Tests.exe --full --strict-env (add --oob
only if the maintainer wants the off-machine tier). Strict mode exits non-zero
on absent or unverified coverage; it does not run anything it skipped.
If anything fails, show the failing output and find the root cause. A failure is
a real defect to fix, not a test to weaken or skip. If a fix needs a design
decision, stop and ask.
Finish
Ask the user the gadget/plugin question. From check 4, list any gadget or
plugin that looks incomplete, and add your own suggestions (a missing
formatter it could support, a variant worth adding, a plugin mode, a metadata
gap). Use AskUserQuestion for concrete choices; keep options short and in
simple words. Do not implement these now unless the user asks.
Surface open items per CLAUDE.md: write each decision, follow-up, or
"worth doing later" fix as its own short markdown file in dev-kitchen/todo/
(with a README.md index), and call them out in your final message. Do not
bury them only in a committed doc or code comment.
If the user approved fixes, make them, re-run the affected check, and (only if
asked) commit once in the house style. Never push.
Report format
Lead with a one-line verdict per check (pass / drift / fail), then a findings
table:
Check
Severity
Location
Finding
Evidence
Resolution
1-9
error / warning / info
file:line
issue
source
reported / fixed / needs-decision
End with: the full-test Passed/Failed summary and its environment verdict, which surfaces were verified, any
unresolved uncertainty, and the questions that need the user. A clean run should
say which gadgets, plugins, docs, and surfaces were checked, not just "all good".
Final checks
Review-only unless the user approved changes.
All nine checks run; none silently skipped.
Every finding traceable to evidence from a real tool call.
Docs, ARCHITECTURE.md, both CLIs, and tests compared against the live code.
Hosted-payload folder and GadgetTags.Hosted tag agree with what each
gadget hands to Serialize() (check 4).
Every multi-variant gadget's (N) formatter annotation matches the real
per-formatter variant count, in code and in both docs (check 4).
Every independent option that changes formatter support has a verified
formatter x variant x option matrix, unambiguous help, and boundary tests.
Every non-empty Variants() list is exactly 1, 2, ..., N in order, and
GadgetsDeclareVariants enforces that invariant catalogue-wide (checks 4-5).
Every new runtime-gated gadget names a verified working target version,
and a latest-version failure does not overstate WithVersions (check 4).
Skills/agents checked against references/anthropic-skill-standards.md.
.claude/memory/ audited: index complete, entries verified against the
code, no stale "still outstanding" clause; no entry changed without the
user's approval (check 7).
Seam swept (check 8): seam check script run if present, ignored names
derived from git and searched across all tracked files including comments
and memory, .gitignore still generic, no local path or build output
tracked, branch commits and messages checked. No private name written into
the repo by the report itself.
No test executes a real application, every executed shell command comes
from FireBackend.Create(...), and the sink is wired and staged (check 5).
Full suite ran; Passed/Failed, the environment verdict, the
environment-skipped count, and the Fire backend: line reported honestly;
no test weakened; an environment-limited run was not called complete
coverage.
Gadget/plugin suggestion question asked; open items written to
dev-kitchen/todo/.
1---2name: ysonet-dev-consistency-check3description: Runs a whole-repo consistency audit of ysonet before a release or after a change. Checks that docs match the code, docs/ARCHITECTURE.md is current, both CLIs expose every gadget and plugin, each gadget and plugin has all required parts, tests exist for everything following the existing test patterns, no test opens a real application and every fired command goes through the test sink, all skills and agent files match the Anthropic skill standard, the git-tracked memory under .claude/memory/ is still true and indexed, no ignored, private, or machine-specific content leaked into tracked files, and the full test suite passes with zero errors. Use when the user asks to check consistency, audit the repo, verify docs and tests are in sync, check for private or local data leaking into the public repo, or confirm the tool is release-ready. Read-only until the user approves fixes.4---56# ysonet consistency check78Verify the whole repo hangs together: code, docs, both CLIs, gadget and plugin9completeness, tests, agent tooling, the shared memory, the public/private seam,10and a green full test run. Report first;11change only what the user approves. Never weaken a test to get a green tick (see12the "Test integrity policy" in `CLAUDE.md`).1314Take the role of a senior .NET developer and maintainer doing a release review.15Say so, then work the checks below in order.1617## Mode1819- Default is REVIEW: find and report drift with evidence, change nothing.20- Only make fixes the user approves. Clear, evidence-backed doc or comment fixes21 can be applied when the user says "fix" or "repair"; anything touching payload22 generation, a gadget, a plugin, or a test needs explicit sign-off first.23- When two readings are both plausible, ask instead of guessing.2425## Load the contract first2627Read `CLAUDE.md` and `docs/ARCHITECTURE.md` (at least its section headers and the28areas in scope). ARCHITECTURE.md is the code map; trust it as a guide but verify29its claims against the code, since it can lag. Note its `Last reviewed for30vX.Y.Z` line near the top.3132Read `.claude/memory/memory.md` and the files it indexes too. They are the shared33knowledge base, and they are also an audit target in check 7, so treat every34entry as a claim to verify rather than as fact.3536## Fast path: run the bundled scripts first3738Two deterministic PowerShell scripts live beside this skill. Run them ONCE at the39start to collect the mechanical facts in one compact report, instead of many40Grep/Read calls. They are read-only and advisory; you still confirm semantic41claims and run the full suite yourself. Both auto-detect the repo root.4243- Inventory and cross-reference (checks 1-5): run44 `powershell -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/inventory.ps1"`.45 It prints the authoritative gadget/plugin catalog (from the built exe's46 `--list`, or an APPROXIMATE static scan if there is no Debug build), the47 ARCHITECTURE.md declared counts and `Last reviewed` version vs `VERSION`,48 validates every built gadget's variant sequence, compares formatter-count49 suffixes with variant metadata, flags formatter-dependent option axes for50 semantic review, audits test fire safety (no fire scope executes a real51 application or a literal command; the52 sink is wired and staged), and reports catalog gaps across ARCHITECTURE.md,53 docs, and tests. Build Debug first so the catalog and metadata are exact.54- Skill/agent frontmatter and style (check 6): run55 `powershell -ExecutionPolicy Bypass -File "${CLAUDE_SKILL_DIR}/scripts/check-skills.ps1"`.56 It validates every `.claude/skills/*/SKILL.md` against the hard limits in57 `references/anthropic-skill-standards.md` and flags style issues.5859Treat every flag as a lead to verify, not a final verdict. A warning can be a60deliberate example (an anti-pattern shown on purpose); confirm before reporting61it. The scripts do not cover the interactive-CLI parity (check 3, part), the62semantic doc review (check 1), the memory audit (check 7), the public/private63seam (check 8), or the test run (check 9): do those yourself.6465## The nine checks6667Run all nine. Track them with TodoWrite so none is dropped. Start from the68script output above, then gather any missing evidence with real tool calls; do69not assert from memory.7071### 1. Docs match what is implemented7273- Compare every doc under `docs/` against the code it describes: `README.md`,74 `gadgets-and-plugins.md`, `getting-started.md`, `usage-and-examples.md`,75 `minification-savings.md`, `credits.md`, `references.md`,76 `dotnet-deserialization-research.md`, `dependency-security.md`.77- Run `python tools/references/refs.py verify` for the reference archive. It is78 offline and instant. It checks the archive against what was actually acquired,79 that every published file still names its source, and that neither curated80 reading list was modified by an archive run. A failure there is a real defect,81 not noise.82- Check that gadget names, plugin names, option flags, example commands, and83 counts in the docs still exist and still behave as written.84- Flag stale flags, renamed gadgets, dropped or added options, and example85 commands that would now fail.86- A PRIVATE module is expected to be absent from every public doc. A gadget with87 `GadgetTags.Private` in `Labels()`, or a plugin whose `IsPrivate()` returns88 true, must NOT appear in `docs/gadgets-and-plugins.md`, `docs/credits.md`, or89 any other tracked file, and its absence is never a finding. Never name one in90 the report either: say "a private module" and count it. In a clean clone there91 are none, which is an empty applicable set, not a skipped check.92- `docs/dependency-security.md` must cover every entry in `ysonet/packages.config`93 and every file under `ysonet/dlls/`, with the version in the doc matching the94 version actually referenced by `ysonet/ysonet.csproj`. Flag a package or DLL95 that was added, removed, or re-versioned without a matching row, and flag a row96 whose "shipped" claim disagrees with the `CopyToOutputDirectory` entries in the97 `.csproj`. Do not propose upgrading a pin the doc marks as gadget side.9899### 2. docs/ARCHITECTURE.md is up to date100101- Verify the structural claims: the project list and target framework, the102 directory map, the gadget table and its count, the plugin table and its count,103 the helper map, and the supported serializers/formatters list.104- Confirm the gadget count in the "Full gadget table" heading matches the real105 number of `IGenerator` implementations under `ysonet/Generators/`, and the106 plugin count matches the real `IPlugin` implementations under107 `ysonet/Plugins/`. Discovery is interface-based via108 `ysonet/Helpers/Discovery/GadgetRegistry.cs` and `PluginRegistry.cs`.109- If anything changed, the `Last reviewed for vX.Y.Z` line should be advanced110 and the changed section corrected (only when the user approves the edit).111112### 3. CLI and interactive CLI both support every gadget and plugin113114The tool has two front ends and they must expose the same catalog:115116- Command-line: `ysonet/Program.cs` (`Main`), with listings via `--list gadgets`117 and `--list plugins`, help in `ysonet/Helpers/Cli/HelpText.cs`, and shell118 completion in `ysonet/Helpers/Cli/CompletionCommand.cs`.119- Interactive: `ysonet/Interactive/InteractiveMode.cs` and the picker, wizard,120 and module editor beside it.121122Confirm every discovered gadget and plugin is reachable from BOTH front ends and123that neither hard-codes a list that has drifted from the registries. Build Debug124and run `ysonet/bin/Debug/ysonet.exe --list gadgets` and `--list plugins`, then125compare those lists to the registry contents and to the interactive catalog.126Flag anything present in one surface but missing from the other, and any127completion or help text that omits a real gadget, plugin, option, or value.128129Private modules invert the expectation, so check both directions:130131- a private module must be ABSENT from the default `--list gadgets` /132 `--list plugins` output. Present there is a finding;133- the same module must be PRESENT in `--list gadgets --prv` /134 `--list plugins --prv`. Absent there is also a finding, because the flag is135 the only way an operator can see it.136137Get the private set by diffing `--prv` against the default listing; do not read138the private source folders to build the list, and never name a private module in139the report. Tab completion is expected not to offer private names: the completion140script calls `--list` with no flag on purpose.141142Static placement guard (the runtime cannot provide this): inspect the production143generator and plugin IMPLEMENTATIONS and report an error if a private144declaration - `GadgetTags.Private` in a `Labels()` return, or `IsPrivate()`145returning true - appears anywhere outside the generic private source folders146(`ysonet/Generators/Private/`, `ysonet/Plugins/Private/`). That catches a tracked147public module being marked private, without hardcoding the public module list148anywhere. Do NOT flag the tag declaration itself (`IGenerator.cs`), the policy149(`Helpers/Core/PrivateModulePolicy.cs`), the docs, the READMEs, or the test150doubles under a `Helpers.TestingArena` namespace merely for mentioning151`GadgetTags.Private` or `IsPrivate`.152153### 4. Every gadget and plugin has all required parts154155- For each gadget, hold it to156 `.claude/skills/ysonet-dev-create-plan/references/making-a-gadget.md`.157- For each plugin, hold it to158 `.claude/skills/ysonet-dev-create-plan/references/making-a-plugin.md`.159- Check the required members are present and wired: the generator/plugin160 contract, supported formatters, variants where relevant, labels, additional161 info, help text, an architecture-table row, and metadata (facets) where the162 facet API exists. For deep gadget-metadata work, defer to163 `$ysonet-audit-gadget-metadata` rather than duplicating it here.164- For every new runtime-gated gadget, confirm the plan and implementation name165 at least one evidence-backed working target version. If current/latest did not166 fire because of runtime compatibility, the highest verified working version167 is the `WithVersions` ceiling and the latest tested non-working version is168 documented. A single token must not become a range without evidence for the169 contiguous span.170- Variant numbers are ordered and contiguous. Every non-empty `Variants()` list171 must contain exactly `1, 2, ..., N` in that order: variant 1 is the default,172 and there are no gaps, duplicates, zero/negative numbers, or out-of-order173 entries. `1, 2, 4` is invalid because it skips 3. A retired number is still a174 gap and must be reported, not treated as an exception. Compare the list with175 the selector's help text, every formatter-specific branch in `Generate()`,176 the interactive choices, and both docs so renumbering cannot leave one surface177 stale.178- Formatter display annotations state the real variant count. A `(N)` suffix in a179 `SupportedFormatters()` token means "this formatter carries N variants"; a bare180 name means one. It never counts combinations with an independent option such as181 a root/container/carrier selector. Count a variant when that formatter supports182 it in at least one valid option setting. Separately audit every option whose value183 changes formatter compatibility using184 `references/formatter-option-matrices.md`. Derive the per-formatter count from185 `Variants()`, `.Without(...)`, option guards, and `Generate()`, then compare it to:186 - the token in `SupportedFormatters()`;187 - the row in `docs/gadgets-and-plugins.md`;188 - the formatter column of the gadget table in `docs/ARCHITECTURE.md`.189 Report a missing or wrong suffix, a suffix on a single-variant formatter, an190 undocumented option restriction, ambiguous help that makes option values look191 like variant counts, and any supported/refused matrix boundary with no test.192 Counts are per formatter; `WindowsClaimsIdentityGenerator.cs` is the differing-193 count reference. The suffix is display-only, but a wrong count misleads users.194- Hosted payloads sit in the right folder with the right tag. The two must agree,195 and both must match what the code does. For every gadget, read what reaches196 `Serialize()`:197 - hands another generator's object to `Serialize()` (for example198 `TypeConfuseDelegateGenerator.GetXamlGadget(...)` or a bare199 `TextFormattingRunPropertiesMarshal`) => must live in200 `ysonet/Generators/HostedPayloads/` and carry `GadgetTags.Hosted`;201 - serializes a type it defines (its own `*Marshal` class or a real framework202 type) => must live in `ysonet/Generators/` and must NOT carry203 `GadgetTags.Hosted`, even when it nests another gadget's payload inside.204 Report either mismatch as a finding: a hosted gadget outside the folder or205 without the tag, and a normal gadget wrongly tagged or filed. A `Variants()`206 list or `var/variant` option is not evidence either way. Also flag any file in207 `HostedPayloads/` whose namespace is not `ysonet.Generators`, and any gadget208 file missing from the `ysonet.csproj` `<Compile>` list. Contract:209 `ysonet/Generators/HostedPayloads/README.md`.210- Every gadget's payload is self-contained. Contract:211 `ysonet/Generators/README.md`. Report as a finding:212 - a payload template, target type name, member name/order, or surrogate shape213 for a specific gadget that lives outside that gadget's own file (a helper, a214 shared "payload builder", or another gadget's file);215 - any class under `ysonet/Helpers/` that names a gadget, a gadget's target type,216 or a gadget's members. A helper may only hold mechanics that take those as217 arguments (`MessagePackTypelessTypeSwap`, `SharpSerializerTypeSwap`,218 `SerializersHelper`, the minifiers, the escapers);219 - a non-gadget class sitting in `ysonet/Generators/` (everything there is an220 `IGenerator`, apart from `Base/` and the READMEs);221 - plumbing copied into a gadget that `GenericGenerator` already provides222 (`Serialize`, or the hand written path in223 `Generators/Base/GenericGenerator.HandWritten.cs`).224 The one allowed cross-gadget dependency is reusing another gadget as the inner225 payload via `GenerateInner`, declared with `GadgetTags.Bridged`/`Hosted`.226- Every gadget and plugin is readable as research material. Same contract227 (`ysonet/Generators/README.md`). Report as a finding:228 - a payload that is not visible in the source: a base64 blob or byte array229 standing in for a document a human could read, a string assembled from230 fragments or `char` codes, reflection used to avoid naming a type that can be231 named, or one document split across methods;232 - an encoded or compressed WIRE payload with no comment saying what the bytes233 are and no readable source it is built from (the `--compressed` assembly chain234 and the base64 `SerializedValue` form are the compliant examples);235 - cryptic or misleading names where the real target/member name or a236 technique-derived name belongs;237 - comments that restate the syntax while the WHY (the sink, why an order or238 member set matters, the target-side condition, what silently breaks) is239 missing;240 - missing or unverifiable credits in `Finders()`/`Contributors()`/241 `AdditionalInfo()`.242 Do NOT report the Release binary's string encryption (`ysonet/obfuscar.xml`): it243 is a deliberate antivirus measure on one shipped executable, documented in244 `docs/getting-started.md`, and unrelated to source readability.245- Note any gadget or plugin that is missing a part, or whose parts contradict246 each other. Collect these for the closing question to the user (see "Finish").247248### 5. Tests exist for everything, following the existing patterns249250Tests live in `ysonet.Tests/Tests.cs` (a self-contained runner, two tiers:251NORMAL and FULL, gated by the `--full` arg or the `YSONET_FULL_TESTS` env var).252First read what kinds of tests already exist and follow the SAME path; do not253invent a new style. Existing coverage includes CLI listing tests254(`CliListingBasics`, `CliListingPerModule`), interactive wizard/menu tests,255option and variant tests (`GadgetsDeclareVariants`, `VariantInputTypes`), the256per-gadget generation matrix and runtime-effect matrix257(`PayloadsFireIntoTestSinks` with `SampleInputForGadget`), and the plugin258coverage guard (`EverySafePluginGeneratesAPayload` with `argvByPlugin` and259`excluded`, plus `PluginFullMatrixGenerates`).260261Confirm the coverage norms from `CLAUDE.md` hold:262- A new gadget/formatter/variant is covered by the generation matrix; if a new263 gadget needs an input the runner does not sample, `SampleInputForGadget` was264 extended.265- `GadgetsDeclareVariants` enforces the catalogue-wide `1, 2, ..., N` ordering266 invariant, rather than checking only a few representative gadgets.267- A new gadget's runtime EFFECT has a row in the execution matrix.268- A new runtime-gated gadget has evidence for at least one working target269 version. A failed current/latest row is followed by an older-version270 reproduction, not used as the `WithVersions` ceiling.271- A new plugin MODE is in the curated `PluginFullMatrixGenerates` table, and the272 plugin is in `argvByPlugin` or `excluded` (the coverage guard fails the build273 otherwise).274275Flag any gadget, plugin, plugin mode, option, or new function that has no276matching test, and name where the missing test should go by analogy to the277closest existing one.278279Nothing a test runs may open a real application, and a fired shell command comes280from the shared sink. Full contract: `references/test-fire-safety.md`. In short:281282- Naming `calc.exe` or `notepad.exe` is fine as GENERATION input (the catalogue's283 own examples, bytes only compared or encoded). It is a finding the moment that284 payload is deserialized, self-tested (`-t`, `InputArgs.Test = true`), or run by285 a subprocess. Report the path from the literal to the execution call.286- A command fire row takes its command from `FireBackend.Create(...)`, passes287 `fire.Command` with `IsRawCmd = true`, and waits on the target. A hand-written288 `cmd /c ...` command, a private marker, or a copied wait loop is a finding.289- A non-command sink (self-closing `.cs`, loopback listener, temp dir, OOB DNS)290 keeps its own evidence; not using `FireTarget` there is not a finding.291- The sink must be wired and staged, or rows drop to the weaker backend without292 saying so. Confirm the run reports `test-sink` (check 9).293294When you CREATE a test that writes any file (a fixture, input, payload, or a295marker the payload drops), follow `references/test-file-locations.md`: write to296the first writable directory in the chain workspace-root `temp` -> user temp ->297`C:\Windows\Temp` -> `C:\temp`, verify the file survived (antivirus can delete a298generated payload as a false positive) and fall through to the next directory if299it vanished, and never hardcode a machine path. Use the `WriteTestArtifact` /300`ResolveTestArtifactDir` helpers from that reference. This makes the file301location resilient; it never loosens a behavioral assertion.302303### 6. Skills, agents, instructions, and prompts match the Anthropic standard304305The standard is stored at306`references/anthropic-skill-standards.md` (fetched and distilled, so you do not307need to re-fetch it). Read it, then check every skill and agent file in the repo308against its compliance checklist: all `.claude/skills/*/SKILL.md`, any309`.claude/skills/*/agents/*.yaml`, and any agent or prompt files under310`.claude/`. Verify frontmatter limits, third-person "what and when" descriptions,311body size, one-level-deep references, consistent terminology, forward-slash312paths, the repo `ysonet-` naming pattern, and the `CLAUDE.md` plain-ASCII writing313style. Report each violation with the file and the rule it breaks. Only refresh314the stored standard if it has actually changed.315316### 7. The shared memory is still true317318`.claude/memory/` is git-tracked and loaded into every session, so a wrong entry319misleads every later contributor and agent. Audit it the way check 1 audits the320docs: as claims about the code, not as facts.321322- `memory.md` is a complete index. Every file under `.claude/memory/` has exactly323 one row with a description and a last-updated date. Flag a file with no row, a324 row pointing at a file that is gone, and a date older than the newest entry in325 the file it names.326- Entries follow `date - what - why` and nothing more, newest first within a327 file, in the plain-ASCII writing style from `CLAUDE.md`.328- Verify the CLAIMS. A named file, class, method, test, option, flag, or facet329 value must still exist and still behave as written. Report an entry that names330 something renamed, moved, or deleted, and an entry the current code331 contradicts. Spot-check with a real Grep or Read; do not assert from memory.332- Flag an entry that describes work as still outstanding when it has shipped: a333 "still on the old X", "not yet wired", or "see `dev-kitchen/todo/`" clause334 whose item is done, and any `dev-kitchen/todo/` file it points at that no335 longer exists. This is the most common form of drift, because the entry is336 written before the follow-up work lands.337- Flag a `[[link]]` that names no memory file, and duplicate entries that say the338 same thing in two files (they should be merged).339- No local, private, or sensitive data anywhere in it. The memory files are the340 easiest place for this to slip in, because an entry is written from whatever341 was on screen. Check 8 sweeps them along with every other tracked file.342343Report every finding and STOP there. `CLAUDE.md` requires the user's344confirmation before an existing memory entry is changed or removed, so show the345current text and the proposed replacement and let them decide, even when the346entry is plainly stale.347348### 8. Nothing ignored, private, or machine-specific leaked into tracked files349350This repo is PUBLIC, and a contributor may keep private material (research351tooling, datasets, unpublished gadgets, working notes) in a separate private352repo linked in at ignored paths that look like ordinary folders. Read the353"Public and private content (the seam)" and "No local artifacts in commits"354sections of `CLAUDE.md` first; this check enforces both.355356It covers EVERY tracked file, in every shape a name can hide: code, comments and357XML doc comments, string literals, help and completion text, tests and test data,358docs, the skill and agent files, `.claude/memory/`, `.gitignore` itself, project359and workflow files, and the commit messages on the current branch.360361Derive the private names, never guess them:362363- Run the seam check script FIRST if there is one. When a private area is set up364 it provides one, and `.claude/memory/private/index.md` names it. Read that365 index if it exists. If the script reports a leak, that is an error finding and366 the branch is not releasable.367- Build the ignored set from git, so nothing has to be hardcoded here:368 `git status --ignored --short` for what exists and is ignored right now, plus369 the patterns in `.gitignore` and in the local, uncommitted `.git/info/exclude`.370 Every folder, tool, dataset, and script name in that set is a name that must371 not appear in tracked content.372- Search the tracked files (`git ls-files`) for each of those names with Grep.373 A hit is a finding even in a comment, a commented-out line, an example command,374 a test fixture, or a memory entry.375376Then check the rest of the seam:377378- `.gitignore` entries stay generic (`local/`, `dev-kitchen/`, `**/private/`). An379 entry naming a private path, tool, or dataset PUBLISHES that name, and is a380 finding on its own: the rule belongs in `.git/info/exclude`, which is local and381 never committed.382- Tracked text may describe a CAPABILITY in general terms ("if a code graph is383 configured, use it") but never the artifact that provides it. Judge by whether384 a reader could identify the private thing from the tracked text.385- No machine-specific data: an absolute local path (`C:\Users\...`, `C:\root\...`,386 `/Users/`, `/mnt/c/`, a home directory, a scratchpad or temp path), a user or387 machine name, a key or token. The quick sweep from `CLAUDE.md` is388 `git grep -niE '[A-Z]:\\\\|/Users/|AppData|scratchpad'` over tracked files;389 everything it returns must be intended gadget or example content.390- No temp or build output tracked: `bin/`, `obj/`, `*.tmp`, `*.bak`, `*.user`,391 `*.suo`, `*.log`, editor swap files, `.DS_Store`, `Thumbs.db`,392 `*.FileListAbsolute.txt`. Check with `git ls-files`, not by looking at the393 working tree.394- History counts, because a push sends the whole branch. Check the commits this395 branch adds (`git log <main>..HEAD --name-only` for paths, and the messages396 themselves) for the same leaks. A name scrubbed only in the current tree is397 still in the branch and needs a history fix before that branch is pushed.398399Reporting rule for this check, and it matters: describe a leak by its LOCATION400and KIND (`ysonet.Tests/Tests.cs:120 names an ignored tooling folder`), and do401not copy the private name into any tracked file, including402`dev-kitchen/todo/` notes you would otherwise write. Naming it in your chat403report to the maintainer is fine; writing it into the repo is the leak itself.404Never resolve a finding by adding the name to `.gitignore`, and never405`git add -f` an ignored path. If a fix seems to need private content in a406tracked file, stop and ask.407408### 9. Full tests run with zero errors409410Run the FULL suite last, after the reads above. Set `YSONET_FULL_TESTS=1` and411build Debug, or run the standalone `ysonet/bin/Debug/ysonet.Tests.exe --full`.412Redirect output to a file in the scratchpad and read it with the Read/Grep tools413rather than piping, so the safety classifier does not block the run (see414`CLAUDE.md`, "Running build/test/git commands without getting blocked").415416Report the Passed/Failed summary AND the `ENVIRONMENT VERDICT:` line beside it,417plus the `Environment-skipped` count. They answer different questions: the418summary says what passed, the verdict says whether this machine could run419everything.420421Report the `Fire backend:` header line too. `test-sink (...)` is expected;422`legacy-cmd (...)` means every command fire row used the weaker marker backend423for the reason in the brackets, so name that reason and do not call it equivalent424coverage. An application window appearing during the run is a check-5 finding.425426- Never call an `environment-limited` run complete coverage or release-ready.427 Name the skipped checks and the capability each one needed.428- On `environment-suspect` or `mixed`, report the capability evidence and stop:429 that is not a defect to fix blind.430- When the audit claims that every environment-dependent row really ran, verify431 it with `ysonet/bin/Debug/ysonet.Tests.exe --full --strict-env` (add `--oob`432 only if the maintainer wants the off-machine tier). Strict mode exits non-zero433 on absent or unverified coverage; it does not run anything it skipped.434435If anything fails, show the failing output and find the root cause. A failure is436a real defect to fix, not a test to weaken or skip. If a fix needs a design437decision, stop and ask.438439## Finish4404411. Ask the user the gadget/plugin question. From check 4, list any gadget or442 plugin that looks incomplete, and add your own suggestions (a missing443 formatter it could support, a variant worth adding, a plugin mode, a metadata444 gap). Use AskUserQuestion for concrete choices; keep options short and in445 simple words. Do not implement these now unless the user asks.4462. Surface open items per `CLAUDE.md`: write each decision, follow-up, or447 "worth doing later" fix as its own short markdown file in `dev-kitchen/todo/`448 (with a `README.md` index), and call them out in your final message. Do not449 bury them only in a committed doc or code comment.4503. If the user approved fixes, make them, re-run the affected check, and (only if451 asked) commit once in the house style. Never push.452453## Report format454455Lead with a one-line verdict per check (pass / drift / fail), then a findings456table:457458| Check | Severity | Location | Finding | Evidence | Resolution |459|---|---|---|---|---|---|460| 1-9 | error / warning / info | file:line | issue | source | reported / fixed / needs-decision |461462End with: the full-test Passed/Failed summary and its environment verdict, which surfaces were verified, any463unresolved uncertainty, and the questions that need the user. A clean run should464say which gadgets, plugins, docs, and surfaces were checked, not just "all good".465466## Final checks467468- [ ] Review-only unless the user approved changes.469- [ ] All nine checks run; none silently skipped.470- [ ] Every finding traceable to evidence from a real tool call.471- [ ] Docs, ARCHITECTURE.md, both CLIs, and tests compared against the live code.472- [ ] Hosted-payload folder and `GadgetTags.Hosted` tag agree with what each473 gadget hands to `Serialize()` (check 4).474- [ ] Every multi-variant gadget's `(N)` formatter annotation matches the real475 per-formatter variant count, in code and in both docs (check 4).476- [ ] Every independent option that changes formatter support has a verified477 formatter x variant x option matrix, unambiguous help, and boundary tests.478- [ ] Every non-empty `Variants()` list is exactly `1, 2, ..., N` in order, and479 `GadgetsDeclareVariants` enforces that invariant catalogue-wide (checks 4-5).480- [ ] Every new runtime-gated gadget names a verified working target version,481 and a latest-version failure does not overstate `WithVersions` (check 4).482- [ ] Skills/agents checked against `references/anthropic-skill-standards.md`.483- [ ] `.claude/memory/` audited: index complete, entries verified against the484 code, no stale "still outstanding" clause; no entry changed without the485 user's approval (check 7).486- [ ] Seam swept (check 8): seam check script run if present, ignored names487 derived from git and searched across all tracked files including comments488 and memory, `.gitignore` still generic, no local path or build output489 tracked, branch commits and messages checked. No private name written into490 the repo by the report itself.491- [ ] No test executes a real application, every executed shell command comes492 from `FireBackend.Create(...)`, and the sink is wired and staged (check 5).493- [ ] Full suite ran; Passed/Failed, the environment verdict, the494 environment-skipped count, and the `Fire backend:` line reported honestly;495 no test weakened; an environment-limited run was not called complete496 coverage.497- [ ] Gadget/plugin suggestion question asked; open items written to498 `dev-kitchen/todo/`.
Run npx skillmds@latest add irsdl/ysonet-dev-consistency-check in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Runs a whole-repo consistency audit of ysonet before a release or after a change. Checks that docs match the code, docs/ARCHITECTURE.md is current, both CLIs expose every gadget and plugin, each gadget and plugin has all required parts, tests exist for everything following the existing test patterns, no test opens a real application and every fired command goes through the test sink, all skills and agent files match the Anthropic skill standard, the git-tracked memory under .claude/memory/ is still true and indexed, no ignored, private, or machine-specific content leaked into tracked files, and the full test suite passes with zero errors. Use when the user asks to check consistency, audit the repo, verify docs and tests are in sync, check for private or local data leaking into the public repo, or confirm the tool is release-ready. Read-only until the user approves fixes. It is listed under AI & ML on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
irsdl (@irsdl) published this skill. Their other Agent Skills are listed on their SkillMD profile.