Auto-annotate existing tests and source code with [INV-*] / @spec tags by reading all spec gaps, understanding each invariant, and matching them to existing test assertions. Optionally creates missing tests too. Drives FCI from 0% toward 100%.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Auto-annotate existing tests and source code with [INV-*] / @spec tags by reading all spec gaps, understanding each invariant, and matching them to existing test assertions. Optionally creates missing tests too. Drives FCI from 0% toward 100%.
argument-hint
<doc-name> [--with-tests] (doc name required; --with-tests to also create missing tests)
Map Invariants
Automatically match uncovered invariants to existing tests and source code, then annotate them with [INV-*] tags. Unlike /verify-invariants (which writes new tests from scratch), this skill starts by mapping what already exists.
Use when: A module has a spec (design doc + PRD) with many invariants and an existing test suite that already covers most behaviors — you just need to connect the dots.
Options
Flag
Effect
(no flag)
Map + annotate existing tests only. MISSING invariants are reported as skeletons but not implemented.
--with-tests
After mapping, also create full integration tests for every MISSING invariant so FCI reaches 100%.
When --with-tests is NOT provided, after the report in Step 7 the agent MUST ask:
"There are Z missing invariants that need new tests. Would you like me to create them now?"
If the user says yes, proceed as if --with-tests was given (continue to Step 8).
How tx spec Discovery Works
tx spec discover scans files in two passes:
Test files (matched by test_patterns in .tx/config.toml) — scanned for both [INV-*] bracket tags in test names AND // @spec INV-* comments
Source files (all programming languages) — scanned ONLY for // @spec INV-* comments (structural annotations)
This means @spec comments work in ANY file (test or source), but [INV-*] bracket tags are only picked up from test files.
Annotation Formats
Format
Where It Works
Example
[INV-TAG-001] in test name
Test files only
it('creates tag [INV-TAG-001]', ...)
// @spec INV-TAG-001 comment
Any file (test or source)
// @spec INV-TAG-001 above a schema definition
-- @spec INV-TAG-001 SQL comment
.sql files
-- @spec INV-TAG-001 in pgTAP test
# @spec INV-TAG-001 hash comment
.py, .rb, etc.
# @spec INV-TAG-001 above a test
Critical: IDs Are Case-Sensitive
INV-TAG-001 and inv-tag-001 are NOT the same. Always use UPPERCASE as shown in the design doc's invariants: YAML block.
Critical: Config Matters
The test_patterns in .tx/config.toml control which files are scanned as test files. The defaults include:
test_patterns = [
"**/*.test.{ts,js,tsx,jsx}",
"**/*.integration.test.{ts,js,tsx,jsx}",
"**/*.spec.{ts,js,tsx,jsx}",
"**/*.pgtap.sql",
# ... and more for Go, Python, Rust, Java, Ruby, C/C++
]
If your test file isn't being found, check that its pattern matches one of these globs.
Workflow
START
│
▼
Step 1: LOAD ALL GAPS
│
▼
Step 2: READ THE TEST FILES
│
▼
Step 3: MATCH INVARIANTS TO CODE
│
▼
Step 4: ANNOTATE
│
▼
Step 5: DISCOVER + VALIDATE
│
▼
Step 6: RUN TESTS + RECORD
│
▼
Step 7: REPORT
│
├─ No MISSING invariants? → DONE
│
├─ --with-tests flag? → Step 8
│
└─ No flag? → Ask user → Yes? → Step 8
│ No? → DONE
▼
Step 8: CREATE MISSING TESTS (optional)
│
▼
Step 9: RE-DISCOVER + RE-RUN + FINAL REPORT
│
▼
DONE
Step 1 — Load All Gaps (Show the Full Picture)
Get every uncovered invariant and understand what each one means.
# Get all uncovered invariant IDs
tx spec gaps --doc $ARGUMENTS# Get current coverage baseline
tx spec fci --doc $ARGUMENTS# Read the full spec to understand every invariant
tx doc show $ARGUMENTS --md
For each gap, extract from the spec:
Field
What to capture
Example
id
The invariant ID (case-sensitive, UPPERCASE)
INV-AUTH-001 or INV-REQ-AUTH-001
statement
What must be true — read this carefully
"Sign-up creates a verified user and returns a session token"
Which REQ-* it maps to (for INV-REQ-* derived invariants)
REQ-AUTH-001
Print a rich summary table showing ALL gaps with their IDs, statements, and severities before proceeding. The agent must understand what each invariant means before matching.
If FCI is already 100%, report success and stop.
Handling Both Invariant Types
Design docs produce explicit invariants: INV-AUTH-001, INV-AUTH-002, etc.
PRDs produce derived invariants from EARS requirements: INV-REQ-AUTH-001, INV-REQ-AUTH-002, etc.
Both types appear in tx spec gaps. Every invariant gets a marker — do not skip derived invariants.
Step 2 — Read the Test Files
Build a complete map of what every test actually verifies.
Find all relevant test files
# Start with files referenced in verified_by hints from Step 1# Then glob for additional test files in the module
Search for test files matching patterns like:
**/*.test.ts, **/*.integration.test.ts
**/*.spec.ts, **/*.pgtap.sql
Any files referenced in verified_by hints
Read and analyze each test file
For each test file:
Read the entire file — not just test names
Extract all it() / test() blocks with their line numbers
Read each test body to understand what it actually asserts:
What endpoint/function does it call?
What status code / return value does it expect?
What response body does it check?
What side effects does it verify (DB state, events, tokens)?
Build a map: { testName → [behaviors it verifies] }
Also read source files for structural invariants
Some invariants are enforced by code structure, not tests. Read:
Keyword overlap between invariant statement and test name
Medium
Invariant: "rejects sign-in with wrong password" ↔ Test: rejects sign-in with invalid credentials
Test body assertions
High
Test calls POST /auth/sign-in with bad password, expects 401
Source code structure
For structural only
Schema has uniqueIndex('users_email_unique')
Classification
Classify each invariant into exactly one category:
Category
Meaning
Action
TESTABLE-MATCHED
An existing test already covers this behavior
Append [INV-*] tag to test name
STRUCTURAL-MATCHED
Code structure enforces this (schema, lint, type)
Add // @spec INV-* comment above enforcing code
MISSING
No existing test or code covers this
Report as gap with test skeleton
Rules for matching
Read the test body, not just the name. A test named "complete auth flow" might cover 5+ invariants. You can only tell by reading its assertions.
One test can match multiple invariants. A single test can get [INV-AUTH-005] [INV-REQ-AUTH-013] if it verifies both behaviors.
Prefer TESTABLE-MATCHED over STRUCTURAL-MATCHED. Use structural only when no test exercises the behavior and the enforcement is genuinely structural (DB constraint, type system, lint rule).
Be precise about matching. Don't force-match an invariant to a vaguely related test. If the test doesn't actually assert the specific behavior, classify as MISSING.
Step 4 — Annotate
For TESTABLE-MATCHED: Edit test names
Append [INV-*] tag(s) to the it() description string:
// Beforeit('rejects sign-in with invalid credentials', async () => {
// After — single invariantit('rejects sign-in with invalid credentials [INV-AUTH-011]', async () => {
// After — multiple invariants covered by one testit('rejects sign-in with invalid credentials [INV-AUTH-011] [INV-REQ-AUTH-022]', async () => {
Critical formatting rules:
Tag goes INSIDE the string, before the closing quote
Space before the opening [
Tags are UPPERCASE and match the spec exactly (case-sensitive)
Multiple tags separated by spaces: [INV-A] [INV-B]
For STRUCTURAL-MATCHED: Add @spec comments
Place // @spec INV-* comment directly above the enforcing code:
Run each annotated test file. The batch command matches test results to discovered spec links automatically.
For structural annotations (manual recording)
# Get the exact test ID
tx spec tests <INV-ID>
# Output: packages/infra/db/src/schema.ts::spec@line-264 [comment]# Record as passed after confirming the code enforces the invariant
tx spec run "<file>::spec@line-N" --passed
For pgTAP annotations
pnpm test:db:pgtap
tx spec run "<pgtap-file>::<test>" --passed