@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.
Files changed (100) hide show
  1. package/README.md +82 -0
  2. package/agents/design-pattern-reviewer.md +40 -0
  3. package/agents/modern-typescript-reviewer.md +24 -0
  4. package/agents/testing-pattern-reviewer.md +23 -0
  5. package/bin/ai-engineering-gate.mjs +6 -0
  6. package/contracts/axi/axi-standard.md +273 -0
  7. package/contracts/axi/pin.json +36 -0
  8. package/contracts/members.json +58 -0
  9. package/contracts/schemas/arbitration.schema.json +45 -0
  10. package/contracts/schemas/decision-envelope.schema.json +215 -0
  11. package/contracts/schemas/declaration.schema.json +190 -0
  12. package/contracts/schemas/dispute.schema.json +67 -0
  13. package/contracts/schemas/evidence-append.schema.json +72 -0
  14. package/contracts/schemas/gate-output.schema.json +296 -0
  15. package/contracts/schemas/marker.schema.json +75 -0
  16. package/contracts/schemas/review-envelope.schema.json +378 -0
  17. package/contracts/schemas/verdict-record.schema.json +191 -0
  18. package/contracts/suite-contract.md +270 -0
  19. package/dist/ai-engineering-gate.mjs +2762 -0
  20. package/package.json +47 -0
  21. package/skills/engineering/review-design-patterns/LICENSE +6 -0
  22. package/skills/engineering/review-design-patterns/SKILL.md +196 -0
  23. package/skills/engineering/review-design-patterns/agents/openai.yaml +3 -0
  24. package/skills/engineering/review-design-patterns/references/smell-signatures.md +117 -0
  25. package/skills/engineering/review-design-patterns/review-design-patterns.yaml +25 -0
  26. package/skills/engineering/review-modern-typescript/LICENSE +21 -0
  27. package/skills/engineering/review-modern-typescript/SKILL.md +88 -0
  28. package/skills/engineering/review-modern-typescript/agents/openai.yaml +3 -0
  29. package/skills/engineering/review-modern-typescript/references/smell-signatures.md +36 -0
  30. package/skills/engineering/review-modern-typescript/review-modern-typescript.yaml +22 -0
  31. package/skills/engineering/review-testing-patterns/SKILL.md +108 -0
  32. package/skills/engineering/review-testing-patterns/agents/openai.yaml +4 -0
  33. package/skills/engineering/review-testing-patterns/references/compiler-profile.mjs +103 -0
  34. package/skills/engineering/review-testing-patterns/references/smell-signatures.md +30 -0
  35. package/skills/engineering/review-testing-patterns/review-testing-patterns.yaml +23 -0
  36. package/skills/engineering/transpose-design-patterns/LICENSE +6 -0
  37. package/skills/engineering/transpose-design-patterns/SKILL.md +231 -0
  38. package/skills/engineering/transpose-design-patterns/agents/openai.yaml +3 -0
  39. package/skills/engineering/transpose-design-patterns/references/arbitration.schema.json +45 -0
  40. package/skills/engineering/transpose-design-patterns/references/decision-envelope.schema.json +215 -0
  41. package/skills/engineering/transpose-design-patterns/references/declaration.schema.json +190 -0
  42. package/skills/engineering/transpose-design-patterns/references/design-decision-record.schema.json +731 -0
  43. package/skills/engineering/transpose-design-patterns/references/dispute.schema.json +67 -0
  44. package/skills/engineering/transpose-design-patterns/references/evidence-append.schema.json +72 -0
  45. package/skills/engineering/transpose-design-patterns/references/marker.schema.json +75 -0
  46. package/skills/engineering/transpose-design-patterns/references/pattern-catalog.md +305 -0
  47. package/skills/engineering/transpose-design-patterns/references/record.example.json +120 -0
  48. package/skills/engineering/transpose-design-patterns/references/review-envelope.schema.json +378 -0
  49. package/skills/engineering/transpose-design-patterns/references/suite-contract.md +270 -0
  50. package/skills/engineering/transpose-design-patterns/references/transpose-angular.md +224 -0
  51. package/skills/engineering/transpose-design-patterns/references/transpose-php.md +561 -0
  52. package/skills/engineering/transpose-design-patterns/references/transpose-quarkus.md +283 -0
  53. package/skills/engineering/transpose-design-patterns/references/transpose-react.md +256 -0
  54. package/skills/engineering/transpose-design-patterns/references/transpose-vanilla.md +204 -0
  55. package/skills/engineering/transpose-design-patterns/references/transpose-vue.md +234 -0
  56. package/skills/engineering/transpose-design-patterns/transpose-design-patterns.yaml +24 -0
  57. package/skills/engineering/transpose-modern-typescript/LICENSE +21 -0
  58. package/skills/engineering/transpose-modern-typescript/SKILL.md +90 -0
  59. package/skills/engineering/transpose-modern-typescript/agents/openai.yaml +3 -0
  60. package/skills/engineering/transpose-modern-typescript/references/arbitration.schema.json +45 -0
  61. package/skills/engineering/transpose-modern-typescript/references/catalog.md +38 -0
  62. package/skills/engineering/transpose-modern-typescript/references/collections.md +50 -0
  63. package/skills/engineering/transpose-modern-typescript/references/compatibility.md +61 -0
  64. package/skills/engineering/transpose-modern-typescript/references/decision-envelope.schema.json +215 -0
  65. package/skills/engineering/transpose-modern-typescript/references/decision-record.schema.json +830 -0
  66. package/skills/engineering/transpose-modern-typescript/references/declaration.schema.json +190 -0
  67. package/skills/engineering/transpose-modern-typescript/references/dispute.schema.json +67 -0
  68. package/skills/engineering/transpose-modern-typescript/references/evidence-append.schema.json +72 -0
  69. package/skills/engineering/transpose-modern-typescript/references/idioms.md +74 -0
  70. package/skills/engineering/transpose-modern-typescript/references/marker.schema.json +75 -0
  71. package/skills/engineering/transpose-modern-typescript/references/platform.md +147 -0
  72. package/skills/engineering/transpose-modern-typescript/references/record.example.json +172 -0
  73. package/skills/engineering/transpose-modern-typescript/references/record.md +37 -0
  74. package/skills/engineering/transpose-modern-typescript/references/review-envelope.schema.json +378 -0
  75. package/skills/engineering/transpose-modern-typescript/references/suite-contract.md +270 -0
  76. package/skills/engineering/transpose-modern-typescript/references/types.md +97 -0
  77. package/skills/engineering/transpose-modern-typescript/transpose-modern-typescript.yaml +22 -0
  78. package/skills/engineering/transpose-testing-patterns/SKILL.md +96 -0
  79. package/skills/engineering/transpose-testing-patterns/agents/openai.yaml +4 -0
  80. package/skills/engineering/transpose-testing-patterns/references/arbitration.schema.json +45 -0
  81. package/skills/engineering/transpose-testing-patterns/references/catalog.md +218 -0
  82. package/skills/engineering/transpose-testing-patterns/references/decision-envelope.schema.json +215 -0
  83. package/skills/engineering/transpose-testing-patterns/references/decision-record.schema.json +857 -0
  84. package/skills/engineering/transpose-testing-patterns/references/declaration.schema.json +190 -0
  85. package/skills/engineering/transpose-testing-patterns/references/detect-adapter.mjs +98 -0
  86. package/skills/engineering/transpose-testing-patterns/references/dispute.schema.json +67 -0
  87. package/skills/engineering/transpose-testing-patterns/references/doubles-data.md +45 -0
  88. package/skills/engineering/transpose-testing-patterns/references/evidence-append.schema.json +72 -0
  89. package/skills/engineering/transpose-testing-patterns/references/journal-event.schema.json +115 -0
  90. package/skills/engineering/transpose-testing-patterns/references/marker.schema.json +75 -0
  91. package/skills/engineering/transpose-testing-patterns/references/record.example.json +230 -0
  92. package/skills/engineering/transpose-testing-patterns/references/record.md +25 -0
  93. package/skills/engineering/transpose-testing-patterns/references/review-envelope.schema.json +378 -0
  94. package/skills/engineering/transpose-testing-patterns/references/suite-contract.md +270 -0
  95. package/skills/engineering/transpose-testing-patterns/references/tdd.md +62 -0
  96. package/skills/engineering/transpose-testing-patterns/references/transpose-codeception.md +84 -0
  97. package/skills/engineering/transpose-testing-patterns/references/transpose-karma-jasmine-angular.md +73 -0
  98. package/skills/engineering/transpose-testing-patterns/references/transpose-vitest.md +111 -0
  99. package/skills/engineering/transpose-testing-patterns/references/typescript.md +42 -0
  100. 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.
@@ -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/).