@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,190 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/hellraisercenobit/skills/blob/main/contracts/schemas/declaration.schema.json",
4
+ "title": "Dimension declaration 1.0.0",
5
+ "description": "One per registered dimension per task, written through `declare` before any decision record. It states whether the dimension applies, on which paths, for which request and under which constraints. A non-applicable dimension has a declaration and nothing else.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "document",
10
+ "documentVersion",
11
+ "dimension",
12
+ "applicability",
13
+ "reason",
14
+ "request",
15
+ "constraints",
16
+ "revision"
17
+ ],
18
+ "properties": {
19
+ "document": {
20
+ "const": "declaration"
21
+ },
22
+ "documentVersion": {
23
+ "const": "1.0.0"
24
+ },
25
+ "dimension": {
26
+ "description": "A dimension identifier the member manifest registers.",
27
+ "type": "string",
28
+ "minLength": 1
29
+ },
30
+ "applicability": {
31
+ "enum": [
32
+ "applicable",
33
+ "non-applicable"
34
+ ]
35
+ },
36
+ "reason": {
37
+ "description": "Why the dimension applies, or why it does not. Never empty: skipping a dimension is a recorded decision.",
38
+ "type": "string",
39
+ "minLength": 1
40
+ },
41
+ "request": {
42
+ "description": "The requester's own wording, without builder choices or rationale. The neutral brief is rendered from it.",
43
+ "type": "string",
44
+ "minLength": 1
45
+ },
46
+ "constraints": {
47
+ "description": "Factual constraints only: project targets, public contracts, independent sources. When tests are TypeScript, name the ES/compiler target as a factual string (example: compiler: TypeScript 4.0.5, target ES2015, lib es2015, strict off). A tsconfig path in scope.configuration is not a substitute. PHP and other non-TypeScript suites omit this constraint rather than invent one.",
48
+ "type": "array",
49
+ "items": {
50
+ "type": "string",
51
+ "minLength": 1
52
+ }
53
+ },
54
+ "base": {
55
+ "$ref": "#/$defs/base"
56
+ },
57
+ "scope": {
58
+ "$ref": "#/$defs/scope"
59
+ },
60
+ "revision": {
61
+ "$ref": "#/$defs/revision"
62
+ }
63
+ },
64
+ "$defs": {
65
+ "base": {
66
+ "description": "The comparison base. Required when the dimension applies; the change set is the diff from its merge-base with HEAD.",
67
+ "type": "string",
68
+ "minLength": 1
69
+ },
70
+ "scope": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": [
74
+ "paths"
75
+ ],
76
+ "properties": {
77
+ "paths": {
78
+ "description": "Repository-relative file paths or directory prefixes the dimension protects.",
79
+ "type": "array",
80
+ "minItems": 1,
81
+ "uniqueItems": true,
82
+ "items": {
83
+ "type": "string",
84
+ "minLength": 1
85
+ }
86
+ },
87
+ "configuration": {
88
+ "description": "Repository-relative configuration files the decisions depend on. They enter the source fingerprint.",
89
+ "type": "array",
90
+ "uniqueItems": true,
91
+ "items": {
92
+ "type": "string",
93
+ "minLength": 1
94
+ }
95
+ }
96
+ }
97
+ },
98
+ "revision": {
99
+ "description": "Same shape as a decision record's revision: revision 1 has no previous, a later one names it.",
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": [
103
+ "number",
104
+ "previous",
105
+ "reason"
106
+ ],
107
+ "properties": {
108
+ "number": {
109
+ "type": "integer",
110
+ "minimum": 1
111
+ },
112
+ "previous": {
113
+ "type": [
114
+ "string",
115
+ "null"
116
+ ],
117
+ "minLength": 1
118
+ },
119
+ "reason": {
120
+ "type": "string",
121
+ "minLength": 1
122
+ }
123
+ },
124
+ "allOf": [
125
+ {
126
+ "if": {
127
+ "properties": {
128
+ "number": {
129
+ "type": "integer",
130
+ "minimum": 2
131
+ }
132
+ },
133
+ "required": [
134
+ "number"
135
+ ]
136
+ },
137
+ "then": {
138
+ "properties": {
139
+ "previous": {
140
+ "type": "string",
141
+ "minLength": 1
142
+ }
143
+ }
144
+ },
145
+ "else": {
146
+ "properties": {
147
+ "previous": {
148
+ "type": "null"
149
+ }
150
+ }
151
+ }
152
+ }
153
+ ]
154
+ }
155
+ },
156
+ "allOf": [
157
+ {
158
+ "if": {
159
+ "properties": {
160
+ "applicability": {
161
+ "const": "applicable"
162
+ }
163
+ },
164
+ "required": [
165
+ "applicability"
166
+ ]
167
+ },
168
+ "then": {
169
+ "required": [
170
+ "scope",
171
+ "base"
172
+ ],
173
+ "properties": {
174
+ "scope": {
175
+ "$ref": "#/$defs/scope"
176
+ },
177
+ "base": {
178
+ "$ref": "#/$defs/base"
179
+ }
180
+ }
181
+ },
182
+ "else": {
183
+ "properties": {
184
+ "scope": false,
185
+ "base": false
186
+ }
187
+ }
188
+ }
189
+ ]
190
+ }
@@ -0,0 +1,98 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ export function inspectProject(root) {
5
+ const evidence = { npmPackages: {}, composerPackages: {} };
6
+ const pkgPath = join(root, 'package.json');
7
+ if (existsSync(pkgPath)) {
8
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
9
+ Object.assign(evidence.npmPackages, pkg.dependencies ?? {}, pkg.devDependencies ?? {});
10
+ evidence.npmScripts = pkg.scripts;
11
+ }
12
+ const composerPath = join(root, 'composer.json');
13
+ if (existsSync(composerPath)) {
14
+ const composer = JSON.parse(readFileSync(composerPath, 'utf8'));
15
+ Object.assign(evidence.composerPackages, composer.require ?? {}, composer['require-dev'] ?? {});
16
+ }
17
+ evidence.hasCodeceptionConfig = existsSync(join(root, 'codeception.yml'));
18
+ evidence.hasKarmaConfig = ['karma.conf.js', 'karma.conf.ts'].some(name => existsSync(join(root, name)));
19
+ evidence.hasAngularProject = existsSync(join(root, 'angular.json'))
20
+ || Boolean(evidence.npmPackages['@angular/core']);
21
+ return detectTestingAdapter(evidence);
22
+ }
23
+
24
+ export function detectTestingAdapter(evidence) {
25
+ const codeceptionVersion = evidence?.composerPackages?.['codeception/codeception'];
26
+ if (codeceptionVersion) {
27
+ const major = packageMajor(codeceptionVersion);
28
+ const known = major === 4 || major === 5;
29
+ const profile = { runner: 'codeception', version: codeceptionVersion };
30
+ if (evidence.hasCodeceptionConfig !== undefined) {
31
+ profile.hasConfig = evidence.hasCodeceptionConfig;
32
+ }
33
+ if (!known) {
34
+ profile.unknowns = ['codeception-major'];
35
+ }
36
+ return {
37
+ family: 'codeception',
38
+ adapter: 'transpose-codeception.md',
39
+ complete: known,
40
+ profile,
41
+ };
42
+ }
43
+ const npmPackages = evidence.npmPackages ?? {};
44
+ if (
45
+ evidence.hasKarmaConfig &&
46
+ evidence.hasAngularProject &&
47
+ npmPackages.karma &&
48
+ npmPackages['jasmine-core'] &&
49
+ npmPackages['@angular/core']
50
+ ) {
51
+ const profile = {
52
+ angular: npmPackages['@angular/core'],
53
+ karma: npmPackages.karma,
54
+ jasmineCore: npmPackages['jasmine-core'],
55
+ };
56
+ if (npmPackages.typescript) {
57
+ profile.typescript = npmPackages.typescript;
58
+ }
59
+ const unknowns = [];
60
+ if (packageMajor(profile.angular) !== 10 && packageMajor(profile.angular) !== 11) {
61
+ unknowns.push('angular-major');
62
+ }
63
+ if (packageMajor(profile.karma) !== 6) {
64
+ unknowns.push('karma-major');
65
+ }
66
+ if (packageMajor(profile.jasmineCore) !== 3) {
67
+ unknowns.push('jasmine-major');
68
+ }
69
+ if (unknowns.length > 0) {
70
+ profile.unknowns = unknowns;
71
+ }
72
+ return {
73
+ family: 'karma-jasmine-angular',
74
+ adapter: 'transpose-karma-jasmine-angular.md',
75
+ complete: unknowns.length === 0,
76
+ profile,
77
+ };
78
+ }
79
+ if (npmPackages.vitest) {
80
+ return {
81
+ family: 'vitest',
82
+ adapter: 'transpose-vitest.md',
83
+ complete: true,
84
+ profile: { vitest: npmPackages.vitest },
85
+ };
86
+ }
87
+ return {
88
+ family: 'unknown',
89
+ adapter: null,
90
+ complete: false,
91
+ profile: {},
92
+ };
93
+ }
94
+
95
+ function packageMajor(version) {
96
+ const match = String(version).match(/\d+/);
97
+ return match ? Number(match[0]) : undefined;
98
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/hellraisercenobit/skills/blob/main/contracts/schemas/dispute.schema.json",
4
+ "title": "Dispute 1.0.0",
5
+ "description": "The builder's second and only other response to a finding, beside addressing it. It contests one finding with a pointer to counter-evidence that already exists; a dispute without such a pointer is refused. It goes to the user and its only exit is an arbitration.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "document",
10
+ "documentVersion",
11
+ "dimension",
12
+ "report",
13
+ "finding",
14
+ "counterEvidence",
15
+ "position"
16
+ ],
17
+ "properties": {
18
+ "document": {
19
+ "const": "dispute"
20
+ },
21
+ "documentVersion": {
22
+ "const": "1.0.0"
23
+ },
24
+ "dimension": {
25
+ "type": "string",
26
+ "minLength": 1
27
+ },
28
+ "report": {
29
+ "description": "The identifier of the report that carries the contested finding.",
30
+ "type": "string",
31
+ "minLength": 1
32
+ },
33
+ "finding": {
34
+ "description": "The contested finding's identifier.",
35
+ "type": "string",
36
+ "minLength": 1
37
+ },
38
+ "counterEvidence": {
39
+ "description": "Pointers to artifacts that exist now. Each path is checked; a dangling pointer refuses the dispute.",
40
+ "type": "array",
41
+ "minItems": 1,
42
+ "items": {
43
+ "type": "object",
44
+ "additionalProperties": false,
45
+ "required": [
46
+ "path",
47
+ "claim"
48
+ ],
49
+ "properties": {
50
+ "path": {
51
+ "type": "string",
52
+ "minLength": 1
53
+ },
54
+ "claim": {
55
+ "type": "string",
56
+ "minLength": 1
57
+ }
58
+ }
59
+ }
60
+ },
61
+ "position": {
62
+ "description": "The builder's position in one sentence.",
63
+ "type": "string",
64
+ "minLength": 1
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,45 @@
1
+ # Doubles, data and isolation
2
+
3
+ Applies TP-03/04/08/09/10/11. First ask whether the real collaborator is cheap,
4
+ deterministic and part of the behavior. If so, a sociable test often preserves more meaning.
5
+ Isolate a concrete boundary or diagnostic problem, not every object in a constructor.
6
+
7
+ **The principle: the least synthetic collaborator that keeps the test deterministic, fast
8
+ enough and focused on the behavior.** Least synthetic means closest to what runs in
9
+ production - the real object, then a fake with the real contract, then a spy, then a mock with
10
+ expectations. It is a direction, not a ranking to apply mechanically: the three conditions
11
+ decide, and a real collaborator that makes the test slow, flaky or about something else loses
12
+ to a double. Automatic mocking of every constructor argument answers none of the three
13
+ conditions and replaces the forces with a habit. Nothing here overrides the axes: the level, the
14
+ seam, the double and the data are separate decisions, and a test pyramid is not one of them.
15
+
16
+ | Need | Candidate | Cost or alternative |
17
+ | --- | --- | --- |
18
+ | Controlled input | Stub function or typed literal | Never stub the policy being claimed as tested |
19
+ | Observable boundary effect | Spy, typed `vi.fn` or message journal | Assert content; count/order only when contractual |
20
+ | Stateful boundary behavior | Fake | Run applicable contracts on the actual adapter; disclose fidelity limits |
21
+ | Required collaboration protocol | Mock expectations | Internal call sequences can make refactors expensive |
22
+ | Simple fresh valid input | Inline data or factory | Defaults must not conceal the decisive value |
23
+ | Named reusable business case | Object mother using a factory | Avoid combinatorial catalogs and shared mutable objects |
24
+ | Meaningful construction/history | Builder using legitimate operations | No two-argument threshold or forced fluent API |
25
+ | Resource lifetime | Fixture/context or hook | Explicit owner, scope and cleanup, including failure |
26
+
27
+ `vi.fn` can act as stub or spy; its syntax does not make it a strict mock. Compare typed
28
+ functions, object literals and classes for clarity. `satisfies` checks a double without
29
+ widening its useful inferred shape. Do not coerce a partial object into a full dependency
30
+ with `as unknown as`. A narrow production port must express a genuine consumer contract.
31
+
32
+ Expose controls needed by the scenario, including an adjustable clock. Assert through
33
+ public observations. Builders must not seed private fields or bypass aggregate invariants.
34
+ Helper tests are appropriate when helpers have meaningful behavior, but they do not
35
+ qualify product policy. A fake cannot be the sole implementation of an untested business rule.
36
+
37
+ Shared contract checks name the guarantee and execute the same applicable scenarios on
38
+ fake and real adapter with fresh resources. File persistence is real infrastructure for a
39
+ file port; a second in-memory implementation is not. Persistence, concurrency, transactions,
40
+ errors and provider semantics need separate evidence when claimed. Do not require a
41
+ contract with an implementation that does not exist.
42
+
43
+ Testing can reveal the need to control an effect. Reuse an existing seam first. Ask the
44
+ design dimension to decide an architectural extraction only when the force warrants it;
45
+ do not add a test-only public getter or a full hexagonal architecture by default.
@@ -0,0 +1,72 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/hellraisercenobit/skills/blob/main/contracts/schemas/evidence-append.schema.json",
4
+ "title": "Evidence append 1.0.0",
5
+ "description": "Append-only. Journal events, check outputs, snapshots and any artifact a record planned are filed through `evidence append`, never written into the gate's index by hand. The gate stamps every append with the content hashes of the record's planned artifacts, by role, so an event proves the state of test and production artifacts at the moment it was filed.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "document",
10
+ "documentVersion",
11
+ "dimension",
12
+ "record",
13
+ "kind",
14
+ "payload"
15
+ ],
16
+ "properties": {
17
+ "document": {
18
+ "const": "evidence-append"
19
+ },
20
+ "documentVersion": {
21
+ "const": "1.0.0"
22
+ },
23
+ "dimension": {
24
+ "type": "string",
25
+ "minLength": 1
26
+ },
27
+ "record": {
28
+ "description": "The decision record this evidence belongs to.",
29
+ "type": "string",
30
+ "minLength": 1
31
+ },
32
+ "kind": {
33
+ "description": "A kind the member's evidence schemas name, which then validates the payload, or one of the generic kinds.",
34
+ "type": "string",
35
+ "minLength": 1
36
+ },
37
+ "produces": {
38
+ "description": "The planned artifact this append produces or extends. A planned artifact is satisfied by a file in the worktree or by an append that names it here.",
39
+ "type": "string",
40
+ "minLength": 1
41
+ },
42
+ "payload": {
43
+ "description": "Opaque to the envelope. Validated against the member's evidence schema when its kind names one."
44
+ },
45
+ "filedAt": {
46
+ "description": "Stamped by the gate when the append is stored.",
47
+ "type": "string",
48
+ "minLength": 1
49
+ },
50
+ "artifactHashes": {
51
+ "description": "Stamped by the gate: the content hash of every artifact the record planned, grouped by role, at the moment of the append.",
52
+ "type": "object",
53
+ "additionalProperties": {
54
+ "type": "object",
55
+ "additionalProperties": {
56
+ "type": [
57
+ "string",
58
+ "null"
59
+ ]
60
+ }
61
+ }
62
+ },
63
+ "builder": {
64
+ "description": "Stamped by the gate: the identity it captured for the caller.",
65
+ "type": "object"
66
+ },
67
+ "replayed": {
68
+ "description": "Stamped by the gate: `true` only when the gate itself ran the scenario through `replay`.",
69
+ "type": "boolean"
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,115 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/hellraisercenobit/skills/blob/main/skills/engineering/transpose-testing-patterns/references/journal-event.schema.json",
4
+ "title": "Testing patterns journal event 1.0.0",
5
+ "description": "One event of the append-only journal, filed through `evidence append --kind journal-event`. The event says what was run and what happened; the artifact hashes that make it provable are stamped by the gate, by role, and are not writable here. A replay is marked by the gate, never by the builder.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "record",
10
+ "scenario",
11
+ "phase",
12
+ "command",
13
+ "exitCode",
14
+ "output"
15
+ ],
16
+ "properties": {
17
+ "record": {
18
+ "description": "The decision record this cycle belongs to.",
19
+ "type": "string",
20
+ "minLength": 1
21
+ },
22
+ "scenario": {
23
+ "description": "The scenario identifier the record's sites map to.",
24
+ "type": "string",
25
+ "minLength": 1
26
+ },
27
+ "phase": {
28
+ "enum": [
29
+ "red",
30
+ "green",
31
+ "refactor"
32
+ ]
33
+ },
34
+ "command": {
35
+ "description": "The command as run, so it can be run again.",
36
+ "type": "string",
37
+ "minLength": 1
38
+ },
39
+ "exitCode": {
40
+ "type": "integer"
41
+ },
42
+ "cause": {
43
+ "description": "What the run reported, quoted from the tool. Required on a red event.",
44
+ "type": "string",
45
+ "minLength": 1
46
+ },
47
+ "failureClass": {
48
+ "description": "Required on a red event. `expected-behavior-missing` is the only class a TDD cycle's red is made of: the behavior is absent. `assertion-mismatch` says the behavior exists and disagrees. `setup-error` is setup work, not red.",
49
+ "enum": [
50
+ "expected-behavior-missing",
51
+ "assertion-mismatch",
52
+ "setup-error"
53
+ ]
54
+ },
55
+ "output": {
56
+ "description": "The captured output of the actual tool, as a path under the task's evidence or in the worktree.",
57
+ "type": "string",
58
+ "minLength": 1
59
+ },
60
+ "state": {
61
+ "description": "An inspectable snapshot or a resolvable immutable ref for this phase.",
62
+ "type": "string",
63
+ "minLength": 1
64
+ },
65
+ "tests": {
66
+ "description": "Executed test identities for this scenario, so a claim of coverage maps to real tests.",
67
+ "type": "array",
68
+ "items": {
69
+ "type": "string",
70
+ "minLength": 1
71
+ }
72
+ },
73
+ "skipped": {
74
+ "description": "Skips, todos, expected failures and retries observed in this run.",
75
+ "type": "array",
76
+ "items": {
77
+ "type": "string",
78
+ "minLength": 1
79
+ }
80
+ }
81
+ },
82
+ "allOf": [
83
+ {
84
+ "if": {
85
+ "properties": {
86
+ "phase": {
87
+ "const": "red"
88
+ }
89
+ },
90
+ "required": [
91
+ "phase"
92
+ ]
93
+ },
94
+ "then": {
95
+ "required": [
96
+ "cause",
97
+ "failureClass"
98
+ ],
99
+ "properties": {
100
+ "cause": {
101
+ "type": "string",
102
+ "minLength": 1
103
+ },
104
+ "failureClass": {
105
+ "enum": [
106
+ "expected-behavior-missing",
107
+ "assertion-mismatch",
108
+ "setup-error"
109
+ ]
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ]
115
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/hellraisercenobit/skills/blob/main/contracts/schemas/marker.schema.json",
4
+ "title": "Suite marker 1.0.0",
5
+ "description": "Committed at the repository root as `.ai-engineering-suite.json`. Its presence is the project's opt-in and the only signal enforcement reads: without it every gate command allows and prints nothing that blocks.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "markerVersion",
10
+ "dimensions"
11
+ ],
12
+ "properties": {
13
+ "markerVersion": {
14
+ "const": "1.0.0"
15
+ },
16
+ "dimensions": {
17
+ "description": "`all` registers every member of the manifest; a list registers exactly those dimension identifiers.",
18
+ "oneOf": [
19
+ {
20
+ "const": "all"
21
+ },
22
+ {
23
+ "type": "array",
24
+ "minItems": 1,
25
+ "uniqueItems": true,
26
+ "items": {
27
+ "type": "string",
28
+ "minLength": 1
29
+ }
30
+ }
31
+ ]
32
+ },
33
+ "evidenceRoot": {
34
+ "description": "Overrides the default evidence root. `~` expands to the user's home directory. A relative path resolves against the repository root, which the change set then excludes.",
35
+ "type": "string",
36
+ "minLength": 1
37
+ },
38
+ "exportDirectory": {
39
+ "description": "Repository-relative directory `export` writes to. Excluded from the change set and from every fingerprint.",
40
+ "type": "string",
41
+ "minLength": 1
42
+ },
43
+ "ignore": {
44
+ "description": "Repository-relative glob patterns removed from the change set. `*` matches within one segment, `**` across segments.",
45
+ "type": "array",
46
+ "items": {
47
+ "type": "string",
48
+ "minLength": 1
49
+ }
50
+ },
51
+ "base": {
52
+ "description": "Default comparison base when a declaration names none.",
53
+ "type": "string",
54
+ "minLength": 1
55
+ },
56
+ "conflictRoundCap": {
57
+ "description": "Consecutive cross-dimension conflict rounds before `can-review` is refused with `arbitration-required`.",
58
+ "type": "integer",
59
+ "minimum": 1
60
+ },
61
+ "roundCap": {
62
+ "description": "Total review rounds for one task before completion ends with `round-cap-reached`.",
63
+ "type": "integer",
64
+ "minimum": 1
65
+ },
66
+ "allowReplay": {
67
+ "description": "`false` forbids the gate-executed replay remedy, leaving a rerun of a full cycle as the only remedy for chronology-bound evidence.",
68
+ "type": "boolean"
69
+ },
70
+ "requireVerifiedIdentity": {
71
+ "description": "`true` refuses an attestation stored `identity-unverified`, for harnesses that provide agent identifiers.",
72
+ "type": "boolean"
73
+ }
74
+ }
75
+ }