一键导入
test-analyzer
analyzes test files and generates slice.json specifications for drift detection
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
analyzes test files and generates slice.json specifications for drift detection
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
builds an automation slice from an event model
builds a state-view slice from an event model
Generate a sample configuration for slices
builds a state-change slice from an event model
Step-by-step guide for getting started with event-driven development
| name | test-analyzer |
| description | analyzes test files and generates slice.json specifications for drift detection |
Analyzes test files (*.test.ts) to generate code-slice.json specification files. These capture behavioral contracts in given/when/then form, enabling drift detection between tests and slice.json design documentation.
CRITICAL: This skill NEVER touches existing slice.json files. It only creates/deletes code-slice.json files.
code-slice.json files matching the format of slice.json in .slices/ directorycode-slice.json (what tests say) with slice.json (design documentation)slice.json files - only work with code-slice.jsonActivateShift.test.ts or OnlineReservationStatus.test.ts)DeciderSpecification.for() for state-change slicesPostgreSQLProjectionSpec.for() for state-view slicesFile: .slices/<Context>/<folder>/code-slice.json (same directory as slice.json)
Contains:
{
"id": "<slice-id-from-slice.json>",
"title": "<slice-title-from-slice.json>",
"specifications": [...]
}
id and title fields copied from the corresponding slice.json fileInclude ALL test cases that are:
specifications array of existing slice.jsonIMPORTANT: Even if a command/event is defined in slice.json's commands/events arrays, if the test specification is NOT in the specifications array, it MUST be included in code-slice.json
Each specification includes:
vertical: falseid: unique generated IDsliceName: slice titletype: COMMAND, EVENT, READMODEL or SPEC_ERROR'title: spec description from testgiven: array of event objects (preconditions)
when: command object OR empty array
[] (events are in given for projections)then: array of event/error/readmodel objects
comments: empty arraylinkedId: MUST be the same as the specification's id field (self-reference)Uses DeciderSpecification.for() with decide/evolve pattern.
const given = DeciderSpecification.for({
decide,
evolve,
initialState: ...
});
it('spec: description', () => {
given([...events])
.when(command)
.then([...events])
});
Uses PostgreSQLProjectionSpec.for() for projections/read models.
given = PostgreSQLProjectionSpec.for({
projection: SomeProjection,
connectionString,
});
it('spec: description', () => {
await given([...events]) // Events are in given() for projections
.when([]) // when() is always empty for projections
.then(assertReadModel);
});
IMPORTANT for STATE_VIEW:
given array (the events to project)when is always empty array (no command in projections)then contains readmodel assertionsDeciderSpecification.for() → STATE_CHANGEPostgreSQLProjectionSpec.for() → STATE_VIEWFor each it('spec: ...', ...) test:
slice.json specifications arraywhen() calls with fields and typesgiven() and then() calls with fields and typesgiven() calls (events to be projected)when() is always empty for STATE_VIEW slicesthen()slice.json specifications arraySee specification-format.md for complete format details.
Slice Name:
<SliceName>.test.ts → <SliceName>ActivateShift.test.ts → "ActivateShift"Context:
restaurantId or locationId → "Restaurant Management"Using .slices/index.json for lookup:
.slices/index.json to find correct folderfolder and context from matching entry.slices/<context>/<folder>/slice.jsonWhen invoked with a test file path:
Read and parse the test file
Extract slice metadata
Check for existing files
slice.json location via .slices/index.jsonslice.json if found for comparisonid and title fields from slice.json (required for code-slice.json)Analyze test cases
it('spec: ...') test casesslice.jsonBuild specifications array
slice.json specifications arraywhen: Find matching command in slice.json → commands array by titlegiven/then:
slice.json → events array by titlereadmodels → dependencies array (INBOUND events)id field from the matched element/dependency as the linkedIdthen: Find matching readmodel in slice.json → readmodels array by titlenull (indicates new element not in design documentation)linkedId field (errors don't exist in slice.json)Decision: Generate, Update, or Remove code-slice.json
slice.json specifications arrayslice.json specifications: Remove/don't create code-slice.json (no drift)slice.json specifications: Generate/update code-slice.json with:
.slices/<Context>/<folder>/code-slice.json (same directory as slice.json)id field copied from slice.jsontitle field copied from slice.jsonspecifications array with missing specificationsslice.json - it's read-only design documentationValidate output
Infer TypeScript/JSON types from test data:
"String""UUID""Date" or "DateTime""Decimal""Integer""Boolean""List" with element typeCRITICAL: LinkedId Fields Must Use Real IDs from slice.json
linkedId in given/when/then elements: MUST use the actual element IDs from slice.json
slice.json → commands array → id fieldslice.json → events array → id field
events array if they're from other slicesreadmodels → dependencies array for entries with type: "INBOUND" and elementType: "EVENT"id field from the dependency entryslice.json → readmodels array → id fieldnull (will be identified as drift)Other ID fields: Generate unique IDs for specification containers
id: Generate unique ID (e.g., "GENERATED-SPEC-<counter>")id: Generate unique ID for each given/when/then elementExample from slice.json:
{
"commands": [
{
"id": "3458764657124632223", // ← Use THIS for linkedId
"title": "Activate Shift",
...
}
],
"events": [
{
"id": "3458764657005669318", // ← Use THIS for linkedId
"title": "Shift activated",
...
}
]
}
Example in code-slice.json:
{
"id": "GENERATED-SPEC-001", // ← Specification ID
"linkedId": "GENERATED-SPEC-001", // ← MUST match specification id
"when": [
{
"title": "Activate Shift",
"id": "GENERATED-SPEC-CMD-1", // ← Generated wrapper ID
"linkedId": "3458764657124632223" // ← MUST be real command ID from slice.json
}
]
}
Summary of linkedId usage:
specification.linkedId = specification.id (self-reference)element.linkedId = real ID from slice.json → commands arrayelement.linkedId = real ID from slice.json → events array OR readmodels → dependencies (for STATE_VIEW)element.linkedId = real ID from slice.json → readmodels arraylinkedId field (errors don't exist in slice.json)Invoke with any test file path:
State-change slices:
/test-analyzer src/slices/ActivateShift/ActivateShift.test.ts
/test-analyzer src/slices/PlanVacation/PlanVacation.test.ts
State-view slices (projections):
/test-analyzer src/slices/ActivatedOnlineReservations/OnlineReservationStatus.test.ts
/test-analyzer src/slices/ActiveShifts/ActiveShifts.test.ts
The skill automatically:
.slices/ documentationcode-slice.json in same directory as test fileslice.json specifications arrayslice.json specifications array:
code-slice.json:
slice.json specifications → Remove/don't create code-slice.json (no drift)slice.json specifications → Generate/update code-slice.jsonslice.json found → Generate code-slice.json with all test specificationsKey Principle:
slice.json = design documentation (source of truth, READ ONLY)code-slice.json = test-derived specifications (generated/deleted by this skill)src/slices/<SliceName>/<SliceName>.test.ts.slices/<Context>/<folder>/code-slice.json (same directory as slice.json).slices/index.json (find matching slice by title).slices/<Context>/<folder>/slice.json (READ ONLY, from index.json)slice.json specifications arraycode-slice.json if no drift detected (all test specs are in slice.json specifications) - keeps codebase cleanslice.json files - they are read-only design documentation