@hellraisercenobit/ai-engineering-gate 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/agents/design-pattern-reviewer.md +40 -0
- package/agents/modern-typescript-reviewer.md +24 -0
- package/agents/testing-pattern-reviewer.md +23 -0
- package/bin/ai-engineering-gate.mjs +6 -0
- package/contracts/axi/axi-standard.md +273 -0
- package/contracts/axi/pin.json +36 -0
- package/contracts/members.json +58 -0
- package/contracts/schemas/arbitration.schema.json +45 -0
- package/contracts/schemas/decision-envelope.schema.json +215 -0
- package/contracts/schemas/declaration.schema.json +190 -0
- package/contracts/schemas/dispute.schema.json +67 -0
- package/contracts/schemas/evidence-append.schema.json +72 -0
- package/contracts/schemas/gate-output.schema.json +296 -0
- package/contracts/schemas/marker.schema.json +75 -0
- package/contracts/schemas/review-envelope.schema.json +378 -0
- package/contracts/schemas/verdict-record.schema.json +191 -0
- package/contracts/suite-contract.md +270 -0
- package/dist/ai-engineering-gate.mjs +2762 -0
- package/package.json +47 -0
- package/skills/engineering/review-design-patterns/LICENSE +6 -0
- package/skills/engineering/review-design-patterns/SKILL.md +196 -0
- package/skills/engineering/review-design-patterns/agents/openai.yaml +3 -0
- package/skills/engineering/review-design-patterns/references/smell-signatures.md +117 -0
- package/skills/engineering/review-design-patterns/review-design-patterns.yaml +25 -0
- package/skills/engineering/review-modern-typescript/LICENSE +21 -0
- package/skills/engineering/review-modern-typescript/SKILL.md +88 -0
- package/skills/engineering/review-modern-typescript/agents/openai.yaml +3 -0
- package/skills/engineering/review-modern-typescript/references/smell-signatures.md +36 -0
- package/skills/engineering/review-modern-typescript/review-modern-typescript.yaml +22 -0
- package/skills/engineering/review-testing-patterns/SKILL.md +108 -0
- package/skills/engineering/review-testing-patterns/agents/openai.yaml +4 -0
- package/skills/engineering/review-testing-patterns/references/compiler-profile.mjs +103 -0
- package/skills/engineering/review-testing-patterns/references/smell-signatures.md +30 -0
- package/skills/engineering/review-testing-patterns/review-testing-patterns.yaml +23 -0
- package/skills/engineering/transpose-design-patterns/LICENSE +6 -0
- package/skills/engineering/transpose-design-patterns/SKILL.md +231 -0
- package/skills/engineering/transpose-design-patterns/agents/openai.yaml +3 -0
- package/skills/engineering/transpose-design-patterns/references/arbitration.schema.json +45 -0
- package/skills/engineering/transpose-design-patterns/references/decision-envelope.schema.json +215 -0
- package/skills/engineering/transpose-design-patterns/references/declaration.schema.json +190 -0
- package/skills/engineering/transpose-design-patterns/references/design-decision-record.schema.json +731 -0
- package/skills/engineering/transpose-design-patterns/references/dispute.schema.json +67 -0
- package/skills/engineering/transpose-design-patterns/references/evidence-append.schema.json +72 -0
- package/skills/engineering/transpose-design-patterns/references/marker.schema.json +75 -0
- package/skills/engineering/transpose-design-patterns/references/pattern-catalog.md +305 -0
- package/skills/engineering/transpose-design-patterns/references/record.example.json +120 -0
- package/skills/engineering/transpose-design-patterns/references/review-envelope.schema.json +378 -0
- package/skills/engineering/transpose-design-patterns/references/suite-contract.md +270 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-angular.md +224 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-php.md +561 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-quarkus.md +283 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-react.md +256 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-vanilla.md +204 -0
- package/skills/engineering/transpose-design-patterns/references/transpose-vue.md +234 -0
- package/skills/engineering/transpose-design-patterns/transpose-design-patterns.yaml +24 -0
- package/skills/engineering/transpose-modern-typescript/LICENSE +21 -0
- package/skills/engineering/transpose-modern-typescript/SKILL.md +90 -0
- package/skills/engineering/transpose-modern-typescript/agents/openai.yaml +3 -0
- package/skills/engineering/transpose-modern-typescript/references/arbitration.schema.json +45 -0
- package/skills/engineering/transpose-modern-typescript/references/catalog.md +38 -0
- package/skills/engineering/transpose-modern-typescript/references/collections.md +50 -0
- package/skills/engineering/transpose-modern-typescript/references/compatibility.md +61 -0
- package/skills/engineering/transpose-modern-typescript/references/decision-envelope.schema.json +215 -0
- package/skills/engineering/transpose-modern-typescript/references/decision-record.schema.json +830 -0
- package/skills/engineering/transpose-modern-typescript/references/declaration.schema.json +190 -0
- package/skills/engineering/transpose-modern-typescript/references/dispute.schema.json +67 -0
- package/skills/engineering/transpose-modern-typescript/references/evidence-append.schema.json +72 -0
- package/skills/engineering/transpose-modern-typescript/references/idioms.md +74 -0
- package/skills/engineering/transpose-modern-typescript/references/marker.schema.json +75 -0
- package/skills/engineering/transpose-modern-typescript/references/platform.md +147 -0
- package/skills/engineering/transpose-modern-typescript/references/record.example.json +172 -0
- package/skills/engineering/transpose-modern-typescript/references/record.md +37 -0
- package/skills/engineering/transpose-modern-typescript/references/review-envelope.schema.json +378 -0
- package/skills/engineering/transpose-modern-typescript/references/suite-contract.md +270 -0
- package/skills/engineering/transpose-modern-typescript/references/types.md +97 -0
- package/skills/engineering/transpose-modern-typescript/transpose-modern-typescript.yaml +22 -0
- package/skills/engineering/transpose-testing-patterns/SKILL.md +96 -0
- package/skills/engineering/transpose-testing-patterns/agents/openai.yaml +4 -0
- package/skills/engineering/transpose-testing-patterns/references/arbitration.schema.json +45 -0
- package/skills/engineering/transpose-testing-patterns/references/catalog.md +218 -0
- package/skills/engineering/transpose-testing-patterns/references/decision-envelope.schema.json +215 -0
- package/skills/engineering/transpose-testing-patterns/references/decision-record.schema.json +857 -0
- package/skills/engineering/transpose-testing-patterns/references/declaration.schema.json +190 -0
- package/skills/engineering/transpose-testing-patterns/references/detect-adapter.mjs +98 -0
- package/skills/engineering/transpose-testing-patterns/references/dispute.schema.json +67 -0
- package/skills/engineering/transpose-testing-patterns/references/doubles-data.md +45 -0
- package/skills/engineering/transpose-testing-patterns/references/evidence-append.schema.json +72 -0
- package/skills/engineering/transpose-testing-patterns/references/journal-event.schema.json +115 -0
- package/skills/engineering/transpose-testing-patterns/references/marker.schema.json +75 -0
- package/skills/engineering/transpose-testing-patterns/references/record.example.json +230 -0
- package/skills/engineering/transpose-testing-patterns/references/record.md +25 -0
- package/skills/engineering/transpose-testing-patterns/references/review-envelope.schema.json +378 -0
- package/skills/engineering/transpose-testing-patterns/references/suite-contract.md +270 -0
- package/skills/engineering/transpose-testing-patterns/references/tdd.md +62 -0
- package/skills/engineering/transpose-testing-patterns/references/transpose-codeception.md +84 -0
- package/skills/engineering/transpose-testing-patterns/references/transpose-karma-jasmine-angular.md +73 -0
- package/skills/engineering/transpose-testing-patterns/references/transpose-vitest.md +111 -0
- package/skills/engineering/transpose-testing-patterns/references/typescript.md +42 -0
- package/skills/engineering/transpose-testing-patterns/transpose-testing-patterns.yaml +23 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Transpose/review contract 1.1.0
|
|
2
|
+
|
|
3
|
+
Canonical source: `contracts/suite-contract.md` in hellraisercenobit/skills. Copies in
|
|
4
|
+
transpose bundles are generated by `npm run sync:contract`; never edit them by hand.
|
|
5
|
+
The repository maintainer owns this contract. Domain catalogs and record schemas remain
|
|
6
|
+
owned by their transpose skill. Read this contract once per execution.
|
|
7
|
+
|
|
8
|
+
1.1.0 adds clauses to 1.0.0 and changes none of its guarantees. Each member declares the
|
|
9
|
+
contract versions it supports in the member manifest. A workflow that runs on records,
|
|
10
|
+
checks and independent reports without any gate stays valid under 1.1.0: the clauses below
|
|
11
|
+
describe what enforcement derives, never a new obligation on prose.
|
|
12
|
+
|
|
13
|
+
## Guarantees
|
|
14
|
+
|
|
15
|
+
| ID | Requirement | Evidence |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| C01 | One normative catalog per dimension, owned by transpose and read by review. | Resolved local references and identified versions or content hashes. |
|
|
18
|
+
| C02 | Explicit scope and comparison base. | Files and sites, including relevant uncommitted and untracked files. |
|
|
19
|
+
| C03 | Inventory every relevant site, including retained choices. | Domain criteria, alternatives and observable invariants. |
|
|
20
|
+
| C04 | Record each decision before the first affected implementation write. | Schema-valid records outside the repository; preserve previous revisions and reasons. |
|
|
21
|
+
| C05 | Separate deterministic checks from semantic judgment. | Schema/catalog membership and applicable type, runtime, lint and build checks. |
|
|
22
|
+
| C06 | Independent reviewer with a neutral brief. | Fresh context without builder history or rationale; original request and factual constraints only. |
|
|
23
|
+
| C07 | Freeze expectations before reading records or author justification. | Immutable expected matrix in the review transcript; no `git log`, PR rationale or author analysis. |
|
|
24
|
+
| C08 | Compare every site; steelman every candidate finding. | Expected/recorded/actual, exact rule, evidence, strongest defense and refutation. |
|
|
25
|
+
| C09 | Reviewer changes no files and delegates no review. | Report in its response; the builder fixes and dispatches a new fresh reviewer. |
|
|
26
|
+
| C10 | Only a current `SOUND` completes transposition. | Complete audit, zero confirmed findings, passing applicable checks and no unresolved dispute. |
|
|
27
|
+
| C11 | Only the reviewer attests; scope changes invalidate its verdict. | Examined state identified; the gate computes the fingerprints a verdict binds to. |
|
|
28
|
+
| C12 | Missing prerequisites and limits are explicit. | No invented rules, support, independence or attestation. |
|
|
29
|
+
|
|
30
|
+
## Shared execution rules
|
|
31
|
+
|
|
32
|
+
Resolve companions, schema, catalog, this contract and any **required** guides first. Pin
|
|
33
|
+
their versions or hashes for the execution. A missing optional guide is acceptable only
|
|
34
|
+
when the domain permits catalog-only decisions. Conflicting installed contract/catalog
|
|
35
|
+
versions are an incomplete prerequisite; do not silently download another version.
|
|
36
|
+
|
|
37
|
+
The builder inventories scope, compares alternatives including the current implementation,
|
|
38
|
+
records, then writes and checks. Coherent local choices can share a record if every site
|
|
39
|
+
remains identifiable. `none` has the domain's explicit meaning; it is not a shortcut around
|
|
40
|
+
evaluation. No applicable site is a justified non-applicable dimension, not an artificial
|
|
41
|
+
`SOUND`. Do not add common fields to a domain schema that forbids them: coordination
|
|
42
|
+
metadata belongs in an external execution index.
|
|
43
|
+
|
|
44
|
+
The reviewer reads independent requirements and factual constraints, inventories the scope
|
|
45
|
+
and freezes a matrix of expected acceptable choices, rules and invariants **in its response
|
|
46
|
+
before the next tool call that opens records**. It then compares expected, recorded and
|
|
47
|
+
actual. Record absence is not a retrospective code defect in a standalone audit; a claimed
|
|
48
|
+
completed transposition requires its records. State significant exposure to author
|
|
49
|
+
justification. A contaminated brief requires a new reviewer before completion; do not
|
|
50
|
+
rewrite the frozen matrix to match the builder. Verified new facts that change premises
|
|
51
|
+
require a new framing and fresh review, retaining the old matrix.
|
|
52
|
+
|
|
53
|
+
For each candidate, construct the strongest defense (compatibility, public contract, domain
|
|
54
|
+
meaning, framework semantics, proven cost or legitimate simplicity). Drop it if that defense
|
|
55
|
+
holds. Confirm only with an applicable catalog rule and evidence. Report catalog gaps
|
|
56
|
+
separately, without severity or verdict impact. A gap is not permission to invent a rule.
|
|
57
|
+
|
|
58
|
+
Reports identify scope/base/state, reference versions, coverage, frozen matrix, comparison,
|
|
59
|
+
confirmed findings, defended choices, gaps and check evidence. Each finding identifies
|
|
60
|
+
location, rule, expected/recorded/actual, impact, defense, refutation and proposed correction.
|
|
61
|
+
Severity: `Blocker` for concrete correctness/support failures, `Major` for demonstrated
|
|
62
|
+
structural costs or missing guarantees, `Minor` for evidenced idiomatic drift after defense.
|
|
63
|
+
Age or taste alone is never evidence. This clause owns the severity tiers; a domain skill
|
|
64
|
+
references it instead of restating them.
|
|
65
|
+
|
|
66
|
+
| Verdict | Meaning |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| SOUND | Complete audit, zero confirmed findings. |
|
|
69
|
+
| SMELLS | Confirmed findings, no Blocker. |
|
|
70
|
+
| VIOLATIONS | At least one Blocker. |
|
|
71
|
+
|
|
72
|
+
An incomplete execution reports the missing prerequisite and has no attestable quality
|
|
73
|
+
verdict; it is not a fourth verdict. The reviewer edits neither code, records, catalogs nor
|
|
74
|
+
fixtures. Its report is a response that the harness can save externally. Its sole permitted
|
|
75
|
+
external mutations are the gate's attestation and report operations, when supported;
|
|
76
|
+
attestation accepts `SOUND` only. A dispute goes to the user and remains unresolved until
|
|
77
|
+
decided; it is not a fix.
|
|
78
|
+
|
|
79
|
+
## Dimension registry
|
|
80
|
+
|
|
81
|
+
The member manifest `contracts/members.json` is the registry. It owns, per member: the
|
|
82
|
+
dimension identifier, the transpose and review skill locations, the reviewer agent, the
|
|
83
|
+
decision schema, the evidence schemas the dimension owns, the reference bundle, the contract
|
|
84
|
+
versions the member supports, and a status, `implemented` or `qualified`. Nothing else
|
|
85
|
+
defines a dimension identifier, and no other file lists the dimensions.
|
|
86
|
+
|
|
87
|
+
The registry holds orchestration metadata and schema locations only: never a rule, a pattern
|
|
88
|
+
name, an idiom or a test form. Adding a dimension is a registration plus a qualification. It
|
|
89
|
+
never changes enforcement logic and never adds a hook.
|
|
90
|
+
|
|
91
|
+
## State and evidence
|
|
92
|
+
|
|
93
|
+
Store evidence, derive state. Every durable fact is a schema-valid document on disk: a
|
|
94
|
+
declaration, a decision record, an evidence append, an attestation, a report, a dispute or
|
|
95
|
+
an arbitration. No implementation persists a workflow boolean such as "reviewed" or
|
|
96
|
+
"fresh"; state is recomputed from those documents and from the code they cover.
|
|
97
|
+
|
|
98
|
+
A project opts in with one committed marker at its repository root, which also carries the
|
|
99
|
+
project's dimension selection and its evidence and export locations. Without that marker,
|
|
100
|
+
enforcement is silent and every workflow stays portable. Evidence lives outside the
|
|
101
|
+
checkout, under a task key derived from the branch.
|
|
102
|
+
|
|
103
|
+
### Declaration
|
|
104
|
+
|
|
105
|
+
Before the first record, a task declares each registered dimension applicable or
|
|
106
|
+
non-applicable, with a reason, the requester's wording of the request and the factual
|
|
107
|
+
constraints. An applicable declaration also names its scope, as repository-relative file
|
|
108
|
+
paths or directory prefixes, and the relevant configuration files. A non-applicable
|
|
109
|
+
dimension has a declaration and nothing else: skipping a dimension is a recorded decision,
|
|
110
|
+
never a default, and an undeclared registered dimension is an incomplete task.
|
|
111
|
+
|
|
112
|
+
The declaration is what protects the scope and what a neutral brief is rendered from. It is
|
|
113
|
+
revisioned like a record, and it locks once a record, report, review window or dispute
|
|
114
|
+
depends on it, unless the revision only widens scope or adds constraints.
|
|
115
|
+
|
|
116
|
+
### Fingerprints
|
|
117
|
+
|
|
118
|
+
"Current" means three fingerprints.
|
|
119
|
+
|
|
120
|
+
- **Source**: the content hashes of the union of the declared scope paths, the declared
|
|
121
|
+
configuration files and the change set. The change set is the tracked diff between the
|
|
122
|
+
merge-base of the recorded base and HEAD, plus staged, unstaged and untracked files, minus
|
|
123
|
+
the export directory, the gate-owned paths and the marker's ignore patterns. Content
|
|
124
|
+
hashes only: the base revision is recorded and not hashed, so a content-neutral rebase
|
|
125
|
+
does not expire a verdict, and a clean HEAD never identifies a dirty worktree. Change-set
|
|
126
|
+
paths outside every applicable declaration are reported as undeclared changes.
|
|
127
|
+
- **Reference**: the content hashes of the dimension's reference bundle as distributed —
|
|
128
|
+
catalog, decision schema, evidence schemas, guides, the review skill's references and the
|
|
129
|
+
generated copy of this contract — plus the contract version and the gate version.
|
|
130
|
+
- **Decision**: the ordered hash of the dimension's declaration and of every decision record
|
|
131
|
+
of the dimension for the task, each with its revision number.
|
|
132
|
+
|
|
133
|
+
A verdict is current only while all three fingerprints it was bound to still match. Any
|
|
134
|
+
mismatch is stale. Eager marking by a PostToolUse hook is an optimization and is never
|
|
135
|
+
authoritative: a skipped hook, a crash or an editor outside the harness must never leave a
|
|
136
|
+
stale verdict looking current, so expiry is always derived from the fingerprints.
|
|
137
|
+
|
|
138
|
+
### Envelopes
|
|
139
|
+
|
|
140
|
+
Every decision record carries a common outer envelope: dimension, schema version, catalog
|
|
141
|
+
version, the contract versions it supports, need, scope as an array of paths, base, revision
|
|
142
|
+
as number, previous and reason, and two typed lists — `cites`, artifacts and evidence
|
|
143
|
+
sources that exist when the record is validated, and `plans`, artifacts the record commits
|
|
144
|
+
to produce, each with its dimension-defined role. The dimension-specific body stays owned by
|
|
145
|
+
the dimension schema. Applicability is not a record field; it lives in the declaration.
|
|
146
|
+
|
|
147
|
+
`cites` carries referential integrity. A cited path that does not exist refuses the record.
|
|
148
|
+
A claim of unknown about a checkable fact — targets, runtimes, environments, configuration —
|
|
149
|
+
is accepted only with the sources consulted cited, or with the paths searched and not found.
|
|
150
|
+
A revision that announces a correction is refused when no cited artifact changed: a record
|
|
151
|
+
describes what was done, not what should have been. `plans` are not checked when the record
|
|
152
|
+
is written, so a record that precedes the first affected write stays valid under C04; every
|
|
153
|
+
planned artifact must exist before a review begins, is filed or is dispatched.
|
|
154
|
+
|
|
155
|
+
Every review emits a common review envelope: dimension, the supported contract version, the
|
|
156
|
+
verdict, the records examined, the checks it saw executed, a reviewer object with an
|
|
157
|
+
independence claim and a declared identity, the confirmed findings and the
|
|
158
|
+
challenged-survived list. Each finding has an identifier and a kind, `evidence` or
|
|
159
|
+
`judgment`; an evidence finding carries a typed remedy, a judgment finding the proposed
|
|
160
|
+
correction C08 already requires. The envelope carries no fingerprint: a fingerprint a
|
|
161
|
+
builder or a reviewer writes anywhere is ignored.
|
|
162
|
+
|
|
163
|
+
### Attestation and report
|
|
164
|
+
|
|
165
|
+
The gate writes both, and they are the reviewer's only permitted external mutations. An
|
|
166
|
+
attestation stores a `SOUND` envelope together with the three fingerprints of the reviewer's
|
|
167
|
+
window and its captured identity. A report stores a `SMELLS` or `VIOLATIONS` envelope bound
|
|
168
|
+
the same way; it blocks completion until a `SOUND` attestation on a later state, or an
|
|
169
|
+
arbitration closing its last open finding, supersedes it. No other verdict is attestable and
|
|
170
|
+
no verdict is a score.
|
|
171
|
+
|
|
172
|
+
### Findings, disputes and arbitration
|
|
173
|
+
|
|
174
|
+
A finding admits two responses: address it — the remedy executed and the artifact appended,
|
|
175
|
+
or the record revised and the state moved — or dispute it with a pointer to existing
|
|
176
|
+
counter-evidence. An answer in prose is neither, and a changed fingerprint alone addresses
|
|
177
|
+
nothing. Findings about evidence say evidence not on file, never false claim: the builder is
|
|
178
|
+
asked to file, not to confess.
|
|
179
|
+
|
|
180
|
+
While any finding of the last report is pending, no new review of that dimension begins, so
|
|
181
|
+
the same finding is never re-litigated with a fresh reviewer. A valid dispute blocks
|
|
182
|
+
completion and goes to the user; it never goes to another reviewer on the same state. Its
|
|
183
|
+
only exit is an arbitration that only a human hand writes: `uphold` closes the finding,
|
|
184
|
+
`reject` puts its remedy or correction back to pending.
|
|
185
|
+
|
|
186
|
+
### Reviewer identity
|
|
187
|
+
|
|
188
|
+
Every gate call carries the harness session identifier. A reviewer's calls carry an agent
|
|
189
|
+
identifier that must differ from the builder's. This checks consistency, not independence.
|
|
190
|
+
Where a harness provides no agent identifier, the attestation is stored unverified, the state
|
|
191
|
+
says so, and a pipeline may require verified identity.
|
|
192
|
+
|
|
193
|
+
### Completion
|
|
194
|
+
|
|
195
|
+
For each registered dimension: a non-applicable declaration needs its reason; an applicable
|
|
196
|
+
one needs at least one validated record, every planned artifact produced, a current `SOUND`
|
|
197
|
+
attestation, no current report with an open finding and no unresolved dispute. An undeclared
|
|
198
|
+
registered dimension is incomplete. Any incomplete dimension blocks completion whatever the
|
|
199
|
+
others say. Requirements combine; they never average, and there is no score.
|
|
200
|
+
|
|
201
|
+
Deterministic checks stay the reviewer's responsibility under C10 and appear in the review
|
|
202
|
+
envelope as the checks it saw executed. Enforcement validates their presence, never their
|
|
203
|
+
result.
|
|
204
|
+
|
|
205
|
+
## Neutral brief
|
|
206
|
+
|
|
207
|
+
Send only the filled fields below to the named reviewer or a fresh general subagent with
|
|
208
|
+
no inherited conversation. Keep test expectations and other reviewers' conclusions out.
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
You are the fresh <dimension> reviewer. Run /<review-skill> yourself; do not delegate.
|
|
212
|
+
Read-only: do not modify any file, including code, records, catalogs or fixtures.
|
|
213
|
+
Scope: <exact paths/symbols>; repository: <absolute path>.
|
|
214
|
+
Base: <ref/commit or standalone>; include relevant uncommitted and new files.
|
|
215
|
+
Use git diff and file reads, never git log or PR descriptions.
|
|
216
|
+
Original request: <requester wording, without builder choices or rationale>.
|
|
217
|
+
Factual constraints: <project targets, public contracts, independent sources>.
|
|
218
|
+
Records: <paths; check existence only until the expected matrix is frozen>.
|
|
219
|
+
Check evidence: <paths; read results after freezing, not implementation rationale>.
|
|
220
|
+
Undeclared changes: <change-set paths outside every declaration>.
|
|
221
|
+
Report your frozen matrix before opening the records. End with the domain report
|
|
222
|
+
and one verdict, or explain incomplete execution without attestation.
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Composition and expiry
|
|
226
|
+
|
|
227
|
+
One builder coordinates all applicable dimensions. Keep their records and verdicts distinct.
|
|
228
|
+
Historical transforming reviews run before final reviews. Independent reviewers can run in
|
|
229
|
+
parallel on one frozen final state, without exchanging rationale. Completion requires all
|
|
230
|
+
applicable dimensions `SOUND` on that same state; one verdict cannot compensate for another.
|
|
231
|
+
|
|
232
|
+
Any change to a file in a review's scope invalidates it, including prose. Shared files
|
|
233
|
+
invalidate all covering reviews. Without precise scope tracking, invalidate the whole
|
|
234
|
+
change's reviews. Identify the state with a commit plus the staged/unstaged diff and
|
|
235
|
+
untracked file contents or hashes; a clean HEAD alone does not identify a dirty worktree.
|
|
236
|
+
Record/schema/catalog changes also reopen the affected review. No generic orchestrator
|
|
237
|
+
is implied. An external index of scopes, hashes, record paths, checks and responses is enough.
|
|
238
|
+
|
|
239
|
+
A correction for one dimension moves the change set and therefore expires every verdict of
|
|
240
|
+
the task, because every reviewer's brief covers the whole diff. Corrections are therefore
|
|
241
|
+
batched: address every pending finding of every dimension, then reopen all applicable
|
|
242
|
+
reviews together on one state, frozen while they are in flight so no verdict binds to code
|
|
243
|
+
its reviewer never read. A review filed on a state that moved since it began is void.
|
|
244
|
+
|
|
245
|
+
If domain requests conflict, identify the incompatible invariants and reopen decisions
|
|
246
|
+
before writing. A dimension that turns non-`SOUND` on a state produced by correcting another
|
|
247
|
+
is a cross-dimension conflict, which the next briefs carry. Stop a repeating conflict for
|
|
248
|
+
user arbitration; never force a verdict. Bound the conflict rounds and the total rounds, and
|
|
249
|
+
send a task that reaches either bound to the user rather than looping.
|
|
250
|
+
|
|
251
|
+
## Gate and portable execution
|
|
252
|
+
|
|
253
|
+
Inspect the installed gate's help/capabilities before using a dimension. Never invent CLI
|
|
254
|
+
flags, reuse a different dimension or treat a refused record as an absent gate. A gate
|
|
255
|
+
validates shape, membership and referential integrity; the reviewer owns semantic judgment
|
|
256
|
+
and only attests SOUND. The gate computes its own fingerprints and accepts none. Fix a
|
|
257
|
+
refused record before continuing that workflow.
|
|
258
|
+
|
|
259
|
+
The suite's own gate is `ai-engineering-gate`, generic by construction: it derives state from
|
|
260
|
+
evidence and holds no domain rule. Enforcement it applies covers omission, drift and stale
|
|
261
|
+
evidence, not a deliberately forged evidence index. A harness Stop hook is advisory by design
|
|
262
|
+
of the harnesses; the lock on publication is the gate's exit code, consumed by a delivery
|
|
263
|
+
pipeline gate or a CI check.
|
|
264
|
+
|
|
265
|
+
Without a compatible gate, portable completion consists of validated records, successful
|
|
266
|
+
checks and an independent report tied to the examined state. It provides no automatic
|
|
267
|
+
enforcement or lock. If the project's workflow requires gate attestation, an absent or
|
|
268
|
+
unsupported gate leaves that workflow incomplete; portable evidence cannot replace it.
|
|
269
|
+
Keep evidence available through review/correction; do not reconstruct missing historical
|
|
270
|
+
decisions as if they preceded implementation.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# TDD and process evidence
|
|
2
|
+
|
|
3
|
+
Applies TP-06/07/15/16. Choose `tdd`, `characterization`, `coverage` or `audit` in the
|
|
4
|
+
record. Existing tests that pass immediately are useful coverage, not an observed TDD cycle.
|
|
5
|
+
|
|
6
|
+
1. Name the behavior, independent requirement, public seam and discriminating example.
|
|
7
|
+
Record before tests, determinant helpers, configuration or production changes.
|
|
8
|
+
2. Write one behavioral slice. Run it. An import/setup error is setup work, not RED.
|
|
9
|
+
A minimal public skeleton can make the intended assertion reachable. For a static
|
|
10
|
+
guarantee, isolate the expected diagnostic for the missing type contract.
|
|
11
|
+
3. Preserve test/oracle and determinant helper contents. Implement the behavior to GREEN.
|
|
12
|
+
Changing the test to obtain GREEN starts a new cycle and preserves the old observation.
|
|
13
|
+
Do not add speculative features; an obvious naturally general solution is allowed.
|
|
14
|
+
4. Run the focused scenario and relevant regression checks. Map scenario IDs to executed
|
|
15
|
+
test identities. Record discovered counts, skips/todos/fails and retries explicitly.
|
|
16
|
+
5. Before refactoring, name concrete pressure: duplication, extension cost, fragile
|
|
17
|
+
invariant or confused responsibility. Keeping the design is valid. Preserve observable
|
|
18
|
+
contracts; green alone is not full equivalence. Compare with the legacy/reference or
|
|
19
|
+
add a discriminating probe when the risk warrants it. New behavior needs its own cycle.
|
|
20
|
+
|
|
21
|
+
Keep an append-only external JSONL journal linked to the initial record, one event per phase,
|
|
22
|
+
validated against `journal-event.schema.json`:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{"record":"rec-001","scenario":"boundary","phase":"red","command":"npm test -- --run boundary.test.ts","exitCode":1,"cause":"expected 10, received 0","failureClass":"expected-behavior-missing","output":"runs/red.txt","state":"snapshots/red/"}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This is a format example, not evidence. Capture output from the actual tool and preserve
|
|
29
|
+
accessible snapshots or resolvable immutable refs for RED, GREEN and any relevant refactor.
|
|
30
|
+
Every event names its **failure class** when its phase is red, so an absent behavior is
|
|
31
|
+
distinguishable from a behavior that exists and disagrees, and both from setup work.
|
|
32
|
+
|
|
33
|
+
Artifact hashes are not written in the event. Where a gate is installed, `evidence append`
|
|
34
|
+
stamps each event with the content hashes of the record's planned artifacts by role, `test`
|
|
35
|
+
and `production`, so the event proves the state of those files at the moment it was filed.
|
|
36
|
+
Hashes identify states but do not allow inspection of missing content. Do not overwrite
|
|
37
|
+
earlier events or backfill results into the initial decision. No RED commits or empty
|
|
38
|
+
reflection commits are required. Keep evidence through review and correction.
|
|
39
|
+
|
|
40
|
+
## Derived states
|
|
41
|
+
|
|
42
|
+
The journal is the fact; these four states are read from it, not claimed:
|
|
43
|
+
|
|
44
|
+
| State | Read from the journal | What it proves |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| `observed` | a red event, not marked replayed, whose stamped `production` hashes equal the base state, followed by a green event on the same scenario | the test failed before the production change existed |
|
|
47
|
+
| `replayed` | a red and a green event the gate wrote itself while executing a replay | the test discriminates the behavior; nothing about chronology |
|
|
48
|
+
| `incomplete` | a cycle missing its red or its green | the profile claims TDD and its evidence does not support it |
|
|
49
|
+
| `non-TDD` | the record's mode is `characterization`, `coverage` or `audit` | another profile, judged on its own terms |
|
|
50
|
+
|
|
51
|
+
A record whose mode is `tdd` and whose scenarios are `incomplete` is a false TDD claim, and a
|
|
52
|
+
reviewer states it as a finding on evidence, not as an opinion. A `replayed` state answers a
|
|
53
|
+
missing-RED remedy: it is proof that the test discriminates, not proof that it was written
|
|
54
|
+
first, and a review says which of the two it has. The reviewer judges discrimination and
|
|
55
|
+
design; chronology is the gate's stamp to read, not a claim to weigh.
|
|
56
|
+
|
|
57
|
+
Portable evidence is inspectable, not tamperproof. Timestamps and commit messages do not
|
|
58
|
+
prove chronology alone. Missing observations cannot be reconstructed from final source.
|
|
59
|
+
A retrospective audit can assess test quality with that limit; a claimed full TDD
|
|
60
|
+
transposition without its required evidence remains incomplete. The reviewer never
|
|
61
|
+
modifies code or fixtures to create evidence; the builder runs requested experiments in
|
|
62
|
+
an isolated copy, then a fresh reviewer examines the results.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Codeception adapter 1.0.0
|
|
2
|
+
|
|
3
|
+
Read alongside the applicable catalog rules. Identity is **Codeception**: any installed
|
|
4
|
+
`codeception/codeception` the lockfile reports. This is not "Codeception 5.0 only" and not
|
|
5
|
+
generic PHPUnit. Detect the profile from the lockfile, `codeception.yml` / suite files,
|
|
6
|
+
installed PHPUnit, and the command the project actually runs. Record Codeception major/minor,
|
|
7
|
+
suite types (Unit/Cest/Functional/Acceptance), DB/transaction helpers, group filters and
|
|
8
|
+
command. Do not key routing on an exact `5.0.0` string.
|
|
9
|
+
|
|
10
|
+
A first **reference profile** pins Codeception 5.x Unit tests that talk to MySQL through
|
|
11
|
+
`public UnitTester $tester` transactions. That profile is a qualification target, not an
|
|
12
|
+
adoption pin and not a requirement that every Codeception project look like Unit+MySQL.
|
|
13
|
+
A project without MySQL, without `@group`, or with a different `codecept` invocation still
|
|
14
|
+
uses this adapter; the freeze records what is actually there.
|
|
15
|
+
|
|
16
|
+
Sources checked 2026-09-18; verify support again for a different installed profile.
|
|
17
|
+
Unknown or undocumented Codeception/PHPUnit majors are incomplete execution, or use the
|
|
18
|
+
conservative mappings below with named unknowns. Never treat PHP as close enough to Vitest.
|
|
19
|
+
|
|
20
|
+
## Detect and route
|
|
21
|
+
|
|
22
|
+
If `codeception/codeception` is present, load this adapter. Patch, minor and major differences
|
|
23
|
+
stay in the capability table. Do not fall back to catalog-only because the version is not 5.0,
|
|
24
|
+
and do not silently migrate to Vitest.
|
|
25
|
+
|
|
26
|
+
| Detected fact | Record when present | Do not invent |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| Lockfile `codeception/codeception` | major/minor (4.x, 5.0.x, 5.1.x and other installed ids) | an exact 5.0.0 pin |
|
|
29
|
+
| Suite type | Unit, Cest, Functional, Acceptance from config/paths | Unit+MySQL for a pure Acceptance suite |
|
|
30
|
+
| `UnitTester` + `startTransaction` / `endTransaction` | DB isolation on `$this->tester` | a jsdom or "pure unit" claim |
|
|
31
|
+
| `@group` / CI filter | TP-16 execution filter | a group rule the project does not use |
|
|
32
|
+
| Actual invocation | compose, `vendor/bin/codecept`, CI image | a guessed `codecept` path |
|
|
33
|
+
| `Codeception\\Stub` and PHPUnit doubles | APIs on the installed pair | `vi.fn<(...)>()` |
|
|
34
|
+
| `loadMfb` / `getLegacyController` | existing entry to legacy controllers | a new port |
|
|
35
|
+
| `getDefaultAccountId` / `tests/resources/modelHelper` | project helpers that exist | those helpers on a project that lacks them |
|
|
36
|
+
|
|
37
|
+
## Capability table
|
|
38
|
+
|
|
39
|
+
Map each TP family from **profile predicates**, not from a single frozen 5.0 column.
|
|
40
|
+
|
|
41
|
+
| Catalog families | Profile predicate | Transposition |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| TP-01/02/06/15 | Cest or Unit methods exist | Direct methods, explicit assertions. Snapshots unavailable unless the profile already has a snapshot tool |
|
|
44
|
+
| TP-03/04/08/10 | `Codeception\\Stub` / PHPUnit doubles on the installed pair | Those doubles at the chosen seam. No Vitest generics. Module-mock hoisting unavailable |
|
|
45
|
+
| TP-05 | A PHP property library is already in the lockfile | Use that library. Otherwise unavailable; do not add `fast-check` |
|
|
46
|
+
| TP-07/16 | Detected invocation and, when configured, `@group` / CI filters | Recorded command = actual command. Absence of a group filter is not a finding |
|
|
47
|
+
| TP-09 | A project helper is present in the suite | Use that helper. If none exists, do not invent `getDefaultAccountId` or `modelHelper` |
|
|
48
|
+
| TP-11 | An existing entry is present | Use that entry. If `loadMfb` / `getLegacyController` are absent, do not invent a port |
|
|
49
|
+
| TP-12 | PHP | Unavailable. No `expectTypeOf` |
|
|
50
|
+
| TP-13 | PHPUnit/Codeception teardown | Teardown hooks and, when present, DB transaction lifecycle. No JS fake timers |
|
|
51
|
+
| TP-14 | Suite actor / DB | Environment from the suite. MySQL when the Unit tester uses it; otherwise the suite's actor. `Codeception\\Test\\Unit` does not automatically mean no I/O |
|
|
52
|
+
|
|
53
|
+
## Isolation and environment
|
|
54
|
+
|
|
55
|
+
When the profile uses `$this->tester` plus transactions against a database, isolation is
|
|
56
|
+
that transaction lifecycle, not a mocked database under a Unit class name. Recale "pure
|
|
57
|
+
unit", jsdom and Vitest Browser Mode claims. A Unit path that talks to MySQL is still this
|
|
58
|
+
adapter; name the remaining integration risk.
|
|
59
|
+
|
|
60
|
+
Account identity and model helpers belong only when those symbols exist. Legacy `app/`
|
|
61
|
+
controllers belong only through the existing `loadMfb()` / `getLegacyController()` entry.
|
|
62
|
+
|
|
63
|
+
## Doubles and errors
|
|
64
|
+
|
|
65
|
+
Use `Codeception\\Stub` and the PHPUnit doubles that ship with `Codeception\\Test\\Unit` on
|
|
66
|
+
the installed pair. Keep the seam honest: a stub is not a fake, and a fake's policy needs
|
|
67
|
+
its own owner. Do not emit `vi.fn`, `vi.spyOn`, `vi.mocked`, `test.extend` or hoisted
|
|
68
|
+
`vi.mock`.
|
|
69
|
+
|
|
70
|
+
Error recipes must reject a wrong class with the same message, a missing exception and an
|
|
71
|
+
accidental error. Message matching alone does not establish class. Inspect one observed
|
|
72
|
+
failure instead of invoking a stateful action twice.
|
|
73
|
+
|
|
74
|
+
## Commands and builder limits
|
|
75
|
+
|
|
76
|
+
RED/GREEN must use the project's actual invocation, for example
|
|
77
|
+
`docker compose run --rm --no-deps -T cli vendor/bin/codecept run --no-colors <path>` when
|
|
78
|
+
that is what CI or the worktree runs. Do not invent a local `vendor/bin/codecept` if the
|
|
79
|
+
project never uses it. Map required scenarios to executed test identities. Honor `@group`
|
|
80
|
+
filters when CI actually applies them.
|
|
81
|
+
|
|
82
|
+
Never copy Vitest `test.extend`, `vi.fn`, `expectTypeOf`, snapshots or `fast-check` into
|
|
83
|
+
PHP tests. Catalog families stay runner-neutral; this adapter chooses APIs from the detected
|
|
84
|
+
profile only.
|
package/skills/engineering/transpose-testing-patterns/references/transpose-karma-jasmine-angular.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Karma + jasmine-core + Angular TestBed adapter 1.0.0
|
|
2
|
+
|
|
3
|
+
Read alongside the applicable catalog rules. Identity is **Karma + jasmine-core +
|
|
4
|
+
Angular TestBed**, not generic Jasmine and not a pinned Angular patch. Detect the
|
|
5
|
+
family from lockfile, karma config and Angular project signals, then map capabilities
|
|
6
|
+
from the **installed** profile. Neighbouring majors that still use TestBed plus Karma
|
|
7
|
+
stay on this adapter.
|
|
8
|
+
|
|
9
|
+
Reference profile 1 (a test target, not a supported-version list): Angular 10.2.5,
|
|
10
|
+
Karma 6.3.4, jasmine-core 3.5, TypeScript 4.0.5, with
|
|
11
|
+
`strict` / `noImplicitAny` / `strictNullChecks` / `noImplicitThis` off, ChromeHeadless
|
|
12
|
+
when that launcher is configured, and optional drifted-spec quarantine when the project
|
|
13
|
+
already has one. Record the derived compiler target, majors, browser and unavailable
|
|
14
|
+
families before opening records. An unknown major that still looks like this family is
|
|
15
|
+
incomplete execution or a conservative mapping with named unknowns, never a Vitest
|
|
16
|
+
fallback.
|
|
17
|
+
|
|
18
|
+
## Detect and route
|
|
19
|
+
|
|
20
|
+
Require Karma, jasmine-core, `@angular/core`, a karma config and an Angular project.
|
|
21
|
+
Plain jasmine-core without TestBed/Karma does not route here. Vitest lockfiles route to
|
|
22
|
+
the Vitest adapter. Missing required signals are unknown or `complete: false`, never
|
|
23
|
+
Vitest.
|
|
24
|
+
|
|
25
|
+
Inspect lockfile versions, `karma.conf`, `test.ts` / `include` discovery, tsconfig
|
|
26
|
+
target and strictness, browserslist / `customLaunchers`, and npm scripts. Compiler and
|
|
27
|
+
runtime layers come from the project's tsconfig and installed TypeScript, not a
|
|
28
|
+
hardcoded 4.0.5 / ES2015 line.
|
|
29
|
+
|
|
30
|
+
## Capability table
|
|
31
|
+
|
|
32
|
+
Predicates follow the detected profile. Do not copy a recipe that the installed
|
|
33
|
+
stack cannot honor.
|
|
34
|
+
|
|
35
|
+
| Catalog families | Profile predicates |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| TP-01/02/15 | `describe` / `it` or the installed Jasmine/Angular equivalents. No Vitest `test.for`. |
|
|
38
|
+
| TP-06 | Snapshots unavailable unless the profile already has a snapshot tool. |
|
|
39
|
+
| TP-03/04/08 | `jasmine.createSpy` / `spyOn` / `spyOnProperty`. Untyped `jasmine.createSpy` when types or strictness cannot honor generics; typed spies only when the compiler profile supports them. `vi.fn` is forbidden. |
|
|
40
|
+
| TP-05 | Property testing unavailable unless already in the lockfile. |
|
|
41
|
+
| TP-07/16 | The project's actual Karma/Angular command (`ng test`, `npm run test-headless`, or equivalent). Pass `NODE_OPTIONS=--openssl-legacy-provider` only when that app's Node/webpack already needs it. Discovery: `require.context` when `test.ts` uses it, otherwise the project's Karma files pattern. When a quarantine or skip list is present (`DRIFTED_SPECS`, `*.spec.ts.drifted`, or the project's equivalent), a green total that excludes those specs is not coverage. |
|
|
42
|
+
| TP-09 | Existing TestBed modules and spec factories. No Vitest `test.extend`. |
|
|
43
|
+
| TP-11 | TestBed resource ownership when tests use TestBed. |
|
|
44
|
+
| TP-12 | Unavailable while `strict`, `noImplicitAny`, `strictNullChecks` and `noImplicitThis` are off; do not turn them on to make a type test pass. `satisfies` / `expectTypeOf` only when the compiler profile allows them. |
|
|
45
|
+
| TP-13 | Angular async clock APIs present in the installed `@angular/core/testing` (`fakeAsync` / `tick` / `flush` / `waitForAsync` on the reference profile). Do not mix with `jasmine.clock()`. Mixing two clocks is a finding. If a later profile replaces that clock, map the installed clock, still without mixing. |
|
|
46
|
+
| TP-14 | Detected browser launcher (often ChromeHeadless). jsdom, happy-dom and Vitest Browser Mode are the wrong guarantee when Karma launches a real Chrome. |
|
|
47
|
+
|
|
48
|
+
## Doubles, types and TestBed
|
|
49
|
+
|
|
50
|
+
Keep doubles on the installed jasmine-core API. Do not invent Vitest spies to satisfy
|
|
51
|
+
TP-03. When the installed tsconfig has `strict` / `noImplicitAny` / `strictNullChecks` /
|
|
52
|
+
`noImplicitThis` off, untyped spies are the honest mapping; enabling those flags to unlock
|
|
53
|
+
TP-12 is out of scope.
|
|
54
|
+
|
|
55
|
+
Arrange through existing TestBed modules or spec factories. TestBed owns component,
|
|
56
|
+
module and HTTP testing resources that the spec creates; reset or close them according
|
|
57
|
+
to the installed TestBed API, including failure paths.
|
|
58
|
+
|
|
59
|
+
## Async clock and execution
|
|
60
|
+
|
|
61
|
+
Use one clock. On the reference profile that is Angular `fakeAsync` / `tick` / `flush` /
|
|
62
|
+
`waitForAsync`. `jasmine.clock()` in the same spec is a mixing finding. Await
|
|
63
|
+
`waitForAsync` work; a swallowed rejection is a false green.
|
|
64
|
+
|
|
65
|
+
Run the detected non-interactive command. If CI cannot launch ChromeHeadless, stay on
|
|
66
|
+
this adapter as `implemented` and record the skip; do not substitute Vitest. Map
|
|
67
|
+
required scenario IDs to executed identities and disclose skipped, quarantined and
|
|
68
|
+
retried specs. A suite that hides drifted specs behind a green total has not proven
|
|
69
|
+
TP-16.
|
|
70
|
+
|
|
71
|
+
Sources: [Karma](https://karma-runner.github.io/),
|
|
72
|
+
[jasmine](https://jasmine.github.io/),
|
|
73
|
+
[Angular testing](https://angular.dev/guide/testing).
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Vitest adapter 1.0.0
|
|
2
|
+
|
|
3
|
+
Read alongside the applicable catalog rules. This is the only qualified runner adapter.
|
|
4
|
+
Detect versions from the lockfile and actual commands, not package ranges alone. Reference
|
|
5
|
+
profiles are Vitest 5.0.1/TypeScript 7.0.2 and Vitest 4/TypeScript 6; exact fixture versions
|
|
6
|
+
and reproducible commands live in the repository's [qualification guide](https://github.com/hellraisercenobit/skills/blob/main/tests/testing-patterns/README.md).
|
|
7
|
+
They are test targets, not an adoption claim or migration requirement. Sources checked
|
|
8
|
+
2026-09-16; verify support again for a different installed profile.
|
|
9
|
+
|
|
10
|
+
## Detect and route
|
|
11
|
+
|
|
12
|
+
Record runner, compiler/checker, Node/browser, Vite, module mode, strict options, transform,
|
|
13
|
+
type declarations and relevant configuration. Vitest 5 requires Node >=22.12 and Vite >=6.4.
|
|
14
|
+
Its clearMocks default clears histories, not implementations; inline projects inherit
|
|
15
|
+
root configuration; hoisted calls must be top level. Inspect migration differences before
|
|
16
|
+
copying configuration. Keep a compatible older project when upgrading adds no needed guarantee.
|
|
17
|
+
|
|
18
|
+
| Catalog families | Vitest transposition |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| TP-01/02/06/15 | Direct `test`/`it`, explicit assertions, reviewed snapshots only where useful |
|
|
21
|
+
| TP-03/04/08/10 | Typed `vi.fn`, `vi.spyOn`, port fake, shared real/fake contract |
|
|
22
|
+
| TP-05 | fast-check inside Vitest, replay seed/path and independent model |
|
|
23
|
+
| TP-07/16 | `vitest run`, actual reporter output, separate compiler command |
|
|
24
|
+
| TP-09/11 | Local factory first; context fixture/hooks for resource ownership |
|
|
25
|
+
| TP-12 | Compiler project/consumer tests or supported Vitest type-test mode |
|
|
26
|
+
| TP-13 | Awaited assertions, controlled clock/timers/barriers and cleanup |
|
|
27
|
+
| TP-14 | Node, DOM simulation or real Browser Mode according to the guarantee |
|
|
28
|
+
|
|
29
|
+
## Scenarios and resources
|
|
30
|
+
|
|
31
|
+
Use behavior names and the project's `test`/`it` convention. `test.each` or `test.for` can
|
|
32
|
+
clarify a typed table; no count threshold forces parameterization. For concurrent tests,
|
|
33
|
+
use context-bound `expect` where assertion/snapshot tracking requires the test context.
|
|
34
|
+
|
|
35
|
+
Plain factories suit simple fresh values. `test.extend` suits reusable resources with
|
|
36
|
+
explicit scope. Current fixture builders support named extension and `onCleanup`; older
|
|
37
|
+
profiles may require the documented `use` form. Register cleanup according to the installed
|
|
38
|
+
API, including partial setup and failure. Do not register multiple `onCleanup` callbacks
|
|
39
|
+
where only one is supported; split resources or combine teardown. Hooks and `try/finally`
|
|
40
|
+
are legitimate. `using`/`await using` require both transformation and runtime disposal support.
|
|
41
|
+
|
|
42
|
+
## Doubles and errors
|
|
43
|
+
|
|
44
|
+
Keep signatures typed, for example `vi.fn<(message: Message) => Promise<void>>()`.
|
|
45
|
+
`vi.mocked` supplies typing, not a runtime mock. Clear removes call history, reset changes
|
|
46
|
+
implementation state, restore restores originals for spies; confirm exact installed
|
|
47
|
+
behavior. Module mocking is justified only at the chosen seam. Use typed imports where
|
|
48
|
+
supported and respect hoisting. Native browser ESM namespaces are sealed; spying on an
|
|
49
|
+
export may require an appropriate supported module-spy strategy instead.
|
|
50
|
+
|
|
51
|
+
Error recipes must reject a wrong class/discriminant with the same message, missing
|
|
52
|
+
rejection and an accidental error. Message matching alone does not establish class.
|
|
53
|
+
For a stateful action inspect one observed error instead of invoking the action twice:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const outcome = await operation().then(
|
|
57
|
+
value => ({ kind: 'resolved' as const, value }),
|
|
58
|
+
(error: unknown) => ({ kind: 'rejected' as const, error }),
|
|
59
|
+
);
|
|
60
|
+
expect(outcome.kind).toBe('rejected');
|
|
61
|
+
if (outcome.kind !== 'rejected') throw new Error('Expected rejection');
|
|
62
|
+
expect(outcome.error).toBeInstanceOf(DomainError);
|
|
63
|
+
expect(outcome.error).toMatchObject({ code: 'LIMIT', message: 'Limit reached' });
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Assert only fields that belong to the contract. The explicit guard also narrows TypeScript;
|
|
67
|
+
an ordinary matcher does not guarantee narrowing. `toThrowError` is deprecated in current
|
|
68
|
+
documentation. Execute recipes on each claimed profile instead of assuming matcher semantics.
|
|
69
|
+
|
|
70
|
+
## Async, time, properties and environments
|
|
71
|
+
|
|
72
|
+
Await/return promises and async matchers; a catch without guaranteed assertions permits
|
|
73
|
+
false green. Time as input or a controlled clock handles business time. Fake timers handle
|
|
74
|
+
schedulers, debounce and retry; advance tasks deliberately and restore timers even on
|
|
75
|
+
failure. To prove exclusion, force overlapping operations using controlled promises and
|
|
76
|
+
observe the contested effect. Timer advancement or a final total alone is insufficient.
|
|
77
|
+
|
|
78
|
+
Use fast-check when input space or histories justify it. Preserve shrinking result, seed
|
|
79
|
+
and replay path. Avoid a production algorithm copied into a reference model. Retain a
|
|
80
|
+
simple example where it is clearer.
|
|
81
|
+
|
|
82
|
+
Use Browser Mode for native browser contracts, with a real provider and engine recorded.
|
|
83
|
+
The Playwright provider is still Vitest, not Playwright Test. Await browser locators and
|
|
84
|
+
retrying assertions. Simulation remains valid for guarantees it faithfully models.
|
|
85
|
+
For HTTP, choose port fake, MSW, local server or real isolated service by the seam under
|
|
86
|
+
test. Fail visibly on unexpected requests and reset/close handlers. MSW is not a remote
|
|
87
|
+
provider contract proof.
|
|
88
|
+
|
|
89
|
+
## Commands and execution limits
|
|
90
|
+
|
|
91
|
+
Run the installed `vitest run` non-interactively and a checker command that actually
|
|
92
|
+
includes production and test files. Vitest runtime is not a typecheck; `expectTypeOf`
|
|
93
|
+
alone at runtime is no proof. TypeScript 7 tooling using the older programmatic API may
|
|
94
|
+
need a compatible TS6 checker. Inspect compiler included-file output when uncertain.
|
|
95
|
+
|
|
96
|
+
Map required scenario IDs to executed test identities and outcomes, not just exit code.
|
|
97
|
+
Expose `.skip`, `.todo`, `.fails`, filtering and retries. Honor the project's lint/build/
|
|
98
|
+
coverage gates; include relevant unimported files with coverage configuration. No invented
|
|
99
|
+
coverage threshold or mandatory mutation framework. Resource cases include failure cleanup.
|
|
100
|
+
|
|
101
|
+
Sources: [migration](https://vitest.dev/guide/migration/),
|
|
102
|
+
[test context](https://vitest.dev/guide/test-context),
|
|
103
|
+
[mocking](https://vitest.dev/guide/mocking),
|
|
104
|
+
[modules](https://vitest.dev/guide/mocking/modules),
|
|
105
|
+
[expect](https://vitest.dev/api/expect),
|
|
106
|
+
[types](https://vitest.dev/guide/testing-types),
|
|
107
|
+
[timers](https://vitest.dev/guide/mocking/timers),
|
|
108
|
+
[disposal](https://vitest.dev/guide/recipes/explicit-resources),
|
|
109
|
+
[browser](https://vitest.dev/guide/browser/),
|
|
110
|
+
[requests](https://vitest.dev/guide/mocking/requests),
|
|
111
|
+
[coverage](https://vitest.dev/guide/coverage).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# TypeScript guarantees
|
|
2
|
+
|
|
3
|
+
Applies TP-12/15/16. Identify the actual compiler/checker, declarations, module mode,
|
|
4
|
+
strict options, transform and runtimes. Keep these three checks distinct:
|
|
5
|
+
|
|
6
|
+
| Check | Proves | Does not prove |
|
|
7
|
+
| --- | --- | --- |
|
|
8
|
+
| Runtime tests | Exercised observable behavior | Compilation or preserved inference |
|
|
9
|
+
| Compile production and tests | Compatibility with configured types/options | All consumer guarantees or runtime support |
|
|
10
|
+
| Consumer type tests | Significant valid/forbidden uses and inference | Validation of network input or runtime immutability |
|
|
11
|
+
|
|
12
|
+
Protect meaningful literals/inference, const generics, discriminated unions, exhaustivity,
|
|
13
|
+
narrowing, overloads, brands and optionality. Use positive counterparts for negative cases.
|
|
14
|
+
Keep invalid static calls in checker-only files. For `@ts-expect-error`, give a concise why
|
|
15
|
+
and verify the intended diagnostic without the directive in an isolated probe; a typo or
|
|
16
|
+
missing import can otherwise satisfy the directive. Do not run invalid static-only calls
|
|
17
|
+
as runtime tests. An unused directive must fail the checker.
|
|
18
|
+
|
|
19
|
+
Prefer typed factories and structural doubles. Do not reach for `satisfies` unless the
|
|
20
|
+
installed compiler already supports it and a typed factory is not enough. Avoid
|
|
21
|
+
`any`, `as unknown as` or suppressions used to conceal an invalid contract.
|
|
22
|
+
Construct malformed inputs at `unknown`, where validation belongs. A brand does not validate an
|
|
23
|
+
external string and `readonly` does not freeze or defensively copy an object.
|
|
24
|
+
|
|
25
|
+
Ordinary runtime matchers do not necessarily narrow types. Use a genuinely typed assertion
|
|
26
|
+
such as a supported `expect.assert` or a small `asserts` function when later code needs
|
|
27
|
+
narrowing and the compiler profile supports it; do not hide the issue with `!`.
|
|
28
|
+
|
|
29
|
+
Where observable, test Map/Set key identity, duplicate policy and promised iteration order;
|
|
30
|
+
test partial generator consumption and closure without prescribing their private data
|
|
31
|
+
structure. The modern-typescript dimension owns the implementation idiom choice.
|
|
32
|
+
|
|
33
|
+
Vitest runtime transforms do not typecheck by default; `expectTypeOf` is not a runtime
|
|
34
|
+
type proof. Check the installed runner's type-test command or run a dedicated compiler
|
|
35
|
+
project including production, runtime tests and separate consumer cases. Inspect included
|
|
36
|
+
files. TypeScript 7's native compiler and tools depending on the TypeScript 6 programmatic
|
|
37
|
+
API can require different compatible configurations. Never force an upgrade from a
|
|
38
|
+
qualification fixture's version.
|
|
39
|
+
|
|
40
|
+
Sources: [Vitest type testing](https://vitest.dev/guide/testing-types),
|
|
41
|
+
[narrowing](https://vitest.dev/guide/recipes/type-narrowing),
|
|
42
|
+
[TypeScript 7](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/).
|