@fro.bot/systematic 3.12.4 → 3.13.1
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/ATTRIBUTIONS.md +2 -2
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +324 -2
- package/dist/{index-h26p98ny.js → index-0stf3ag0.js} +948 -948
- package/dist/index.js +1 -1
- package/dist/lib/review-artifact-schema.d.ts +239 -0
- package/package.json +9 -6
- package/skills/ce-compound/references/yaml-schema.md +18 -1
- package/skills/ce-review/SKILL.md +1 -0
- package/skills/ce-review/references/review-summary-schema.json +517 -0
- package/skills/ce-review/references/synthesis-artifact-contract.md +40 -0
package/dist/index.js
CHANGED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const REVIEW_ARTIFACT_CUSTOM_MESSAGES: readonly ['severity count must match rejected finding count', 'filtered findings require a validation reason'];
|
|
3
|
+
export declare const DispatchOutcomeSchema: z.ZodEnum<{
|
|
4
|
+
empty: "empty";
|
|
5
|
+
findings: "findings";
|
|
6
|
+
malformed: "malformed";
|
|
7
|
+
never_returned: "never_returned";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const DispositionSchema: z.ZodEnum<{
|
|
10
|
+
filtered: "filtered";
|
|
11
|
+
merged: "merged";
|
|
12
|
+
rejected: "rejected";
|
|
13
|
+
suppressed: "suppressed";
|
|
14
|
+
surviving: "surviving";
|
|
15
|
+
}>;
|
|
16
|
+
export declare const HarnessSchema: z.ZodEnum<{
|
|
17
|
+
"claude-code": "claude-code";
|
|
18
|
+
opencode: "opencode";
|
|
19
|
+
pi: "pi";
|
|
20
|
+
}>;
|
|
21
|
+
export declare const RepoRelativePathSchema: z.ZodString;
|
|
22
|
+
export declare const InputFindingSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
record_type: z.ZodLiteral<"admitted">;
|
|
24
|
+
input_id: z.ZodString;
|
|
25
|
+
reviewer: z.ZodString;
|
|
26
|
+
confidence: z.ZodNumber;
|
|
27
|
+
disposition: z.ZodEnum<{
|
|
28
|
+
filtered: "filtered";
|
|
29
|
+
merged: "merged";
|
|
30
|
+
suppressed: "suppressed";
|
|
31
|
+
surviving: "surviving";
|
|
32
|
+
}>;
|
|
33
|
+
reason: z.ZodString;
|
|
34
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
35
|
+
record_type: z.ZodLiteral<"rejected_summary">;
|
|
36
|
+
reviewer: z.ZodString;
|
|
37
|
+
dispatch_outcome: z.ZodEnum<{
|
|
38
|
+
empty: "empty";
|
|
39
|
+
findings: "findings";
|
|
40
|
+
malformed: "malformed";
|
|
41
|
+
never_returned: "never_returned";
|
|
42
|
+
}>;
|
|
43
|
+
rejected_finding_count: z.ZodNumber;
|
|
44
|
+
rejected_severities: z.ZodArray<z.ZodEnum<{
|
|
45
|
+
P0: "P0";
|
|
46
|
+
P1: "P1";
|
|
47
|
+
P2: "P2";
|
|
48
|
+
P3: "P3";
|
|
49
|
+
unknown: "unknown";
|
|
50
|
+
}>>;
|
|
51
|
+
disposition: z.ZodEnum<{
|
|
52
|
+
rejected: "rejected";
|
|
53
|
+
}>;
|
|
54
|
+
reason: z.ZodString;
|
|
55
|
+
}, z.core.$strict>], "record_type">;
|
|
56
|
+
declare const SynthesizedFindingFieldsSchema: z.ZodObject<{
|
|
57
|
+
title: z.ZodString;
|
|
58
|
+
severity: z.ZodEnum<{
|
|
59
|
+
P0: "P0";
|
|
60
|
+
P1: "P1";
|
|
61
|
+
P2: "P2";
|
|
62
|
+
P3: "P3";
|
|
63
|
+
}>;
|
|
64
|
+
file: z.ZodString;
|
|
65
|
+
line: z.ZodNumber;
|
|
66
|
+
why_it_matters: z.ZodString;
|
|
67
|
+
autofix_class: z.ZodEnum<{
|
|
68
|
+
advisory: "advisory";
|
|
69
|
+
gated_auto: "gated_auto";
|
|
70
|
+
manual: "manual";
|
|
71
|
+
safe_auto: "safe_auto";
|
|
72
|
+
}>;
|
|
73
|
+
owner: z.ZodEnum<{
|
|
74
|
+
"downstream-resolver": "downstream-resolver";
|
|
75
|
+
human: "human";
|
|
76
|
+
release: "release";
|
|
77
|
+
"review-fixer": "review-fixer";
|
|
78
|
+
}>;
|
|
79
|
+
requires_verification: z.ZodBoolean;
|
|
80
|
+
confidence: z.ZodNumber;
|
|
81
|
+
evidence: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
82
|
+
overflow: z.ZodLiteral<true>;
|
|
83
|
+
excerpt: z.ZodString;
|
|
84
|
+
}, z.core.$strict>]>>;
|
|
85
|
+
pre_existing: z.ZodBoolean;
|
|
86
|
+
suggested_fix: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
87
|
+
validated: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
validation_reason: z.ZodOptional<z.ZodString>;
|
|
89
|
+
input_finding_ids: z.ZodArray<z.ZodString>;
|
|
90
|
+
provenance: z.ZodObject<{
|
|
91
|
+
fingerprint: z.ZodString;
|
|
92
|
+
submitters: z.ZodArray<z.ZodString>;
|
|
93
|
+
agreement_credit: z.ZodArray<z.ZodString>;
|
|
94
|
+
}, z.core.$strict>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
type SynthesizedFindingFields = z.infer<typeof SynthesizedFindingFieldsSchema>;
|
|
97
|
+
type SynthesizedFinding = Omit<SynthesizedFindingFields, 'validated' | 'validation_reason'> & ({
|
|
98
|
+
validated: false;
|
|
99
|
+
validation_reason: string;
|
|
100
|
+
} | {
|
|
101
|
+
validated?: true;
|
|
102
|
+
validation_reason?: string;
|
|
103
|
+
});
|
|
104
|
+
export declare const ReviewArtifactSchema: z.ZodObject<{
|
|
105
|
+
schema_version: z.ZodLiteral<1>;
|
|
106
|
+
run_id: z.ZodString;
|
|
107
|
+
mode: z.ZodEnum<{
|
|
108
|
+
autofix: "autofix";
|
|
109
|
+
headless: "headless";
|
|
110
|
+
interactive: "interactive";
|
|
111
|
+
}>;
|
|
112
|
+
harness: z.ZodEnum<{
|
|
113
|
+
"claude-code": "claude-code";
|
|
114
|
+
opencode: "opencode";
|
|
115
|
+
pi: "pi";
|
|
116
|
+
}>;
|
|
117
|
+
run_status: z.ZodEnum<{
|
|
118
|
+
abnormal: "abnormal";
|
|
119
|
+
completed: "completed";
|
|
120
|
+
degraded: "degraded";
|
|
121
|
+
in_progress: "in_progress";
|
|
122
|
+
}>;
|
|
123
|
+
verdict: z.ZodString;
|
|
124
|
+
dispatches: z.ZodArray<z.ZodObject<{
|
|
125
|
+
persona: z.ZodString;
|
|
126
|
+
dispatch_outcome: z.ZodEnum<{
|
|
127
|
+
empty: "empty";
|
|
128
|
+
findings: "findings";
|
|
129
|
+
malformed: "malformed";
|
|
130
|
+
never_returned: "never_returned";
|
|
131
|
+
}>;
|
|
132
|
+
input_finding_count: z.ZodNumber;
|
|
133
|
+
rejection_reason: z.ZodOptional<z.ZodString>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
input_findings: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
136
|
+
record_type: z.ZodLiteral<"admitted">;
|
|
137
|
+
input_id: z.ZodString;
|
|
138
|
+
reviewer: z.ZodString;
|
|
139
|
+
confidence: z.ZodNumber;
|
|
140
|
+
disposition: z.ZodEnum<{
|
|
141
|
+
filtered: "filtered";
|
|
142
|
+
merged: "merged";
|
|
143
|
+
suppressed: "suppressed";
|
|
144
|
+
surviving: "surviving";
|
|
145
|
+
}>;
|
|
146
|
+
reason: z.ZodString;
|
|
147
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
148
|
+
record_type: z.ZodLiteral<"rejected_summary">;
|
|
149
|
+
reviewer: z.ZodString;
|
|
150
|
+
dispatch_outcome: z.ZodEnum<{
|
|
151
|
+
empty: "empty";
|
|
152
|
+
findings: "findings";
|
|
153
|
+
malformed: "malformed";
|
|
154
|
+
never_returned: "never_returned";
|
|
155
|
+
}>;
|
|
156
|
+
rejected_finding_count: z.ZodNumber;
|
|
157
|
+
rejected_severities: z.ZodArray<z.ZodEnum<{
|
|
158
|
+
P0: "P0";
|
|
159
|
+
P1: "P1";
|
|
160
|
+
P2: "P2";
|
|
161
|
+
P3: "P3";
|
|
162
|
+
unknown: "unknown";
|
|
163
|
+
}>>;
|
|
164
|
+
disposition: z.ZodEnum<{
|
|
165
|
+
rejected: "rejected";
|
|
166
|
+
}>;
|
|
167
|
+
reason: z.ZodString;
|
|
168
|
+
}, z.core.$strict>], "record_type">>;
|
|
169
|
+
findings: z.ZodArray<z.ZodType<SynthesizedFinding, {
|
|
170
|
+
title: string;
|
|
171
|
+
severity: "P0" | "P1" | "P2" | "P3";
|
|
172
|
+
file: string;
|
|
173
|
+
line: number;
|
|
174
|
+
why_it_matters: string;
|
|
175
|
+
autofix_class: "advisory" | "gated_auto" | "manual" | "safe_auto";
|
|
176
|
+
owner: "downstream-resolver" | "human" | "release" | "review-fixer";
|
|
177
|
+
requires_verification: boolean;
|
|
178
|
+
confidence: number;
|
|
179
|
+
evidence: (string | {
|
|
180
|
+
overflow: true;
|
|
181
|
+
excerpt: string;
|
|
182
|
+
})[];
|
|
183
|
+
pre_existing: boolean;
|
|
184
|
+
suggested_fix?: string | null | undefined;
|
|
185
|
+
validated?: boolean | undefined;
|
|
186
|
+
validation_reason?: string | undefined;
|
|
187
|
+
input_finding_ids: string[];
|
|
188
|
+
provenance: {
|
|
189
|
+
fingerprint: string;
|
|
190
|
+
submitters: string[];
|
|
191
|
+
agreement_credit: string[];
|
|
192
|
+
};
|
|
193
|
+
}, z.core.$ZodTypeInternals<SynthesizedFinding, {
|
|
194
|
+
title: string;
|
|
195
|
+
severity: "P0" | "P1" | "P2" | "P3";
|
|
196
|
+
file: string;
|
|
197
|
+
line: number;
|
|
198
|
+
why_it_matters: string;
|
|
199
|
+
autofix_class: "advisory" | "gated_auto" | "manual" | "safe_auto";
|
|
200
|
+
owner: "downstream-resolver" | "human" | "release" | "review-fixer";
|
|
201
|
+
requires_verification: boolean;
|
|
202
|
+
confidence: number;
|
|
203
|
+
evidence: (string | {
|
|
204
|
+
overflow: true;
|
|
205
|
+
excerpt: string;
|
|
206
|
+
})[];
|
|
207
|
+
pre_existing: boolean;
|
|
208
|
+
suggested_fix?: string | null | undefined;
|
|
209
|
+
validated?: boolean | undefined;
|
|
210
|
+
validation_reason?: string | undefined;
|
|
211
|
+
input_finding_ids: string[];
|
|
212
|
+
provenance: {
|
|
213
|
+
fingerprint: string;
|
|
214
|
+
submitters: string[];
|
|
215
|
+
agreement_credit: string[];
|
|
216
|
+
};
|
|
217
|
+
}>>>;
|
|
218
|
+
disposition_counts: z.ZodObject<{
|
|
219
|
+
surviving: z.ZodNumber;
|
|
220
|
+
merged: z.ZodNumber;
|
|
221
|
+
suppressed: z.ZodNumber;
|
|
222
|
+
filtered: z.ZodNumber;
|
|
223
|
+
rejected: z.ZodNumber;
|
|
224
|
+
}, z.core.$strict>;
|
|
225
|
+
applied_fixes: z.ZodArray<z.ZodString>;
|
|
226
|
+
residual_actionable_work: z.ZodArray<z.ZodString>;
|
|
227
|
+
advisory_outputs: z.ZodArray<z.ZodString>;
|
|
228
|
+
coverage: z.ZodObject<{
|
|
229
|
+
reviewers: z.ZodOptional<z.ZodNumber>;
|
|
230
|
+
validators: z.ZodOptional<z.ZodNumber>;
|
|
231
|
+
residual_risks: z.ZodArray<z.ZodString>;
|
|
232
|
+
testing_gaps: z.ZodArray<z.ZodString>;
|
|
233
|
+
failed_reviewers: z.ZodArray<z.ZodString>;
|
|
234
|
+
validator_failures: z.ZodArray<z.ZodString>;
|
|
235
|
+
intent_uncertainty: z.ZodArray<z.ZodString>;
|
|
236
|
+
}, z.core.$strict>;
|
|
237
|
+
}, z.core.$strict>;
|
|
238
|
+
export type ReviewArtifact = z.infer<typeof ReviewArtifactSchema>;
|
|
239
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fro.bot/systematic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.1",
|
|
4
4
|
"description": "Compound-engineering loops for OpenCode, Pi, and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://fro.bot/systematic",
|
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
"docs:generate": "bun docs/scripts/generate-stats.ts && bun docs/scripts/transform-content.ts && bun scripts/generate-config-schema.ts && bun docs/scripts/generate-config-reference.ts",
|
|
50
50
|
"schema:generate": "bun scripts/generate-config-schema.ts",
|
|
51
51
|
"schema:drift": "bun scripts/generate-config-schema.ts --check",
|
|
52
|
+
"review-schema:generate": "bun scripts/generate-review-artifact-schema.ts",
|
|
53
|
+
"review-schema:drift": "bun scripts/generate-review-artifact-schema.ts --check",
|
|
52
54
|
"agent-browser:build": "bun scripts/generate-agent-browser-skill.ts",
|
|
53
55
|
"agent-browser:drift": "bun scripts/generate-agent-browser-skill.ts --check",
|
|
54
56
|
"registry:build": "bun scripts/build-registry.ts",
|
|
@@ -91,7 +93,7 @@
|
|
|
91
93
|
}
|
|
92
94
|
},
|
|
93
95
|
"devDependencies": {
|
|
94
|
-
"@biomejs/biome": "2.5.
|
|
96
|
+
"@biomejs/biome": "2.5.9",
|
|
95
97
|
"@earendil-works/pi-coding-agent": "0.83.0",
|
|
96
98
|
"@opencode-ai/plugin": "1.18.18",
|
|
97
99
|
"@opencode-ai/sdk": "1.18.18",
|
|
@@ -100,15 +102,15 @@
|
|
|
100
102
|
"@types/bun": "latest",
|
|
101
103
|
"@types/js-yaml": "4.0.9",
|
|
102
104
|
"@types/node": "26.2.0",
|
|
103
|
-
"agent-browser": "0.
|
|
105
|
+
"agent-browser": "0.34.0",
|
|
104
106
|
"ajv": "8.20.0",
|
|
105
107
|
"ajv-formats": "3.0.1",
|
|
106
|
-
"conventional-changelog-conventionalcommits": "10.
|
|
108
|
+
"conventional-changelog-conventionalcommits": "10.4.0",
|
|
107
109
|
"markdownlint-cli": "0.49.1",
|
|
108
110
|
"rimraf": "6.1.3",
|
|
109
111
|
"semantic-release": "25.0.9",
|
|
110
112
|
"semantic-release-export-data": "1.2.0",
|
|
111
|
-
"typebox": "1.3.
|
|
113
|
+
"typebox": "1.3.16",
|
|
112
114
|
"typescript": "7.0.2"
|
|
113
115
|
},
|
|
114
116
|
"dependencies": {
|
|
@@ -120,7 +122,8 @@
|
|
|
120
122
|
},
|
|
121
123
|
"overrides": {
|
|
122
124
|
"@earendil-works/pi-ai": "0.83.0",
|
|
123
|
-
"brace-expansion": "^5.0.8"
|
|
125
|
+
"brace-expansion": "^5.0.8",
|
|
126
|
+
"conventional-changelog-writer": ">=9"
|
|
124
127
|
},
|
|
125
128
|
"publishConfig": {
|
|
126
129
|
"access": "public",
|
|
@@ -16,7 +16,14 @@ The `problem_type` determines which **track** applies. Each track has different
|
|
|
16
16
|
| Track | problem_types | Description |
|
|
17
17
|
|-------|--------------|-------------|
|
|
18
18
|
| **Bug** | `build_error`, `test_failure`, `runtime_error`, `performance_issue`, `database_issue`, `security_issue`, `ui_bug`, `integration_issue`, `logic_error` | Defects and failures that were diagnosed and fixed |
|
|
19
|
-
| **Knowledge** | `best_practice`, `documentation_gap`, `workflow_issue`, `developer_experience` | Practices, patterns, workflow improvements, and documentation |
|
|
19
|
+
| **Knowledge** | `best_practice`, `documentation_gap`, `workflow_issue`, `developer_experience`, `architecture_pattern`, `design_pattern`, `tooling_decision`, `convention` | Practices, patterns, workflow improvements, and documentation |
|
|
20
|
+
|
|
21
|
+
Prefer the narrowest applicable value. `best_practice` is the fallback when no narrower knowledge-track value fits.
|
|
22
|
+
|
|
23
|
+
- `architecture_pattern` — structural decisions about how components relate
|
|
24
|
+
- `design_pattern` — reusable solutions to recurring design problems
|
|
25
|
+
- `tooling_decision` — choices about tools, libraries, or build infrastructure
|
|
26
|
+
- `convention` — agreed-upon naming, formatting, or style rules
|
|
20
27
|
|
|
21
28
|
## Required Fields (both tracks)
|
|
22
29
|
|
|
@@ -35,6 +42,8 @@ Required:
|
|
|
35
42
|
|
|
36
43
|
## Knowledge Track Fields
|
|
37
44
|
|
|
45
|
+
Applies to every knowledge-track `problem_type` listed in the Tracks table above.
|
|
46
|
+
|
|
38
47
|
No additional required fields beyond the shared ones. All fields below are optional:
|
|
39
48
|
|
|
40
49
|
- **applies_when**: Conditions or situations where this guidance applies
|
|
@@ -73,6 +82,14 @@ Docs created before the track system may have `symptoms`/`root_cause`/`resolutio
|
|
|
73
82
|
- `workflow_issue` -> `docs/solutions/workflow-issues/`
|
|
74
83
|
- `best_practice` -> `docs/solutions/best-practices/`
|
|
75
84
|
- `documentation_gap` -> `docs/solutions/documentation-gaps/`
|
|
85
|
+
- `architecture_pattern` -> `docs/solutions/best-practices/`
|
|
86
|
+
- `design_pattern` -> `docs/solutions/best-practices/`
|
|
87
|
+
- `tooling_decision` -> `docs/solutions/best-practices/`
|
|
88
|
+
- `convention` -> `docs/solutions/best-practices/`
|
|
89
|
+
|
|
90
|
+
The four narrower knowledge-track types share the `best-practices/` directory rather than each
|
|
91
|
+
getting their own. That matches where such docs are already filed, and avoids single-document
|
|
92
|
+
directories that fragment search.
|
|
76
93
|
|
|
77
94
|
## Validation Rules
|
|
78
95
|
|
|
@@ -704,6 +704,7 @@ After presenting findings and verdict (Stage 6), route the next steps by mode. R
|
|
|
704
704
|
|
|
705
705
|
- In interactive, autofix, and headless modes, write **`review-summary.json` unconditionally** under `.context/systematic/ce-review/<run-id>`; `mode:report-only` remains the deliberate no-write exception.
|
|
706
706
|
- `review-summary.json` is the parent-owned synthesis artifact. Its lifecycle, dispatch outcomes, complete input ledger, synthesized and filtered findings with provenance, disposition counts, and downstream work are defined in the [canonical synthesis artifact contract](./references/synthesis-artifact-contract.md), whose vocabulary and bounds are executable in [`findings-schema.json`](./references/findings-schema.json).
|
|
707
|
+
- Before finalizing, follow the [artifact validation and failure path](./references/synthesis-artifact-contract.md).
|
|
707
708
|
- Initialize the artifact before dispatch and persist only validated parent-owned records. Finalize lifecycle and reconciliation after synthesis; preserve the existing degraded and abnormal-run behavior described in the canonical contract.
|
|
708
709
|
- Also write `metadata.json` alongside the findings so downstream skills can verify the artifact matches the current branch and HEAD. Minimum fields:
|
|
709
710
|
```json
|