project-tiny-context-harness 0.2.81 → 0.2.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/assets/README.md +3 -1
- package/assets/README.zh-CN.md +2 -0
- package/assets/skills/composite-long-task-workflow/SKILL.md +3 -1
- package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +2 -2
- package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +7 -2
- package/dist/lib/superpowers-task-assertion-normalizers.js +4 -1
- package/dist/lib/superpowers-task-assertions.js +17 -16
- package/dist/lib/superpowers-task-delivery.js +30 -18
- package/dist/lib/superpowers-task-derive.d.ts +1 -0
- package/dist/lib/superpowers-task-derive.js +62 -1
- package/dist/lib/superpowers-task-fields.d.ts +22 -0
- package/dist/lib/superpowers-task-fields.js +276 -0
- package/dist/lib/superpowers-task-source-compile.js +93 -95
- package/dist/lib/superpowers-task-source-parser.js +1 -3
- package/dist/lib/superpowers-task-state-schema.d.ts +59 -0
- package/dist/lib/superpowers-task-state.js +14 -5
- package/dist/lib/superpowers-task-validator.js +6 -10
- package/package.json +69 -69
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
export const PRODUCT_FIELDS = [
|
|
2
|
+
"delivery_scope",
|
|
3
|
+
"full_population_required",
|
|
4
|
+
"representative_samples_validate",
|
|
5
|
+
"representative_samples_do_not_validate",
|
|
6
|
+
"out_of_scope_backlog",
|
|
7
|
+
"scope_fit_decision",
|
|
8
|
+
"selected_scope_fit_slice",
|
|
9
|
+
"owner_boundary",
|
|
10
|
+
"primary_capability_path",
|
|
11
|
+
"non_completing_outcomes",
|
|
12
|
+
"assertion_policy",
|
|
13
|
+
"source_authority",
|
|
14
|
+
"product_goal",
|
|
15
|
+
"surface_ia_lock",
|
|
16
|
+
"decision_lock",
|
|
17
|
+
"context_delta",
|
|
18
|
+
"source_to_context_coverage",
|
|
19
|
+
"acceptance_semantics",
|
|
20
|
+
"impact"
|
|
21
|
+
];
|
|
22
|
+
export const PLAN_FIELDS = [
|
|
23
|
+
"delivery_scope",
|
|
24
|
+
"capability_target",
|
|
25
|
+
"representative_samples",
|
|
26
|
+
"full_population_boundary",
|
|
27
|
+
"non_required_population",
|
|
28
|
+
"owner_surfaces",
|
|
29
|
+
"forbidden_surfaces",
|
|
30
|
+
"owner_boundary",
|
|
31
|
+
"primary_capability_path",
|
|
32
|
+
"trigger_contract",
|
|
33
|
+
"state_transition_contract",
|
|
34
|
+
"observable_result_contract",
|
|
35
|
+
"assertion_support",
|
|
36
|
+
"required_assertion_commands",
|
|
37
|
+
"invalid_implementation_shortcuts",
|
|
38
|
+
"implementation_paths",
|
|
39
|
+
"required_tests",
|
|
40
|
+
"related_acs",
|
|
41
|
+
"requirement_ref",
|
|
42
|
+
"decision_id",
|
|
43
|
+
"proof_layer_ids",
|
|
44
|
+
"api_schema_changes",
|
|
45
|
+
"state_machine",
|
|
46
|
+
"data_flow",
|
|
47
|
+
"worker_runtime_behavior",
|
|
48
|
+
"ui_ia_changes",
|
|
49
|
+
"migration_plan",
|
|
50
|
+
"evidence_artifacts",
|
|
51
|
+
"explicit_no_test_scope",
|
|
52
|
+
"non_completing_shortcuts",
|
|
53
|
+
"substitution_policy",
|
|
54
|
+
"drift_severity",
|
|
55
|
+
"partial_conditions",
|
|
56
|
+
"blockers",
|
|
57
|
+
"context_fact_refs"
|
|
58
|
+
];
|
|
59
|
+
export const ACCEPTANCE_FIELDS = [
|
|
60
|
+
"acceptance_scope",
|
|
61
|
+
"ac_validates",
|
|
62
|
+
"ac_does_not_validate",
|
|
63
|
+
"sample_boundary",
|
|
64
|
+
"full_population_required",
|
|
65
|
+
"related_plan_items",
|
|
66
|
+
"required_proof_layers",
|
|
67
|
+
"assertion_command",
|
|
68
|
+
"assertion_artifacts",
|
|
69
|
+
"positive_assertions",
|
|
70
|
+
"negative_assertions",
|
|
71
|
+
"machine_blocking",
|
|
72
|
+
"invalid_completion_signals",
|
|
73
|
+
"assertion_result_required",
|
|
74
|
+
"ac_type",
|
|
75
|
+
"proof_chain",
|
|
76
|
+
"verification_method",
|
|
77
|
+
"fail_conditions",
|
|
78
|
+
"invalid_evidence",
|
|
79
|
+
"substitution_policy",
|
|
80
|
+
"missing_layer_downgrade",
|
|
81
|
+
"auditor_expectation",
|
|
82
|
+
"out_of_scope_na_approval_source",
|
|
83
|
+
"required_test_ids",
|
|
84
|
+
"explicit_no_test_scope",
|
|
85
|
+
"hard_blockers",
|
|
86
|
+
"validates_explanation",
|
|
87
|
+
"does_not_validate_explanation",
|
|
88
|
+
"final_evidence_expected",
|
|
89
|
+
"test_cases"
|
|
90
|
+
];
|
|
91
|
+
export const PRODUCT_REQUIRED_FIELDS = [
|
|
92
|
+
"delivery_scope",
|
|
93
|
+
"full_population_required",
|
|
94
|
+
"representative_samples_validate",
|
|
95
|
+
"representative_samples_do_not_validate",
|
|
96
|
+
"out_of_scope_backlog",
|
|
97
|
+
"scope_fit_decision",
|
|
98
|
+
"selected_scope_fit_slice",
|
|
99
|
+
"owner_boundary",
|
|
100
|
+
"primary_capability_path",
|
|
101
|
+
"non_completing_outcomes",
|
|
102
|
+
"assertion_policy",
|
|
103
|
+
"source_authority",
|
|
104
|
+
"product_goal"
|
|
105
|
+
];
|
|
106
|
+
export const PLAN_REQUIRED_FIELDS = [
|
|
107
|
+
"delivery_scope",
|
|
108
|
+
"capability_target",
|
|
109
|
+
"representative_samples",
|
|
110
|
+
"full_population_boundary",
|
|
111
|
+
"non_required_population",
|
|
112
|
+
"owner_boundary",
|
|
113
|
+
"primary_capability_path",
|
|
114
|
+
"trigger_contract",
|
|
115
|
+
"state_transition_contract",
|
|
116
|
+
"observable_result_contract",
|
|
117
|
+
"assertion_support",
|
|
118
|
+
"required_assertion_commands",
|
|
119
|
+
"invalid_implementation_shortcuts",
|
|
120
|
+
"implementation_paths"
|
|
121
|
+
];
|
|
122
|
+
export const ACCEPTANCE_REQUIRED_FIELDS = [
|
|
123
|
+
"acceptance_scope",
|
|
124
|
+
"ac_validates",
|
|
125
|
+
"ac_does_not_validate",
|
|
126
|
+
"sample_boundary",
|
|
127
|
+
"full_population_required",
|
|
128
|
+
"related_plan_items",
|
|
129
|
+
"required_proof_layers",
|
|
130
|
+
"assertion_command",
|
|
131
|
+
"assertion_artifacts",
|
|
132
|
+
"positive_assertions",
|
|
133
|
+
"negative_assertions",
|
|
134
|
+
"machine_blocking",
|
|
135
|
+
"invalid_completion_signals",
|
|
136
|
+
"assertion_result_required"
|
|
137
|
+
];
|
|
138
|
+
export const PRODUCT_FIELD_TYPES = {
|
|
139
|
+
delivery_scope: "enum",
|
|
140
|
+
full_population_required: "boolean",
|
|
141
|
+
representative_samples_validate: "array",
|
|
142
|
+
representative_samples_do_not_validate: "array",
|
|
143
|
+
out_of_scope_backlog: "array",
|
|
144
|
+
scope_fit_decision: "enum",
|
|
145
|
+
selected_scope_fit_slice: "text",
|
|
146
|
+
owner_boundary: "text",
|
|
147
|
+
primary_capability_path: "text",
|
|
148
|
+
non_completing_outcomes: "array",
|
|
149
|
+
assertion_policy: "text",
|
|
150
|
+
source_authority: "text",
|
|
151
|
+
product_goal: "text",
|
|
152
|
+
surface_ia_lock: "text",
|
|
153
|
+
decision_lock: "text",
|
|
154
|
+
context_delta: "text",
|
|
155
|
+
source_to_context_coverage: "text",
|
|
156
|
+
acceptance_semantics: "text",
|
|
157
|
+
impact: "text"
|
|
158
|
+
};
|
|
159
|
+
export const PLAN_FIELD_TYPES = {
|
|
160
|
+
delivery_scope: "enum",
|
|
161
|
+
capability_target: "text",
|
|
162
|
+
representative_samples: "array",
|
|
163
|
+
full_population_boundary: "text",
|
|
164
|
+
non_required_population: "array",
|
|
165
|
+
owner_surfaces: "array",
|
|
166
|
+
forbidden_surfaces: "array",
|
|
167
|
+
owner_boundary: "text",
|
|
168
|
+
primary_capability_path: "text",
|
|
169
|
+
trigger_contract: "text",
|
|
170
|
+
state_transition_contract: "text",
|
|
171
|
+
observable_result_contract: "text",
|
|
172
|
+
assertion_support: "text",
|
|
173
|
+
required_assertion_commands: "array",
|
|
174
|
+
invalid_implementation_shortcuts: "array",
|
|
175
|
+
implementation_paths: "array",
|
|
176
|
+
required_tests: "array",
|
|
177
|
+
related_acs: "array",
|
|
178
|
+
requirement_ref: "text",
|
|
179
|
+
decision_id: "text",
|
|
180
|
+
proof_layer_ids: "array",
|
|
181
|
+
api_schema_changes: "text",
|
|
182
|
+
state_machine: "text",
|
|
183
|
+
data_flow: "text",
|
|
184
|
+
worker_runtime_behavior: "text",
|
|
185
|
+
ui_ia_changes: "text",
|
|
186
|
+
migration_plan: "text",
|
|
187
|
+
evidence_artifacts: "array",
|
|
188
|
+
explicit_no_test_scope: "boolean",
|
|
189
|
+
non_completing_shortcuts: "array",
|
|
190
|
+
substitution_policy: "array",
|
|
191
|
+
drift_severity: "text",
|
|
192
|
+
partial_conditions: "array",
|
|
193
|
+
blockers: "array",
|
|
194
|
+
context_fact_refs: "array"
|
|
195
|
+
};
|
|
196
|
+
export const ACCEPTANCE_FIELD_TYPES = {
|
|
197
|
+
acceptance_scope: "enum",
|
|
198
|
+
ac_validates: "array",
|
|
199
|
+
ac_does_not_validate: "array",
|
|
200
|
+
sample_boundary: "text",
|
|
201
|
+
full_population_required: "boolean",
|
|
202
|
+
related_plan_items: "array",
|
|
203
|
+
required_proof_layers: "array",
|
|
204
|
+
assertion_command: "text",
|
|
205
|
+
assertion_artifacts: "array",
|
|
206
|
+
positive_assertions: "array",
|
|
207
|
+
negative_assertions: "array",
|
|
208
|
+
machine_blocking: "boolean",
|
|
209
|
+
invalid_completion_signals: "array",
|
|
210
|
+
assertion_result_required: "boolean",
|
|
211
|
+
ac_type: "text",
|
|
212
|
+
proof_chain: "array",
|
|
213
|
+
verification_method: "array",
|
|
214
|
+
fail_conditions: "array",
|
|
215
|
+
invalid_evidence: "array",
|
|
216
|
+
substitution_policy: "array",
|
|
217
|
+
missing_layer_downgrade: "text",
|
|
218
|
+
auditor_expectation: "text",
|
|
219
|
+
out_of_scope_na_approval_source: "text",
|
|
220
|
+
required_test_ids: "array",
|
|
221
|
+
explicit_no_test_scope: "boolean",
|
|
222
|
+
hard_blockers: "array",
|
|
223
|
+
validates_explanation: "text",
|
|
224
|
+
does_not_validate_explanation: "text",
|
|
225
|
+
final_evidence_expected: "array",
|
|
226
|
+
test_cases: "array"
|
|
227
|
+
};
|
|
228
|
+
export const PRODUCT_DELIVERY_SCOPES = new Set([
|
|
229
|
+
"system_capability_build", "representative_sample_validation", "full_population_operation", "mixed_scope_requires_boundary"
|
|
230
|
+
]);
|
|
231
|
+
export const PLAN_DELIVERY_SCOPES = new Set([
|
|
232
|
+
"system_capability_build", "representative_sample_validation", "full_population_operation", "out_of_scope_backlog"
|
|
233
|
+
]);
|
|
234
|
+
export const ACCEPTANCE_SCOPES = new Set([
|
|
235
|
+
"system_capability_build", "representative_sample_validation", "full_population_operation", "full_population_not_required"
|
|
236
|
+
]);
|
|
237
|
+
export const SCOPE_FIT_DECISIONS = new Set(["fit_for_three_inputs", "selected_from_split", "blocked_for_decision"]);
|
|
238
|
+
export const CANONICAL_PROOF_LAYERS = [
|
|
239
|
+
"code",
|
|
240
|
+
"api_schema",
|
|
241
|
+
"worker_runtime",
|
|
242
|
+
"data_artifact",
|
|
243
|
+
"integration",
|
|
244
|
+
"ui_browser",
|
|
245
|
+
"security_redaction",
|
|
246
|
+
"all_provider_all_runner",
|
|
247
|
+
"cleanup_stale_scan",
|
|
248
|
+
"test"
|
|
249
|
+
];
|
|
250
|
+
export const LEGACY_PROOF_LAYER_ALIASES = {
|
|
251
|
+
runtime: "worker_runtime",
|
|
252
|
+
browser: "ui_browser",
|
|
253
|
+
api: "api_schema",
|
|
254
|
+
data: "data_artifact",
|
|
255
|
+
security: "security_redaction"
|
|
256
|
+
};
|
|
257
|
+
export const MACHINE_VERIFIABLE_LAYER_NAMES = new Set(CANONICAL_PROOF_LAYERS.filter((layer) => layer !== "code"));
|
|
258
|
+
export function fieldSet(fields) {
|
|
259
|
+
return new Set(fields);
|
|
260
|
+
}
|
|
261
|
+
export function normalizeProofLayerName(layer) {
|
|
262
|
+
const normalized = layer.trim().toLowerCase().replace(/[- ]+/g, "_");
|
|
263
|
+
return LEGACY_PROOF_LAYER_ALIASES[normalized] ?? normalized;
|
|
264
|
+
}
|
|
265
|
+
export function normalizeProofLayerId(layerId) {
|
|
266
|
+
const value = layerId.trim();
|
|
267
|
+
if (!value.includes(".")) {
|
|
268
|
+
return normalizeProofLayerName(value);
|
|
269
|
+
}
|
|
270
|
+
const acId = value.slice(0, value.lastIndexOf("."));
|
|
271
|
+
const layer = value.slice(value.lastIndexOf(".") + 1);
|
|
272
|
+
return `${acId}.${normalizeProofLayerName(layer)}`;
|
|
273
|
+
}
|
|
274
|
+
export function isSelectedScopeFitSlice(value) {
|
|
275
|
+
return value === "none" || /^SFC-\d{3,}$/i.test(value);
|
|
276
|
+
}
|
|
@@ -1,89 +1,38 @@
|
|
|
1
1
|
import { MACHINE_VERIFIABLE_PROOF_LAYERS, proofLayerName } from "./superpowers-task-assertions.js";
|
|
2
2
|
import { compileReportSuffix, missingCategory, throwCompileErrors } from "./superpowers-task-compile-diagnostics.js";
|
|
3
|
+
import { ACCEPTANCE_FIELDS, ACCEPTANCE_SCOPES, fieldSet, isSelectedScopeFitSlice, normalizeProofLayerName, PLAN_DELIVERY_SCOPES, PLAN_FIELDS, PRODUCT_DELIVERY_SCOPES, PRODUCT_FIELDS, SCOPE_FIT_DECISIONS } from "./superpowers-task-fields.js";
|
|
3
4
|
import { fieldArray, fieldBoolean, fieldLine, fieldText, parseDocumentFields, parseHeadingDefinitions } from "./superpowers-task-source-parser.js";
|
|
4
5
|
export const DEFAULT_LAYERS = ["code", "test"];
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const PRODUCT_FIELDS = new Set([
|
|
9
|
-
"delivery_scope",
|
|
10
|
-
"full_population_required",
|
|
11
|
-
"representative_samples_validate",
|
|
12
|
-
"representative_samples_do_not_validate",
|
|
13
|
-
"out_of_scope_backlog",
|
|
14
|
-
"source_authority",
|
|
15
|
-
"product_goal",
|
|
16
|
-
"surface_ia_lock",
|
|
17
|
-
"decision_lock",
|
|
18
|
-
"context_delta",
|
|
19
|
-
"source_to_context_coverage",
|
|
20
|
-
"acceptance_semantics",
|
|
21
|
-
"impact"
|
|
22
|
-
]);
|
|
23
|
-
const PLAN_FIELDS = new Set([
|
|
24
|
-
"delivery_scope",
|
|
25
|
-
"capability_target",
|
|
26
|
-
"representative_samples",
|
|
27
|
-
"full_population_boundary",
|
|
28
|
-
"non_required_population",
|
|
29
|
-
"owner_surfaces",
|
|
30
|
-
"forbidden_surfaces",
|
|
31
|
-
"implementation_paths",
|
|
32
|
-
"required_tests",
|
|
33
|
-
"related_acs",
|
|
34
|
-
"requirement_ref",
|
|
35
|
-
"decision_id",
|
|
36
|
-
"proof_layer_ids",
|
|
37
|
-
"api_schema_changes",
|
|
38
|
-
"state_machine",
|
|
39
|
-
"data_flow",
|
|
40
|
-
"worker_runtime_behavior",
|
|
41
|
-
"ui_ia_changes",
|
|
42
|
-
"migration_plan",
|
|
43
|
-
"evidence_artifacts",
|
|
44
|
-
"explicit_no_test_scope",
|
|
45
|
-
"non_completing_shortcuts",
|
|
46
|
-
"substitution_policy",
|
|
47
|
-
"drift_severity",
|
|
48
|
-
"partial_conditions",
|
|
49
|
-
"blockers",
|
|
50
|
-
"context_fact_refs"
|
|
51
|
-
]);
|
|
52
|
-
const ACCEPTANCE_FIELDS = new Set([
|
|
53
|
-
"checklist_source",
|
|
54
|
-
"acceptance_scope",
|
|
55
|
-
"ac_validates",
|
|
56
|
-
"ac_does_not_validate",
|
|
57
|
-
"sample_boundary",
|
|
58
|
-
"full_population_required",
|
|
59
|
-
"related_plan_items",
|
|
60
|
-
"required_proof_layers",
|
|
61
|
-
"ac_type",
|
|
62
|
-
"proof_chain",
|
|
63
|
-
"verification_method",
|
|
64
|
-
"fail_conditions",
|
|
65
|
-
"invalid_evidence",
|
|
66
|
-
"substitution_policy",
|
|
67
|
-
"missing_layer_downgrade",
|
|
68
|
-
"auditor_expectation",
|
|
69
|
-
"out_of_scope_na_approval_source",
|
|
70
|
-
"required_test_ids",
|
|
71
|
-
"explicit_no_test_scope",
|
|
72
|
-
"hard_blockers",
|
|
73
|
-
"validates_explanation",
|
|
74
|
-
"does_not_validate_explanation",
|
|
75
|
-
"final_evidence_expected",
|
|
76
|
-
"test_cases"
|
|
77
|
-
]);
|
|
6
|
+
const PRODUCT_FIELD_SET = fieldSet(PRODUCT_FIELDS);
|
|
7
|
+
const PLAN_FIELD_SET = fieldSet(PLAN_FIELDS);
|
|
8
|
+
const ACCEPTANCE_FIELD_SET = fieldSet(ACCEPTANCE_FIELDS);
|
|
78
9
|
export function parseProductArchitectureScope(content, sourceFile) {
|
|
79
|
-
const fields = parseDocumentFields(content, sourceFile,
|
|
10
|
+
const fields = parseDocumentFields(content, sourceFile, PRODUCT_FIELD_SET);
|
|
80
11
|
const errors = [];
|
|
12
|
+
const selectedScopeFitSlice = requireText(errors, "Product / Architecture Source", "selected_scope_fit_slice", fields, sourceFile, 1);
|
|
13
|
+
if (selectedScopeFitSlice && !isSelectedScopeFitSlice(selectedScopeFitSlice)) {
|
|
14
|
+
errors.push(`Product / Architecture Source invalid selected_scope_fit_slice: ${selectedScopeFitSlice} at ${sourceFile}:${fieldLine(fields, "selected_scope_fit_slice") ?? 1}; allowed: none or SFC-###${compileReportSuffix("blocking_unparseable_object", sourceFile, fieldLine(fields, "selected_scope_fit_slice") ?? 1, "selected_scope_fit_slice", "value must be none or an SFC-### id", "fix selected_scope_fit_slice and rerun compile")}`);
|
|
15
|
+
}
|
|
81
16
|
const scope = {
|
|
82
17
|
delivery_scope: requireEnum(errors, "Product / Architecture Source", "delivery_scope", fields, PRODUCT_DELIVERY_SCOPES, sourceFile, 1),
|
|
83
18
|
full_population_required: requireBoolean(errors, "Product / Architecture Source", "full_population_required", fields, sourceFile, 1),
|
|
84
19
|
representative_samples_validate: requireArray(errors, "Product / Architecture Source", "representative_samples_validate", fields, sourceFile, 1),
|
|
85
20
|
representative_samples_do_not_validate: requireArray(errors, "Product / Architecture Source", "representative_samples_do_not_validate", fields, sourceFile, 1),
|
|
86
|
-
out_of_scope_backlog: requireArray(errors, "Product / Architecture Source", "out_of_scope_backlog", fields, sourceFile, 1)
|
|
21
|
+
out_of_scope_backlog: requireArray(errors, "Product / Architecture Source", "out_of_scope_backlog", fields, sourceFile, 1),
|
|
22
|
+
scope_fit_decision: requireEnum(errors, "Product / Architecture Source", "scope_fit_decision", fields, SCOPE_FIT_DECISIONS, sourceFile, 1),
|
|
23
|
+
selected_scope_fit_slice: selectedScopeFitSlice,
|
|
24
|
+
owner_boundary: requireText(errors, "Product / Architecture Source", "owner_boundary", fields, sourceFile, 1),
|
|
25
|
+
primary_capability_path: requireText(errors, "Product / Architecture Source", "primary_capability_path", fields, sourceFile, 1),
|
|
26
|
+
non_completing_outcomes: requireArray(errors, "Product / Architecture Source", "non_completing_outcomes", fields, sourceFile, 1),
|
|
27
|
+
assertion_policy: requireText(errors, "Product / Architecture Source", "assertion_policy", fields, sourceFile, 1),
|
|
28
|
+
source_authority: requireText(errors, "Product / Architecture Source", "source_authority", fields, sourceFile, 1),
|
|
29
|
+
product_goal: requireText(errors, "Product / Architecture Source", "product_goal", fields, sourceFile, 1),
|
|
30
|
+
surface_ia_lock: optionalText(fields, "surface_ia_lock"),
|
|
31
|
+
decision_lock: optionalText(fields, "decision_lock"),
|
|
32
|
+
context_delta: optionalText(fields, "context_delta"),
|
|
33
|
+
source_to_context_coverage: optionalText(fields, "source_to_context_coverage"),
|
|
34
|
+
acceptance_semantics: optionalText(fields, "acceptance_semantics"),
|
|
35
|
+
impact: optionalText(fields, "impact")
|
|
87
36
|
};
|
|
88
37
|
throwCompileErrors(errors);
|
|
89
38
|
return scope;
|
|
@@ -91,7 +40,7 @@ export function parseProductArchitectureScope(content, sourceFile) {
|
|
|
91
40
|
export function parsePlanItems(content, sourceFile) {
|
|
92
41
|
const items = {};
|
|
93
42
|
const errors = [];
|
|
94
|
-
for (const definition of parseHeadingDefinitions(content, { kind: "PI", sourceFile, allowedFields:
|
|
43
|
+
for (const definition of parseHeadingDefinitions(content, { kind: "PI", sourceFile, allowedFields: PLAN_FIELD_SET })) {
|
|
95
44
|
const fields = definition.fields;
|
|
96
45
|
items[definition.id] = {
|
|
97
46
|
requirement: definition.title,
|
|
@@ -103,13 +52,33 @@ export function parsePlanItems(content, sourceFile) {
|
|
|
103
52
|
representative_samples: requireArray(errors, definition.id, "representative_samples", fields, sourceFile, definition.source_start_line),
|
|
104
53
|
full_population_boundary: requireText(errors, definition.id, "full_population_boundary", fields, sourceFile, definition.source_start_line),
|
|
105
54
|
non_required_population: requireArray(errors, definition.id, "non_required_population", fields, sourceFile, definition.source_start_line),
|
|
55
|
+
owner_boundary: requireText(errors, definition.id, "owner_boundary", fields, sourceFile, definition.source_start_line),
|
|
56
|
+
primary_capability_path: requireText(errors, definition.id, "primary_capability_path", fields, sourceFile, definition.source_start_line),
|
|
57
|
+
trigger_contract: requireText(errors, definition.id, "trigger_contract", fields, sourceFile, definition.source_start_line),
|
|
58
|
+
state_transition_contract: requireText(errors, definition.id, "state_transition_contract", fields, sourceFile, definition.source_start_line),
|
|
59
|
+
observable_result_contract: requireText(errors, definition.id, "observable_result_contract", fields, sourceFile, definition.source_start_line),
|
|
60
|
+
assertion_support: requireText(errors, definition.id, "assertion_support", fields, sourceFile, definition.source_start_line),
|
|
61
|
+
required_assertion_commands: requireArray(errors, definition.id, "required_assertion_commands", fields, sourceFile, definition.source_start_line),
|
|
62
|
+
invalid_implementation_shortcuts: requireArray(errors, definition.id, "invalid_implementation_shortcuts", fields, sourceFile, definition.source_start_line),
|
|
106
63
|
owner_surfaces: optionalArray(fields, "owner_surfaces"),
|
|
107
64
|
forbidden_surfaces: optionalArray(fields, "forbidden_surfaces"),
|
|
108
|
-
implementation_paths:
|
|
65
|
+
implementation_paths: requireArray(errors, definition.id, "implementation_paths", fields, sourceFile, definition.source_start_line),
|
|
109
66
|
required_tests: optionalArray(fields, "required_tests"),
|
|
110
|
-
proof_layer_ids: optionalArray(fields, "proof_layer_ids").map(
|
|
67
|
+
proof_layer_ids: optionalArray(fields, "proof_layer_ids").map(normalizeLayerId),
|
|
68
|
+
requirement_ref: optionalText(fields, "requirement_ref"),
|
|
69
|
+
decision_id: optionalText(fields, "decision_id"),
|
|
70
|
+
api_schema_changes: optionalText(fields, "api_schema_changes"),
|
|
71
|
+
state_machine: optionalText(fields, "state_machine"),
|
|
72
|
+
data_flow: optionalText(fields, "data_flow"),
|
|
73
|
+
worker_runtime_behavior: optionalText(fields, "worker_runtime_behavior"),
|
|
74
|
+
ui_ia_changes: optionalText(fields, "ui_ia_changes"),
|
|
75
|
+
migration_plan: optionalText(fields, "migration_plan"),
|
|
76
|
+
evidence_artifacts: optionalArray(fields, "evidence_artifacts"),
|
|
111
77
|
non_completing_shortcuts: optionalArray(fields, "non_completing_shortcuts"),
|
|
112
78
|
substitution_policy: optionalArray(fields, "substitution_policy"),
|
|
79
|
+
drift_severity: optionalText(fields, "drift_severity"),
|
|
80
|
+
partial_conditions: optionalArray(fields, "partial_conditions"),
|
|
81
|
+
blockers: optionalArray(fields, "blockers"),
|
|
113
82
|
explicit_no_test_scope: fieldBoolean(fields, "explicit_no_test_scope") === true,
|
|
114
83
|
context_fact_refs: optionalArray(fields, "context_fact_refs"),
|
|
115
84
|
status: "not_started",
|
|
@@ -123,9 +92,9 @@ export function parsePlanItems(content, sourceFile) {
|
|
|
123
92
|
export function parseAcceptanceCriteria(content, sourceFile) {
|
|
124
93
|
const items = {};
|
|
125
94
|
const errors = [];
|
|
126
|
-
for (const definition of parseHeadingDefinitions(content, { kind: "AC", sourceFile, allowedFields:
|
|
95
|
+
for (const definition of parseHeadingDefinitions(content, { kind: "AC", sourceFile, allowedFields: ACCEPTANCE_FIELD_SET })) {
|
|
127
96
|
const fields = definition.fields;
|
|
128
|
-
const layers =
|
|
97
|
+
const layers = requireArray(errors, definition.id, "required_proof_layers", fields, sourceFile, definition.source_start_line).map(normalizeLayer).filter(Boolean);
|
|
129
98
|
const requiredProofLayers = layers.length > 0 ? layers : DEFAULT_LAYERS;
|
|
130
99
|
items[definition.id] = {
|
|
131
100
|
scope: definition.title,
|
|
@@ -137,13 +106,31 @@ export function parseAcceptanceCriteria(content, sourceFile) {
|
|
|
137
106
|
ac_does_not_validate: requireArray(errors, definition.id, "ac_does_not_validate", fields, sourceFile, definition.source_start_line),
|
|
138
107
|
sample_boundary: requireText(errors, definition.id, "sample_boundary", fields, sourceFile, definition.source_start_line),
|
|
139
108
|
full_population_required: requireBoolean(errors, definition.id, "full_population_required", fields, sourceFile, definition.source_start_line),
|
|
140
|
-
related_plan_items:
|
|
109
|
+
related_plan_items: requireArray(errors, definition.id, "related_plan_items", fields, sourceFile, definition.source_start_line).map((item) => item.toUpperCase()),
|
|
141
110
|
required_proof_layers: requiredProofLayers,
|
|
142
111
|
assertion_requirements: assertionRequirements(fields, requiredProofLayers),
|
|
112
|
+
assertion_command: requireText(errors, definition.id, "assertion_command", fields, sourceFile, definition.source_start_line),
|
|
113
|
+
assertion_artifacts: requireArray(errors, definition.id, "assertion_artifacts", fields, sourceFile, definition.source_start_line),
|
|
114
|
+
positive_assertions: requireArray(errors, definition.id, "positive_assertions", fields, sourceFile, definition.source_start_line),
|
|
115
|
+
negative_assertions: requireArray(errors, definition.id, "negative_assertions", fields, sourceFile, definition.source_start_line),
|
|
116
|
+
machine_blocking: requireBoolean(errors, definition.id, "machine_blocking", fields, sourceFile, definition.source_start_line),
|
|
117
|
+
invalid_completion_signals: requireArray(errors, definition.id, "invalid_completion_signals", fields, sourceFile, definition.source_start_line),
|
|
118
|
+
assertion_result_required: requireBoolean(errors, definition.id, "assertion_result_required", fields, sourceFile, definition.source_start_line),
|
|
119
|
+
ac_type: optionalText(fields, "ac_type"),
|
|
120
|
+
proof_chain: optionalArray(fields, "proof_chain").map(normalizeLayerId),
|
|
143
121
|
required_test_ids: optionalArray(fields, "required_test_ids"),
|
|
144
122
|
fail_conditions: optionalArray(fields, "fail_conditions"),
|
|
145
123
|
invalid_evidence: optionalArray(fields, "invalid_evidence"),
|
|
124
|
+
substitution_policy: optionalArray(fields, "substitution_policy"),
|
|
125
|
+
missing_layer_downgrade: optionalText(fields, "missing_layer_downgrade"),
|
|
126
|
+
auditor_expectation: optionalText(fields, "auditor_expectation"),
|
|
127
|
+
out_of_scope_na_approval_source: optionalText(fields, "out_of_scope_na_approval_source"),
|
|
128
|
+
hard_blockers: optionalArray(fields, "hard_blockers"),
|
|
129
|
+
validates_explanation: optionalText(fields, "validates_explanation"),
|
|
130
|
+
does_not_validate_explanation: optionalText(fields, "does_not_validate_explanation"),
|
|
146
131
|
final_evidence_expected: optionalArray(fields, "final_evidence_expected"),
|
|
132
|
+
verification_method: optionalArray(fields, "verification_method"),
|
|
133
|
+
test_cases: optionalArray(fields, "test_cases"),
|
|
147
134
|
explicit_no_test_scope: fieldBoolean(fields, "explicit_no_test_scope") === true,
|
|
148
135
|
status: "not_run"
|
|
149
136
|
};
|
|
@@ -152,28 +139,36 @@ export function parseAcceptanceCriteria(content, sourceFile) {
|
|
|
152
139
|
return items;
|
|
153
140
|
}
|
|
154
141
|
function normalizeLayer(value) {
|
|
155
|
-
return value
|
|
142
|
+
return normalizeProofLayerName(value);
|
|
143
|
+
}
|
|
144
|
+
function normalizeLayerId(value) {
|
|
145
|
+
const trimmed = value.trim();
|
|
146
|
+
if (!trimmed.includes(".")) {
|
|
147
|
+
return normalizeLayer(trimmed);
|
|
148
|
+
}
|
|
149
|
+
const acId = trimmed.slice(0, trimmed.lastIndexOf(".")).toUpperCase();
|
|
150
|
+
const layer = trimmed.slice(trimmed.lastIndexOf(".") + 1);
|
|
151
|
+
return `${acId}.${normalizeLayer(layer)}`;
|
|
156
152
|
}
|
|
157
153
|
function assertionRequirements(fields, layers) {
|
|
158
154
|
const requiredTestIds = optionalArray(fields, "required_test_ids");
|
|
159
|
-
const positiveAssertions = unique(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const negativeAssertions = unique([
|
|
167
|
-
...fieldArray(fields, "ac_does_not_validate"),
|
|
168
|
-
...optionalArray(fields, "fail_conditions"),
|
|
169
|
-
...optionalArray(fields, "invalid_evidence")
|
|
170
|
-
]);
|
|
155
|
+
const positiveAssertions = unique(optionalArray(fields, "positive_assertions"));
|
|
156
|
+
const negativeAssertions = unique(optionalArray(fields, "negative_assertions"));
|
|
157
|
+
const assertionCommand = fieldText(fields, "assertion_command");
|
|
158
|
+
const assertionArtifacts = optionalArray(fields, "assertion_artifacts");
|
|
159
|
+
const machineBlocking = fieldBoolean(fields, "machine_blocking");
|
|
160
|
+
const assertionResultRequired = fieldBoolean(fields, "assertion_result_required");
|
|
161
|
+
const invalidCompletionSignals = optionalArray(fields, "invalid_completion_signals");
|
|
171
162
|
return layers.map((layer) => {
|
|
172
163
|
const normalized = proofLayerName(normalizeLayer(layer));
|
|
173
164
|
return {
|
|
174
165
|
proof_layer: normalized,
|
|
175
166
|
required: true,
|
|
176
|
-
machine_blocking: MACHINE_VERIFIABLE_PROOF_LAYERS.has(normalized),
|
|
167
|
+
machine_blocking: machineBlocking ?? MACHINE_VERIFIABLE_PROOF_LAYERS.has(normalized),
|
|
168
|
+
assertion_result_required: assertionResultRequired ?? MACHINE_VERIFIABLE_PROOF_LAYERS.has(normalized),
|
|
169
|
+
assertion_command: assertionCommand,
|
|
170
|
+
assertion_artifacts: assertionArtifacts,
|
|
171
|
+
invalid_completion_signals: invalidCompletionSignals,
|
|
177
172
|
required_test_ids: requiredTestIds,
|
|
178
173
|
positive_assertions: positiveAssertions,
|
|
179
174
|
negative_assertions: negativeAssertions
|
|
@@ -223,6 +218,9 @@ function requireBoolean(errors, label, name, fields, sourceFile, fallbackLine) {
|
|
|
223
218
|
function optionalArray(fields, name) {
|
|
224
219
|
return fields[name] ? fieldArray(fields, name) : [];
|
|
225
220
|
}
|
|
221
|
+
function optionalText(fields, name) {
|
|
222
|
+
return fields[name] ? fieldText(fields, name) : "";
|
|
223
|
+
}
|
|
226
224
|
function unique(values) {
|
|
227
225
|
return [...new Set(values.filter(Boolean))];
|
|
228
226
|
}
|
|
@@ -86,9 +86,7 @@ function parseFields(lines, sourceFile, startLine, allowedFields, errors) {
|
|
|
86
86
|
}
|
|
87
87
|
const name = match[1];
|
|
88
88
|
if (!allowedFields.has(name)) {
|
|
89
|
-
|
|
90
|
-
errors.push(compileError(`${sourceFile}:${lineNumber} unknown field ${name}`, "blocking_unparseable_object", sourceFile, lineNumber, name, "unknown fields may hide required source semantics", "rename the field to a supported canonical key"));
|
|
91
|
-
}
|
|
89
|
+
errors.push(compileError(`${sourceFile}:${lineNumber} unknown field ${name}`, "blocking_unparseable_object", sourceFile, lineNumber, name, "unknown fields may hide required source semantics", "rename the field to a supported canonical key"));
|
|
92
90
|
continue;
|
|
93
91
|
}
|
|
94
92
|
if (fields[name]) {
|
|
@@ -59,6 +59,7 @@ export type SuperpowersAcceptanceStatus = "not_run" | "complete" | "partial" | "
|
|
|
59
59
|
export type SuperpowersProductDeliveryScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "mixed_scope_requires_boundary";
|
|
60
60
|
export type SuperpowersPlanDeliveryScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "out_of_scope_backlog";
|
|
61
61
|
export type SuperpowersAcceptanceScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "full_population_not_required";
|
|
62
|
+
export type SuperpowersScopeFitDecision = "fit_for_three_inputs" | "selected_from_split" | "blocked_for_decision" | "";
|
|
62
63
|
export interface SuperpowersTaskState {
|
|
63
64
|
meta: {
|
|
64
65
|
task_id: string;
|
|
@@ -113,6 +114,20 @@ export interface SuperpowersProductArchitectureScope {
|
|
|
113
114
|
representative_samples_validate: string[];
|
|
114
115
|
representative_samples_do_not_validate: string[];
|
|
115
116
|
out_of_scope_backlog: string[];
|
|
117
|
+
scope_fit_decision: SuperpowersScopeFitDecision;
|
|
118
|
+
selected_scope_fit_slice: string;
|
|
119
|
+
owner_boundary: string;
|
|
120
|
+
primary_capability_path: string;
|
|
121
|
+
non_completing_outcomes: string[];
|
|
122
|
+
assertion_policy: string;
|
|
123
|
+
source_authority: string;
|
|
124
|
+
product_goal: string;
|
|
125
|
+
surface_ia_lock?: string;
|
|
126
|
+
decision_lock?: string;
|
|
127
|
+
context_delta?: string;
|
|
128
|
+
source_to_context_coverage?: string;
|
|
129
|
+
acceptance_semantics?: string;
|
|
130
|
+
impact?: string;
|
|
116
131
|
}
|
|
117
132
|
export interface SuperpowersProgressState {
|
|
118
133
|
system_capability_progress: Record<string, unknown>;
|
|
@@ -131,13 +146,33 @@ export interface SuperpowersPlanItem {
|
|
|
131
146
|
representative_samples: string[];
|
|
132
147
|
full_population_boundary: string;
|
|
133
148
|
non_required_population: string[];
|
|
149
|
+
owner_boundary: string;
|
|
150
|
+
primary_capability_path: string;
|
|
151
|
+
trigger_contract: string;
|
|
152
|
+
state_transition_contract: string;
|
|
153
|
+
observable_result_contract: string;
|
|
154
|
+
assertion_support: string;
|
|
155
|
+
required_assertion_commands: string[];
|
|
156
|
+
invalid_implementation_shortcuts: string[];
|
|
134
157
|
owner_surfaces: string[];
|
|
135
158
|
forbidden_surfaces: string[];
|
|
136
159
|
implementation_paths: string[];
|
|
137
160
|
required_tests: string[];
|
|
138
161
|
proof_layer_ids?: string[];
|
|
162
|
+
requirement_ref?: string;
|
|
163
|
+
decision_id?: string;
|
|
164
|
+
api_schema_changes?: string;
|
|
165
|
+
state_machine?: string;
|
|
166
|
+
data_flow?: string;
|
|
167
|
+
worker_runtime_behavior?: string;
|
|
168
|
+
ui_ia_changes?: string;
|
|
169
|
+
migration_plan?: string;
|
|
170
|
+
evidence_artifacts?: string[];
|
|
139
171
|
non_completing_shortcuts?: string[];
|
|
140
172
|
substitution_policy?: string[];
|
|
173
|
+
drift_severity?: string;
|
|
174
|
+
partial_conditions?: string[];
|
|
175
|
+
blockers?: string[];
|
|
141
176
|
explicit_no_test_scope?: boolean;
|
|
142
177
|
context_fact_refs?: string[];
|
|
143
178
|
status: SuperpowersPlanItemStatus;
|
|
@@ -157,10 +192,28 @@ export interface SuperpowersAcceptanceCriterion {
|
|
|
157
192
|
related_plan_items: string[];
|
|
158
193
|
required_proof_layers: string[];
|
|
159
194
|
assertion_requirements?: AssertionRequirement[];
|
|
195
|
+
assertion_command?: string;
|
|
196
|
+
assertion_artifacts?: string[];
|
|
197
|
+
positive_assertions?: string[];
|
|
198
|
+
negative_assertions?: string[];
|
|
199
|
+
machine_blocking?: boolean | null;
|
|
200
|
+
invalid_completion_signals?: string[];
|
|
201
|
+
assertion_result_required?: boolean | null;
|
|
202
|
+
ac_type?: string;
|
|
203
|
+
proof_chain?: string[];
|
|
160
204
|
required_test_ids?: string[];
|
|
161
205
|
fail_conditions?: string[];
|
|
162
206
|
invalid_evidence?: string[];
|
|
207
|
+
substitution_policy?: string[];
|
|
208
|
+
missing_layer_downgrade?: string;
|
|
209
|
+
auditor_expectation?: string;
|
|
210
|
+
out_of_scope_na_approval_source?: string;
|
|
211
|
+
hard_blockers?: string[];
|
|
212
|
+
validates_explanation?: string;
|
|
213
|
+
does_not_validate_explanation?: string;
|
|
163
214
|
final_evidence_expected?: string[];
|
|
215
|
+
verification_method?: string[];
|
|
216
|
+
test_cases?: string[];
|
|
164
217
|
explicit_no_test_scope?: boolean;
|
|
165
218
|
status: SuperpowersAcceptanceStatus;
|
|
166
219
|
}
|
|
@@ -168,6 +221,10 @@ export interface AssertionRequirement {
|
|
|
168
221
|
proof_layer: string;
|
|
169
222
|
required: boolean;
|
|
170
223
|
machine_blocking: boolean;
|
|
224
|
+
assertion_result_required?: boolean;
|
|
225
|
+
assertion_command?: string;
|
|
226
|
+
assertion_artifacts?: string[];
|
|
227
|
+
invalid_completion_signals?: string[];
|
|
171
228
|
required_test_ids: string[];
|
|
172
229
|
positive_assertions: string[];
|
|
173
230
|
negative_assertions: string[];
|
|
@@ -252,6 +309,8 @@ export interface NegativeEvidenceScan {
|
|
|
252
309
|
schema_version: "negative-evidence-scan-v1";
|
|
253
310
|
status: "passed" | "failed" | "blocked" | "stale";
|
|
254
311
|
target_ac_ids: string[];
|
|
312
|
+
target_proof_layers?: string[];
|
|
313
|
+
invalid_completion_signals_checked?: string[];
|
|
255
314
|
owner_surface?: string;
|
|
256
315
|
route?: string;
|
|
257
316
|
forbidden_findings: NegativeFinding[];
|