project-tiny-context-harness 0.2.81 → 0.2.83
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 +11 -3
- package/assets/README.md +11 -3
- package/assets/README.zh-CN.md +9 -1
- package/assets/protected-harness-baseline.json +18 -0
- package/assets/skills/composite-long-task-workflow/SKILL.md +21 -1
- package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +10 -0
- package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +6 -15
- package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +32 -15
- package/dist/commands/composite-long-task.js +45 -2
- package/dist/lib/superpowers-task-ac010.d.ts +6 -0
- package/dist/lib/superpowers-task-ac010.js +26 -0
- package/dist/lib/superpowers-task-assertion-normalizers.js +8 -1
- package/dist/lib/superpowers-task-assertions.js +35 -20
- package/dist/lib/superpowers-task-attempt.d.ts +4 -0
- package/dist/lib/superpowers-task-attempt.js +102 -0
- package/dist/lib/superpowers-task-command-specs.d.ts +3 -0
- package/dist/lib/superpowers-task-command-specs.js +52 -0
- package/dist/lib/superpowers-task-compile.d.ts +4 -1
- package/dist/lib/superpowers-task-compile.js +7 -1
- package/dist/lib/superpowers-task-contradictions.d.ts +6 -0
- package/dist/lib/superpowers-task-contradictions.js +126 -0
- package/dist/lib/superpowers-task-current-evidence.d.ts +3 -0
- package/dist/lib/superpowers-task-current-evidence.js +154 -0
- 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 +76 -1
- package/dist/lib/superpowers-task-evidence-kernel.d.ts +12 -0
- package/dist/lib/superpowers-task-evidence-kernel.js +351 -0
- package/dist/lib/superpowers-task-evidence-records.d.ts +2 -0
- package/dist/lib/superpowers-task-evidence-records.js +55 -0
- package/dist/lib/superpowers-task-evidence.d.ts +10 -0
- package/dist/lib/superpowers-task-evidence.js +141 -0
- package/dist/lib/superpowers-task-fields.d.ts +22 -0
- package/dist/lib/superpowers-task-fields.js +276 -0
- package/dist/lib/superpowers-task-gates.js +36 -24
- package/dist/lib/superpowers-task-harness-drift.d.ts +11 -0
- package/dist/lib/superpowers-task-harness-drift.js +86 -0
- package/dist/lib/superpowers-task-protected-baseline.d.ts +10 -0
- package/dist/lib/superpowers-task-protected-baseline.js +47 -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 +158 -3
- package/dist/lib/superpowers-task-state-schema.js +23 -1
- package/dist/lib/superpowers-task-state-shape.d.ts +3 -0
- package/dist/lib/superpowers-task-state-shape.js +50 -0
- package/dist/lib/superpowers-task-state.js +19 -39
- package/dist/lib/superpowers-task-status.js +11 -1
- package/dist/lib/superpowers-task-under-specified.d.ts +7 -0
- package/dist/lib/superpowers-task-under-specified.js +61 -0
- package/dist/lib/superpowers-task-validator.js +11 -37
- package/package.json +69 -69
- package/source-mappings.yaml +3 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isHarnessPath } from "./superpowers-task-harness-drift.js";
|
|
2
|
+
import { isRecord } from "./superpowers-task-state-schema.js";
|
|
3
|
+
export const PROTECTED_BASELINE_PATHS = [
|
|
4
|
+
"packages/ty-context/assets/protected-harness-baseline.json",
|
|
5
|
+
".codex/ty-context-managed/protected-harness-baseline.json",
|
|
6
|
+
"packages/ty-context/source-mappings.yaml",
|
|
7
|
+
"packages/ty-context/src/lib/superpowers-task-gates.ts",
|
|
8
|
+
"packages/ty-context/src/lib/superpowers-task-validator.ts",
|
|
9
|
+
"packages/ty-context/src/lib/superpowers-task-derive.ts",
|
|
10
|
+
"packages/ty-context/src/lib/superpowers-task-evidence.ts",
|
|
11
|
+
"packages/ty-context/src/lib/superpowers-task-evidence-kernel.ts",
|
|
12
|
+
"packages/ty-context/src/lib/superpowers-task-state-schema.ts",
|
|
13
|
+
".codex/ty-context-managed/skills/composite-long-task-workflow/SKILL.md",
|
|
14
|
+
".codex/ty-context-managed/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md",
|
|
15
|
+
"packages/ty-context/assets/skills/composite-long-task-workflow/SKILL.md",
|
|
16
|
+
"packages/ty-context/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md"
|
|
17
|
+
];
|
|
18
|
+
export function evaluateProtectedBaseline(state) {
|
|
19
|
+
const attempt = currentAttempt(state);
|
|
20
|
+
const changedFiles = [...new Set((attempt?.changed_files ?? []).map((file) => file.replace(/\\/g, "/")).filter(Boolean))];
|
|
21
|
+
const protectedChanges = changedFiles.filter(isProtectedBaselinePath);
|
|
22
|
+
const mode = attempt?.mode ?? "product_task";
|
|
23
|
+
const errors = [];
|
|
24
|
+
if (mode === "product_task" && protectedChanges.length > 0) {
|
|
25
|
+
errors.push(`protected_baseline_changed: product_task cannot change protected harness baseline paths: ${protectedChanges.join(", ")}`);
|
|
26
|
+
}
|
|
27
|
+
if (mode === "harness_task" && protectedChanges.length > 0 && !protectedBaselineReason(state)) {
|
|
28
|
+
errors.push("protected_baseline_reason_required: harness_task baseline changes must record gates.protected_baseline.reason");
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
protected_baseline_changed: protectedChanges.length > 0,
|
|
32
|
+
product_goal_complete: errors.length === 0,
|
|
33
|
+
changed_files: protectedChanges,
|
|
34
|
+
errors
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function isProtectedBaselinePath(file) {
|
|
38
|
+
const normalized = file.replace(/\\/g, "/");
|
|
39
|
+
return PROTECTED_BASELINE_PATHS.includes(normalized) || isHarnessPath(normalized);
|
|
40
|
+
}
|
|
41
|
+
function protectedBaselineReason(state) {
|
|
42
|
+
const baseline = state.gates?.protected_baseline;
|
|
43
|
+
return isRecord(baseline) && typeof baseline.reason === "string" && baseline.reason.trim().length > 0;
|
|
44
|
+
}
|
|
45
|
+
function currentAttempt(state) {
|
|
46
|
+
return (state.attempts ?? []).find((item) => item.task_attempt_id === state.current_attempt_id) ?? (state.attempts ?? []).at(-1);
|
|
47
|
+
}
|
|
@@ -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]) {
|
|
@@ -4,7 +4,7 @@ export declare const SUPERPOWERS_TASK_STATE_JSON_SCHEMA: {
|
|
|
4
4
|
readonly $id: "https://project-tiny-context-harness.local/superpowers-task-state.schema.json";
|
|
5
5
|
readonly title: "Superpowers Long-Task State";
|
|
6
6
|
readonly type: "object";
|
|
7
|
-
readonly required: readonly ["meta", "sources", "context", "delivery", "graph", "slices", "evidence", "gates", "progress", "blockers", "final"];
|
|
7
|
+
readonly required: readonly ["meta", "sources", "context", "delivery", "graph", "attempts", "current_attempt_id", "required_command_specs", "command_runs", "negative_evidence_records", "slices", "evidence", "gates", "progress", "blockers", "final"];
|
|
8
8
|
readonly properties: {
|
|
9
9
|
readonly meta: {
|
|
10
10
|
readonly type: "object";
|
|
@@ -33,6 +33,21 @@ export declare const SUPERPOWERS_TASK_STATE_JSON_SCHEMA: {
|
|
|
33
33
|
readonly graph: {
|
|
34
34
|
readonly type: "object";
|
|
35
35
|
};
|
|
36
|
+
readonly attempts: {
|
|
37
|
+
readonly type: "array";
|
|
38
|
+
};
|
|
39
|
+
readonly current_attempt_id: {
|
|
40
|
+
readonly type: "string";
|
|
41
|
+
};
|
|
42
|
+
readonly required_command_specs: {
|
|
43
|
+
readonly type: "array";
|
|
44
|
+
};
|
|
45
|
+
readonly command_runs: {
|
|
46
|
+
readonly type: "array";
|
|
47
|
+
};
|
|
48
|
+
readonly negative_evidence_records: {
|
|
49
|
+
readonly type: "array";
|
|
50
|
+
};
|
|
36
51
|
readonly slices: {
|
|
37
52
|
readonly type: "array";
|
|
38
53
|
};
|
|
@@ -55,10 +70,12 @@ export declare const SUPERPOWERS_TASK_STATE_JSON_SCHEMA: {
|
|
|
55
70
|
};
|
|
56
71
|
export type SuperpowersProofLayerStatus = "missing" | "satisfied" | "invalidated" | "blocked";
|
|
57
72
|
export type SuperpowersPlanItemStatus = "not_started" | "in_progress" | "complete" | "partial" | "blocked" | "invalidated" | "out_of_scope_NA";
|
|
58
|
-
export type SuperpowersAcceptanceStatus = "not_run" | "complete" | "partial" | "blocked" | "invalidated" | "out_of_scope_NA";
|
|
73
|
+
export type SuperpowersAcceptanceStatus = "not_run" | "complete" | "partial" | "blocked" | "invalidated" | "under_specified" | "out_of_scope_NA";
|
|
74
|
+
export type SuperpowersAttemptMode = "product_task" | "harness_task";
|
|
59
75
|
export type SuperpowersProductDeliveryScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "mixed_scope_requires_boundary";
|
|
60
76
|
export type SuperpowersPlanDeliveryScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "out_of_scope_backlog";
|
|
61
77
|
export type SuperpowersAcceptanceScope = "system_capability_build" | "representative_sample_validation" | "full_population_operation" | "full_population_not_required";
|
|
78
|
+
export type SuperpowersScopeFitDecision = "fit_for_three_inputs" | "selected_from_split" | "blocked_for_decision" | "";
|
|
62
79
|
export interface SuperpowersTaskState {
|
|
63
80
|
meta: {
|
|
64
81
|
task_id: string;
|
|
@@ -85,6 +102,11 @@ export interface SuperpowersTaskState {
|
|
|
85
102
|
proof_layers: Record<string, SuperpowersProofLayer>;
|
|
86
103
|
edges: SuperpowersGraphEdge[];
|
|
87
104
|
};
|
|
105
|
+
attempts: ExecutionAttempt[];
|
|
106
|
+
current_attempt_id: string;
|
|
107
|
+
required_command_specs: RequiredCommandSpec[];
|
|
108
|
+
command_runs: CommandRunRecord[];
|
|
109
|
+
negative_evidence_records: NegativeEvidenceRecord[];
|
|
88
110
|
slices: SuperpowersSliceRecord[];
|
|
89
111
|
evidence: SuperpowersEvidenceRecord[];
|
|
90
112
|
gates: Record<string, unknown>;
|
|
@@ -98,6 +120,60 @@ export interface SuperpowersTaskState {
|
|
|
98
120
|
next_required_actions?: string[];
|
|
99
121
|
};
|
|
100
122
|
}
|
|
123
|
+
export interface ExecutionAttempt {
|
|
124
|
+
task_attempt_id: string;
|
|
125
|
+
source_bundle_hash: string;
|
|
126
|
+
product_source_hash: string;
|
|
127
|
+
technical_plan_hash: string;
|
|
128
|
+
acceptance_checklist_hash: string;
|
|
129
|
+
git_head: string;
|
|
130
|
+
git_status_short: string;
|
|
131
|
+
tracked_diff_hash: string;
|
|
132
|
+
relevant_untracked_hash: string;
|
|
133
|
+
untracked_relevant_hash?: string;
|
|
134
|
+
worktree_fingerprint: string;
|
|
135
|
+
started_at: string;
|
|
136
|
+
ended_at: string | null;
|
|
137
|
+
finalized_at?: string | null;
|
|
138
|
+
required_command_specs_hash: string;
|
|
139
|
+
mode: SuperpowersAttemptMode;
|
|
140
|
+
changed_files?: string[];
|
|
141
|
+
}
|
|
142
|
+
export interface RequiredCommandSpec {
|
|
143
|
+
command_spec_id: string;
|
|
144
|
+
ac_id: string;
|
|
145
|
+
proof_layers: string[];
|
|
146
|
+
command: string;
|
|
147
|
+
assertion_artifacts: string[];
|
|
148
|
+
required_test_ids: string[];
|
|
149
|
+
machine_blocking: boolean;
|
|
150
|
+
assertion_result_required: boolean;
|
|
151
|
+
positive_assertions: string[];
|
|
152
|
+
negative_assertions: string[];
|
|
153
|
+
invalid_completion_signals: string[];
|
|
154
|
+
final_evidence_expected: string[];
|
|
155
|
+
}
|
|
156
|
+
export interface CommandRunRecord {
|
|
157
|
+
command_run_id: string;
|
|
158
|
+
task_attempt_id: string;
|
|
159
|
+
command_spec_id: string;
|
|
160
|
+
ac_id: string;
|
|
161
|
+
proof_layer: string;
|
|
162
|
+
command_line: string;
|
|
163
|
+
exit_code: number;
|
|
164
|
+
started_at: string;
|
|
165
|
+
ended_at: string;
|
|
166
|
+
artifact_paths: string[];
|
|
167
|
+
}
|
|
168
|
+
export interface NegativeEvidenceRecord {
|
|
169
|
+
negative_evidence_id: string;
|
|
170
|
+
task_attempt_id: string;
|
|
171
|
+
target_ac_ids: string[];
|
|
172
|
+
target_proof_layers: string[];
|
|
173
|
+
artifact_path: string;
|
|
174
|
+
artifact_sha256?: string;
|
|
175
|
+
status: "passed" | "failed" | "blocked" | "stale";
|
|
176
|
+
}
|
|
101
177
|
export interface SuperpowersSourceRecord {
|
|
102
178
|
path: string;
|
|
103
179
|
sha256: string;
|
|
@@ -113,6 +189,20 @@ export interface SuperpowersProductArchitectureScope {
|
|
|
113
189
|
representative_samples_validate: string[];
|
|
114
190
|
representative_samples_do_not_validate: string[];
|
|
115
191
|
out_of_scope_backlog: string[];
|
|
192
|
+
scope_fit_decision: SuperpowersScopeFitDecision;
|
|
193
|
+
selected_scope_fit_slice: string;
|
|
194
|
+
owner_boundary: string;
|
|
195
|
+
primary_capability_path: string;
|
|
196
|
+
non_completing_outcomes: string[];
|
|
197
|
+
assertion_policy: string;
|
|
198
|
+
source_authority: string;
|
|
199
|
+
product_goal: string;
|
|
200
|
+
surface_ia_lock?: string;
|
|
201
|
+
decision_lock?: string;
|
|
202
|
+
context_delta?: string;
|
|
203
|
+
source_to_context_coverage?: string;
|
|
204
|
+
acceptance_semantics?: string;
|
|
205
|
+
impact?: string;
|
|
116
206
|
}
|
|
117
207
|
export interface SuperpowersProgressState {
|
|
118
208
|
system_capability_progress: Record<string, unknown>;
|
|
@@ -131,13 +221,33 @@ export interface SuperpowersPlanItem {
|
|
|
131
221
|
representative_samples: string[];
|
|
132
222
|
full_population_boundary: string;
|
|
133
223
|
non_required_population: string[];
|
|
224
|
+
owner_boundary: string;
|
|
225
|
+
primary_capability_path: string;
|
|
226
|
+
trigger_contract: string;
|
|
227
|
+
state_transition_contract: string;
|
|
228
|
+
observable_result_contract: string;
|
|
229
|
+
assertion_support: string;
|
|
230
|
+
required_assertion_commands: string[];
|
|
231
|
+
invalid_implementation_shortcuts: string[];
|
|
134
232
|
owner_surfaces: string[];
|
|
135
233
|
forbidden_surfaces: string[];
|
|
136
234
|
implementation_paths: string[];
|
|
137
235
|
required_tests: string[];
|
|
138
236
|
proof_layer_ids?: string[];
|
|
237
|
+
requirement_ref?: string;
|
|
238
|
+
decision_id?: string;
|
|
239
|
+
api_schema_changes?: string;
|
|
240
|
+
state_machine?: string;
|
|
241
|
+
data_flow?: string;
|
|
242
|
+
worker_runtime_behavior?: string;
|
|
243
|
+
ui_ia_changes?: string;
|
|
244
|
+
migration_plan?: string;
|
|
245
|
+
evidence_artifacts?: string[];
|
|
139
246
|
non_completing_shortcuts?: string[];
|
|
140
247
|
substitution_policy?: string[];
|
|
248
|
+
drift_severity?: string;
|
|
249
|
+
partial_conditions?: string[];
|
|
250
|
+
blockers?: string[];
|
|
141
251
|
explicit_no_test_scope?: boolean;
|
|
142
252
|
context_fact_refs?: string[];
|
|
143
253
|
status: SuperpowersPlanItemStatus;
|
|
@@ -157,10 +267,28 @@ export interface SuperpowersAcceptanceCriterion {
|
|
|
157
267
|
related_plan_items: string[];
|
|
158
268
|
required_proof_layers: string[];
|
|
159
269
|
assertion_requirements?: AssertionRequirement[];
|
|
270
|
+
assertion_command?: string;
|
|
271
|
+
assertion_artifacts?: string[];
|
|
272
|
+
positive_assertions?: string[];
|
|
273
|
+
negative_assertions?: string[];
|
|
274
|
+
machine_blocking?: boolean | null;
|
|
275
|
+
invalid_completion_signals?: string[];
|
|
276
|
+
assertion_result_required?: boolean | null;
|
|
277
|
+
ac_type?: string;
|
|
278
|
+
proof_chain?: string[];
|
|
160
279
|
required_test_ids?: string[];
|
|
161
280
|
fail_conditions?: string[];
|
|
162
281
|
invalid_evidence?: string[];
|
|
282
|
+
substitution_policy?: string[];
|
|
283
|
+
missing_layer_downgrade?: string;
|
|
284
|
+
auditor_expectation?: string;
|
|
285
|
+
out_of_scope_na_approval_source?: string;
|
|
286
|
+
hard_blockers?: string[];
|
|
287
|
+
validates_explanation?: string;
|
|
288
|
+
does_not_validate_explanation?: string;
|
|
163
289
|
final_evidence_expected?: string[];
|
|
290
|
+
verification_method?: string[];
|
|
291
|
+
test_cases?: string[];
|
|
164
292
|
explicit_no_test_scope?: boolean;
|
|
165
293
|
status: SuperpowersAcceptanceStatus;
|
|
166
294
|
}
|
|
@@ -168,6 +296,10 @@ export interface AssertionRequirement {
|
|
|
168
296
|
proof_layer: string;
|
|
169
297
|
required: boolean;
|
|
170
298
|
machine_blocking: boolean;
|
|
299
|
+
assertion_result_required?: boolean;
|
|
300
|
+
assertion_command?: string;
|
|
301
|
+
assertion_artifacts?: string[];
|
|
302
|
+
invalid_completion_signals?: string[];
|
|
171
303
|
required_test_ids: string[];
|
|
172
304
|
positive_assertions: string[];
|
|
173
305
|
negative_assertions: string[];
|
|
@@ -201,7 +333,24 @@ export interface SuperpowersSliceRecord {
|
|
|
201
333
|
};
|
|
202
334
|
}
|
|
203
335
|
export interface SuperpowersEvidenceRecord {
|
|
336
|
+
schema_version?: "evidence-record-v1" | "evidence-record-v2" | string;
|
|
204
337
|
evidence_id: string;
|
|
338
|
+
task_attempt_id?: string;
|
|
339
|
+
source_bundle_hash?: string;
|
|
340
|
+
product_source_hash?: string;
|
|
341
|
+
technical_plan_hash?: string;
|
|
342
|
+
acceptance_checklist_hash?: string;
|
|
343
|
+
git_head?: string;
|
|
344
|
+
worktree_fingerprint?: string;
|
|
345
|
+
command_spec_id?: string;
|
|
346
|
+
command_run_id?: string;
|
|
347
|
+
command_line?: string;
|
|
348
|
+
artifact_path?: string;
|
|
349
|
+
artifact_sha256?: string;
|
|
350
|
+
artifact_mtime?: string;
|
|
351
|
+
target_ac_ids?: string[];
|
|
352
|
+
target_pi_ids?: string[];
|
|
353
|
+
target_proof_layers?: string[];
|
|
205
354
|
slice_id: string;
|
|
206
355
|
type: string;
|
|
207
356
|
freshness: {
|
|
@@ -228,17 +377,21 @@ export interface SuperpowersEvidenceRecord {
|
|
|
228
377
|
sibling_substitution_approval_source?: string;
|
|
229
378
|
}
|
|
230
379
|
export interface AssertionResult {
|
|
231
|
-
schema_version: "assertion-result-v1";
|
|
380
|
+
schema_version: "assertion-result-v1" | "assertion-result-v2";
|
|
232
381
|
status: "passed" | "failed" | "blocked" | "stale";
|
|
233
382
|
runner: string;
|
|
234
383
|
exit_code: number;
|
|
235
384
|
target_ac_ids: string[];
|
|
385
|
+
target_pi_ids?: string[];
|
|
236
386
|
target_proof_layers: string[];
|
|
237
387
|
owner_surface?: string;
|
|
238
388
|
route?: string;
|
|
239
389
|
action?: string;
|
|
240
390
|
positive_assertions: AssertionCheck[];
|
|
241
391
|
negative_assertions: AssertionCheck[];
|
|
392
|
+
invalid_completion_signals?: AssertionCheck[];
|
|
393
|
+
negative_evidence_scan?: NegativeEvidenceScan;
|
|
394
|
+
required_test_ids?: string[];
|
|
242
395
|
artifacts?: string[];
|
|
243
396
|
}
|
|
244
397
|
export interface AssertionCheck {
|
|
@@ -252,6 +405,8 @@ export interface NegativeEvidenceScan {
|
|
|
252
405
|
schema_version: "negative-evidence-scan-v1";
|
|
253
406
|
status: "passed" | "failed" | "blocked" | "stale";
|
|
254
407
|
target_ac_ids: string[];
|
|
408
|
+
target_proof_layers?: string[];
|
|
409
|
+
invalid_completion_signals_checked?: string[];
|
|
255
410
|
owner_surface?: string;
|
|
256
411
|
route?: string;
|
|
257
412
|
forbidden_findings: NegativeFinding[];
|
|
@@ -4,7 +4,24 @@ export const SUPERPOWERS_TASK_STATE_JSON_SCHEMA = {
|
|
|
4
4
|
$id: "https://project-tiny-context-harness.local/superpowers-task-state.schema.json",
|
|
5
5
|
title: "Superpowers Long-Task State",
|
|
6
6
|
type: "object",
|
|
7
|
-
required: [
|
|
7
|
+
required: [
|
|
8
|
+
"meta",
|
|
9
|
+
"sources",
|
|
10
|
+
"context",
|
|
11
|
+
"delivery",
|
|
12
|
+
"graph",
|
|
13
|
+
"attempts",
|
|
14
|
+
"current_attempt_id",
|
|
15
|
+
"required_command_specs",
|
|
16
|
+
"command_runs",
|
|
17
|
+
"negative_evidence_records",
|
|
18
|
+
"slices",
|
|
19
|
+
"evidence",
|
|
20
|
+
"gates",
|
|
21
|
+
"progress",
|
|
22
|
+
"blockers",
|
|
23
|
+
"final"
|
|
24
|
+
],
|
|
8
25
|
properties: {
|
|
9
26
|
meta: {
|
|
10
27
|
type: "object",
|
|
@@ -19,6 +36,11 @@ export const SUPERPOWERS_TASK_STATE_JSON_SCHEMA = {
|
|
|
19
36
|
context: { type: "object" },
|
|
20
37
|
delivery: { type: "object" },
|
|
21
38
|
graph: { type: "object" },
|
|
39
|
+
attempts: { type: "array" },
|
|
40
|
+
current_attempt_id: { type: "string" },
|
|
41
|
+
required_command_specs: { type: "array" },
|
|
42
|
+
command_runs: { type: "array" },
|
|
43
|
+
negative_evidence_records: { type: "array" },
|
|
22
44
|
slices: { type: "array" },
|
|
23
45
|
evidence: { type: "array" },
|
|
24
46
|
gates: { type: "object" },
|