project-tiny-context-harness 0.7.3 → 0.7.5
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/LICENSE +21 -21
- package/README.md +355 -343
- package/assets/README.md +539 -494
- package/assets/README.zh-CN.md +300 -273
- package/assets/agents/.gitkeep +1 -1
- package/assets/agents/AGENTS_CORE.md +55 -53
- package/assets/context_templates/architecture.md +33 -33
- package/assets/context_templates/area.md +39 -39
- package/assets/context_templates/context.toml +30 -30
- package/assets/context_templates/deployment.md +35 -35
- package/assets/context_templates/global.md +51 -51
- package/assets/context_templates/product-surface-contract.md +64 -57
- package/assets/context_templates/screen-contract.md +180 -0
- package/assets/context_templates/verification.md +32 -32
- package/assets/github/.gitkeep +1 -1
- package/assets/github/harness.yml +41 -41
- package/assets/make/.gitkeep +1 -1
- package/assets/make/ty-context.mk +48 -48
- package/assets/skills/context_development_engineer/SKILL.md +92 -90
- package/assets/skills/context_full_project_export/SKILL.md +70 -70
- package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
- package/assets/skills/context_product_plan/SKILL.md +77 -76
- package/assets/skills/context_surface_contract/SKILL.md +177 -162
- package/assets/skills/context_uiux_design/SKILL.md +108 -91
- package/assets/skills/long-task-workflow/SKILL.md +83 -83
- package/assets/skills/long-task-workflow/agents/openai.yaml +4 -4
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +57 -53
- package/assets/skills/long-task-workflow/references/contract-authoring.md +95 -77
- package/assets/skills/long-task-workflow/references/evidence-design.md +71 -58
- package/assets/skills/normal-long-task/SKILL.md +12 -12
- package/assets/skills/source-plan-authoring/SKILL.md +293 -290
- package/dist/commands/long-task-authoring.js +25 -0
- package/dist/commands/long-task.js +3 -0
- package/dist/lib/design-md.d.ts +7 -0
- package/dist/lib/design-md.js +47 -6
- package/dist/lib/doctor.js +19 -4
- package/dist/lib/long-task-activation-validation.js +13 -2
- package/dist/lib/long-task-authoring-authority-preview.js +1 -0
- package/dist/lib/long-task-authority-material-diff.js +54 -0
- package/dist/lib/long-task-authority-materials.d.ts +2 -2
- package/dist/lib/long-task-authority-materials.js +20 -0
- package/dist/lib/long-task-authority-policy.d.ts +26 -0
- package/dist/lib/long-task-authority-policy.js +23 -0
- package/dist/lib/long-task-authority-revision-analysis.d.ts +33 -0
- package/dist/lib/long-task-authority-revision-analysis.js +91 -0
- package/dist/lib/long-task-authority-revision.js +93 -158
- package/dist/lib/long-task-authority-types.d.ts +21 -0
- package/dist/lib/long-task-authority.js +32 -3
- package/dist/lib/long-task-check-evidence-decoder.d.ts +2 -2
- package/dist/lib/long-task-check-evidence-decoder.js +11 -1
- package/dist/lib/long-task-check-execution-policy.d.ts +3 -0
- package/dist/lib/long-task-check-execution-policy.js +5 -0
- package/dist/lib/long-task-check-runner.js +2 -0
- package/dist/lib/long-task-check-shape.js +33 -3
- package/dist/lib/long-task-claim-definitions.js +14 -0
- package/dist/lib/long-task-conformance-policy.d.ts +5 -0
- package/dist/lib/long-task-conformance-policy.js +35 -0
- package/dist/lib/long-task-contract-types.d.ts +28 -4
- package/dist/lib/long-task-delivery-compiler.js +1 -0
- package/dist/lib/long-task-delivery-parser.js +5 -2
- package/dist/lib/long-task-delivery-types.d.ts +2 -0
- package/dist/lib/long-task-delivery-types.js +2 -0
- package/dist/lib/long-task-delivery-validation.js +11 -0
- package/dist/lib/long-task-evidence-capability-codec.d.ts +2 -0
- package/dist/lib/long-task-evidence-capability-codec.js +231 -0
- package/dist/lib/long-task-evidence-capability-policy.d.ts +8 -0
- package/dist/lib/long-task-evidence-capability-policy.js +147 -0
- package/dist/lib/long-task-evidence-capability-runtime.d.ts +2 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +86 -0
- package/dist/lib/long-task-evidence-capability-types.d.ts +74 -0
- package/dist/lib/long-task-evidence-capability-types.js +1 -0
- package/dist/lib/long-task-evidence-findings.js +5 -1
- package/dist/lib/long-task-evidence-v2.js +38 -23
- package/dist/lib/long-task-final-v2.js +42 -1
- package/dist/lib/long-task-outcome-parser.js +14 -3
- package/dist/lib/long-task-playwright-evidence.d.ts +2 -1
- package/dist/lib/long-task-playwright-evidence.js +70 -2
- package/dist/lib/long-task-product-shape.js +28 -0
- package/dist/lib/long-task-progress.js +4 -0
- package/dist/lib/long-task-root-shape.d.ts +1 -0
- package/dist/lib/long-task-root-shape.js +84 -3
- package/dist/lib/long-task-runner-environment.js +1 -1
- package/dist/lib/long-task-runner-freeze.d.ts +2 -2
- package/dist/lib/long-task-runner-freeze.js +3 -1
- package/dist/lib/long-task-runtime-types.d.ts +13 -0
- package/dist/lib/long-task-semantic-contract-types.d.ts +36 -0
- package/dist/lib/long-task-semantic-contract-types.js +1 -0
- package/dist/lib/long-task-semantic-drift-migration.d.ts +3 -0
- package/dist/lib/long-task-semantic-drift-migration.js +68 -0
- package/dist/lib/long-task-shape-primitives.d.ts +3 -0
- package/dist/lib/long-task-shape-primitives.js +25 -0
- package/dist/lib/long-task-source-target-index.js +14 -0
- package/dist/lib/long-task-stage-policy.d.ts +4 -0
- package/dist/lib/long-task-stage-policy.js +120 -0
- package/dist/lib/long-task-status-projection.d.ts +4 -1
- package/dist/lib/long-task-status-projection.js +63 -3
- package/dist/lib/long-task-status-v2.d.ts +11 -1
- package/dist/lib/long-task-status-v2.js +25 -3
- package/dist/lib/long-task-target-policy.d.ts +6 -0
- package/dist/lib/long-task-target-policy.js +127 -0
- package/dist/lib/migrations.js +29 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +62 -8
- package/migrations/README.md +15 -8
- package/package.json +2 -2
- package/source-mappings.yaml +25 -25
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { addedInputPaths, addedVerificationInputs, bindingReductions, changedRunnerFields, counterfactualReductions, expandedPatterns, globalCounterfactualReductions, obligationReductions, removedExactValues, removedGlobalForbiddenPaths, removedOrNarrowedInputPaths, removedOrReplacedVerificationInputs, removedOrWeakenedExpectedOutputPaths, removedStructuredValues, rollbackReductions, same, } from "./long-task-authority-revision-details.js";
|
|
2
|
+
export function analyzeCheckRevisions(beforeChecks, afterChecks) {
|
|
3
|
+
const result = {
|
|
4
|
+
negative_assertions_removed: [],
|
|
5
|
+
proof_surfaces_changed: [],
|
|
6
|
+
runner_definitions_changed: [],
|
|
7
|
+
verification_inputs_added: [],
|
|
8
|
+
verification_inputs_removed_or_replaced: [],
|
|
9
|
+
input_paths_added: [],
|
|
10
|
+
input_paths_removed_or_narrowed: [],
|
|
11
|
+
expected_output_paths_removed_or_weakened: [],
|
|
12
|
+
artifacts_removed: [],
|
|
13
|
+
environment_requirements_removed: [],
|
|
14
|
+
};
|
|
15
|
+
for (const [identity, before] of beforeChecks) {
|
|
16
|
+
const after = afterChecks.get(identity);
|
|
17
|
+
if (!after)
|
|
18
|
+
continue;
|
|
19
|
+
for (const assertion of before.negative_assertions)
|
|
20
|
+
if (!after.negative_assertions.some((item) => same(item, assertion)))
|
|
21
|
+
result.negative_assertions_removed.push(`${identity}:${assertion.key}`);
|
|
22
|
+
if (before.proof_surface !== after.proof_surface)
|
|
23
|
+
result.proof_surfaces_changed.push(`${identity}:${before.proof_surface}->${after.proof_surface}`);
|
|
24
|
+
result.runner_definitions_changed.push(...changedRunnerFields(identity, before, after));
|
|
25
|
+
result.verification_inputs_added.push(...addedVerificationInputs(identity, before, after));
|
|
26
|
+
result.verification_inputs_removed_or_replaced.push(...removedOrReplacedVerificationInputs(identity, before, after));
|
|
27
|
+
result.input_paths_added.push(...addedInputPaths(identity, before, after));
|
|
28
|
+
result.input_paths_removed_or_narrowed.push(...removedOrNarrowedInputPaths(identity, before, after));
|
|
29
|
+
result.expected_output_paths_removed_or_weakened.push(...removedOrWeakenedExpectedOutputPaths(identity, before, after));
|
|
30
|
+
result.artifacts_removed.push(...removedExactValues(identity, before.artifact_globs, after.artifact_globs));
|
|
31
|
+
result.environment_requirements_removed.push(...removedStructuredValues(identity, before.environment_requirements, after.environment_requirements));
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
export function analyzeOutcomeRevisions(previous, next) {
|
|
36
|
+
const result = {
|
|
37
|
+
owner_paths_expanded: [],
|
|
38
|
+
owner_context_refs_removed: [],
|
|
39
|
+
expected_change_paths_expanded: [],
|
|
40
|
+
allowed_paths_expanded: [],
|
|
41
|
+
forbidden_paths_removed: removedGlobalForbiddenPaths(previous, next),
|
|
42
|
+
bindings_removed_or_expanded: [],
|
|
43
|
+
obligations_removed_or_weakened: [],
|
|
44
|
+
rollback_or_recovery_weakened: [],
|
|
45
|
+
counterfactuals_removed: globalCounterfactualReductions(previous, next),
|
|
46
|
+
population_weakened: [],
|
|
47
|
+
};
|
|
48
|
+
const previousOutcomes = new Map(previous.outcomes.map((outcome) => [outcome.key, outcome]));
|
|
49
|
+
for (const after of next.outcomes) {
|
|
50
|
+
const before = previousOutcomes.get(after.key);
|
|
51
|
+
if (!before)
|
|
52
|
+
continue;
|
|
53
|
+
result.owner_paths_expanded.push(...expandedPatterns(after.key, before.product.owner.path_globs, after.product.owner.path_globs));
|
|
54
|
+
result.owner_context_refs_removed.push(...removedExactValues(after.key, before.product.owner.context_refs, after.product.owner.context_refs));
|
|
55
|
+
result.expected_change_paths_expanded.push(...expandedPatterns(after.key, before.technical.expected_change_paths, after.technical.expected_change_paths));
|
|
56
|
+
result.allowed_paths_expanded.push(...expandedPatterns(after.key, before.technical.allowed_support_paths, after.technical.allowed_support_paths));
|
|
57
|
+
result.forbidden_paths_removed.push(...removedExactValues(after.key, before.technical.forbidden_paths, after.technical.forbidden_paths));
|
|
58
|
+
result.bindings_removed_or_expanded.push(...bindingReductions(before, after));
|
|
59
|
+
result.obligations_removed_or_weakened.push(...obligationReductions(before, after));
|
|
60
|
+
result.rollback_or_recovery_weakened.push(...rollbackReductions(before, after));
|
|
61
|
+
result.counterfactuals_removed.push(...counterfactualReductions(before, after));
|
|
62
|
+
if (before.acceptance.population &&
|
|
63
|
+
(!after.acceptance.population ||
|
|
64
|
+
!same(before.acceptance.population, after.acceptance.population)))
|
|
65
|
+
result.population_weakened.push(after.key);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
export function keyedAuthorityChanges(before, after) {
|
|
70
|
+
const beforeByKey = new Map(before.map((item) => [item.key, item]));
|
|
71
|
+
const afterByKey = new Map(after.map((item) => [item.key, item]));
|
|
72
|
+
return [
|
|
73
|
+
...before
|
|
74
|
+
.filter((item) => !afterByKey.has(item.key))
|
|
75
|
+
.map((item) => `${item.key}:removed`),
|
|
76
|
+
...after
|
|
77
|
+
.filter((item) => !beforeByKey.has(item.key))
|
|
78
|
+
.map((item) => `${item.key}:added`),
|
|
79
|
+
...before
|
|
80
|
+
.filter((item) => {
|
|
81
|
+
const candidate = afterByKey.get(item.key);
|
|
82
|
+
return candidate !== undefined && !same(item, candidate);
|
|
83
|
+
})
|
|
84
|
+
.map((item) => `${item.key}:changed`),
|
|
85
|
+
].sort();
|
|
86
|
+
}
|
|
87
|
+
export function selectedRevisionReasons(entries) {
|
|
88
|
+
return entries
|
|
89
|
+
.filter(([, changed]) => Array.isArray(changed) ? changed.length > 0 : changed)
|
|
90
|
+
.map(([reason]) => reason);
|
|
91
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { acceptanceSemanticsChanged, isMonotonicAcceptanceStrengthening, } from "./long-task-authority.js";
|
|
2
2
|
import { authorityMaterialRevisionDiff, changedProductClaimSemantics, sourceClaimAdditions, } from "./long-task-authority-material-diff.js";
|
|
3
|
+
import { analyzeCheckRevisions, analyzeOutcomeRevisions, keyedAuthorityChanges, selectedRevisionReasons, } from "./long-task-authority-revision-analysis.js";
|
|
4
|
+
import { addedValues, checkIndex, removedExactValues, removedValues, sourceClaimReductions, } from "./long-task-authority-revision-details.js";
|
|
3
5
|
import { compileProductClaimCoverage } from "./long-task-claims.js";
|
|
4
|
-
import { addedInputPaths, addedVerificationInputs, addedValues, bindingReductions, changedRunnerFields, checkIndex, counterfactualReductions, expandedPatterns, globalCounterfactualReductions, obligationReductions, removedExactValues, removedGlobalForbiddenPaths, removedOrNarrowedInputPaths, removedOrReplacedVerificationInputs, removedOrWeakenedExpectedOutputPaths, removedStructuredValues, removedValues, rollbackReductions, same, sourceClaimReductions, } from "./long-task-authority-revision-details.js";
|
|
5
6
|
import { verifierAuthorityDiff } from "./long-task-verifier-authority.js";
|
|
6
7
|
export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials, nextGlobalChecks, nextOutcomes, nextVerifier) {
|
|
7
8
|
const materialDiff = authorityMaterialRevisionDiff(previous, nextMaterials);
|
|
@@ -16,67 +17,12 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
16
17
|
const productClaimsAdded = addedValues(beforeClaimIds, afterClaimIds);
|
|
17
18
|
const productClaimsChanged = changedProductClaimSemantics(previous, next);
|
|
18
19
|
const checksRemoved = removedValues(new Set(beforeChecks.keys()), new Set(afterChecks.keys()));
|
|
19
|
-
const
|
|
20
|
-
const proofSurfacesChanged = [];
|
|
21
|
-
const runnerDefinitionsChanged = [];
|
|
22
|
-
const verificationInputsAdded = [];
|
|
23
|
-
const verificationInputsRemovedOrReplaced = [];
|
|
24
|
-
const inputPathsAdded = [];
|
|
25
|
-
const inputPathsRemovedOrNarrowed = [];
|
|
26
|
-
const expectedOutputPathsRemovedOrWeakened = [];
|
|
27
|
-
const artifactsRemoved = [];
|
|
28
|
-
const environmentRequirementsRemoved = [];
|
|
29
|
-
for (const [identity, before] of beforeChecks) {
|
|
30
|
-
const after = afterChecks.get(identity);
|
|
31
|
-
if (!after)
|
|
32
|
-
continue;
|
|
33
|
-
for (const assertion of before.negative_assertions)
|
|
34
|
-
if (!after.negative_assertions.some((item) => same(item, assertion)))
|
|
35
|
-
negativeAssertionsRemoved.push(`${identity}:${assertion.key}`);
|
|
36
|
-
if (before.proof_surface !== after.proof_surface)
|
|
37
|
-
proofSurfacesChanged.push(`${identity}:${before.proof_surface}->${after.proof_surface}`);
|
|
38
|
-
runnerDefinitionsChanged.push(...changedRunnerFields(identity, before, after));
|
|
39
|
-
verificationInputsAdded.push(...addedVerificationInputs(identity, before, after));
|
|
40
|
-
verificationInputsRemovedOrReplaced.push(...removedOrReplacedVerificationInputs(identity, before, after));
|
|
41
|
-
inputPathsAdded.push(...addedInputPaths(identity, before, after));
|
|
42
|
-
inputPathsRemovedOrNarrowed.push(...removedOrNarrowedInputPaths(identity, before, after));
|
|
43
|
-
expectedOutputPathsRemovedOrWeakened.push(...removedOrWeakenedExpectedOutputPaths(identity, before, after));
|
|
44
|
-
artifactsRemoved.push(...removedExactValues(identity, before.artifact_globs, after.artifact_globs));
|
|
45
|
-
environmentRequirementsRemoved.push(...removedStructuredValues(identity, before.environment_requirements, after.environment_requirements));
|
|
46
|
-
}
|
|
20
|
+
const checkChanges = analyzeCheckRevisions(beforeChecks, afterChecks);
|
|
47
21
|
const sourceClaimsRemovedOrChanged = sourceClaimReductions(previous.source_claims, next.source_claims);
|
|
48
22
|
const sourceClaimsAdded = sourceClaimAdditions(previous.source_claims, next.source_claims);
|
|
49
23
|
const sourcePathsRemovedOrReplaced = removedExactValues("task", previous.task.source_paths, next.task.source_paths);
|
|
50
|
-
const
|
|
51
|
-
const ownerContextRefsRemoved = [];
|
|
52
|
-
const expectedChangePathsExpanded = [];
|
|
53
|
-
const allowedPathsExpanded = [];
|
|
54
|
-
const forbiddenPathsRemoved = removedGlobalForbiddenPaths(previous, next);
|
|
55
|
-
const bindingsRemovedOrExpanded = [];
|
|
56
|
-
const obligationsRemovedOrWeakened = [];
|
|
57
|
-
const rollbackOrRecoveryWeakened = [];
|
|
58
|
-
const counterfactualsRemoved = globalCounterfactualReductions(previous, next);
|
|
59
|
-
const populationWeakened = [];
|
|
24
|
+
const outcomeChanges = analyzeOutcomeRevisions(previous, next);
|
|
60
25
|
const verifierDiff = verifierAuthorityDiff(previous.verifier_identity, nextVerifier);
|
|
61
|
-
const previousOutcomes = new Map(previous.outcomes.map((outcome) => [outcome.key, outcome]));
|
|
62
|
-
for (const after of next.outcomes) {
|
|
63
|
-
const before = previousOutcomes.get(after.key);
|
|
64
|
-
if (!before)
|
|
65
|
-
continue;
|
|
66
|
-
ownerPathsExpanded.push(...expandedPatterns(after.key, before.product.owner.path_globs, after.product.owner.path_globs));
|
|
67
|
-
ownerContextRefsRemoved.push(...removedExactValues(after.key, before.product.owner.context_refs, after.product.owner.context_refs));
|
|
68
|
-
expectedChangePathsExpanded.push(...expandedPatterns(after.key, before.technical.expected_change_paths, after.technical.expected_change_paths));
|
|
69
|
-
allowedPathsExpanded.push(...expandedPatterns(after.key, before.technical.allowed_support_paths, after.technical.allowed_support_paths));
|
|
70
|
-
forbiddenPathsRemoved.push(...removedExactValues(after.key, before.technical.forbidden_paths, after.technical.forbidden_paths));
|
|
71
|
-
bindingsRemovedOrExpanded.push(...bindingReductions(before, after));
|
|
72
|
-
obligationsRemovedOrWeakened.push(...obligationReductions(before, after));
|
|
73
|
-
rollbackOrRecoveryWeakened.push(...rollbackReductions(before, after));
|
|
74
|
-
counterfactualsRemoved.push(...counterfactualReductions(before, after));
|
|
75
|
-
if (before.acceptance.population &&
|
|
76
|
-
(!after.acceptance.population ||
|
|
77
|
-
!same(before.acceptance.population, after.acceptance.population)))
|
|
78
|
-
populationWeakened.push(after.key);
|
|
79
|
-
}
|
|
80
26
|
const riskChanged = previous.authority_hashes.risk_authority_hash !==
|
|
81
27
|
nextHashes.risk_authority_hash;
|
|
82
28
|
const acceptanceChanged = acceptanceSemanticsChanged(previous, next);
|
|
@@ -84,57 +30,64 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
84
30
|
const externalConfirmationsChanged = externalConfirmationChanges.length > 0;
|
|
85
31
|
const monotonic = isMonotonicAcceptanceStrengthening(previous, next);
|
|
86
32
|
const reductionReasons = [
|
|
87
|
-
...(
|
|
88
|
-
|
|
89
|
-
|
|
33
|
+
...selectedRevisionReasons([
|
|
34
|
+
["product_claim_added", productClaimsAdded],
|
|
35
|
+
["product_claim_removed", productClaimsRemoved],
|
|
36
|
+
["product_claim_changed", productClaimsChanged],
|
|
37
|
+
]),
|
|
90
38
|
...materialDiff.reduction_reasons,
|
|
91
|
-
...(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
39
|
+
...selectedRevisionReasons([
|
|
40
|
+
["check_removed", checksRemoved],
|
|
41
|
+
["negative_assertion_removed", checkChanges.negative_assertions_removed],
|
|
42
|
+
["proof_surface_changed", checkChanges.proof_surfaces_changed],
|
|
43
|
+
["source_claim_removed_or_changed", sourceClaimsRemovedOrChanged],
|
|
44
|
+
["source_claim_added", sourceClaimsAdded],
|
|
45
|
+
["source_path_removed_or_replaced", sourcePathsRemovedOrReplaced],
|
|
46
|
+
["owner_path_expanded", outcomeChanges.owner_paths_expanded],
|
|
47
|
+
["owner_context_ref_removed", outcomeChanges.owner_context_refs_removed],
|
|
48
|
+
[
|
|
49
|
+
"expected_change_path_expanded",
|
|
50
|
+
outcomeChanges.expected_change_paths_expanded,
|
|
51
|
+
],
|
|
52
|
+
["allowed_path_expanded", outcomeChanges.allowed_paths_expanded],
|
|
53
|
+
["forbidden_path_removed", outcomeChanges.forbidden_paths_removed],
|
|
54
|
+
["runner_definition_changed", checkChanges.runner_definitions_changed],
|
|
55
|
+
[
|
|
56
|
+
"verification_input_removed_or_replaced",
|
|
57
|
+
checkChanges.verification_inputs_removed_or_replaced,
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"input_path_coverage_reduced",
|
|
61
|
+
checkChanges.input_paths_removed_or_narrowed,
|
|
62
|
+
],
|
|
63
|
+
[
|
|
64
|
+
"expected_output_requirement_weakened",
|
|
65
|
+
checkChanges.expected_output_paths_removed_or_weakened,
|
|
66
|
+
],
|
|
67
|
+
["artifact_removed", checkChanges.artifacts_removed],
|
|
68
|
+
[
|
|
69
|
+
"environment_requirement_removed",
|
|
70
|
+
checkChanges.environment_requirements_removed,
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"binding_removed_or_expanded",
|
|
74
|
+
outcomeChanges.bindings_removed_or_expanded,
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
"obligation_removed_or_weakened",
|
|
78
|
+
outcomeChanges.obligations_removed_or_weakened,
|
|
79
|
+
],
|
|
80
|
+
[
|
|
81
|
+
"rollback_or_recovery_weakened",
|
|
82
|
+
outcomeChanges.rollback_or_recovery_weakened,
|
|
83
|
+
],
|
|
84
|
+
["counterfactual_removed", outcomeChanges.counterfactuals_removed],
|
|
85
|
+
["population_weakened", outcomeChanges.population_weakened],
|
|
86
|
+
["verifier_content_changed", verifierDiff.verifier_content_changed],
|
|
87
|
+
["risk_changed_requires_review", riskChanged],
|
|
88
|
+
["external_confirmation_changed", externalConfirmationsChanged],
|
|
89
|
+
["acceptance_not_monotonic", acceptanceChanged && !monotonic],
|
|
90
|
+
]),
|
|
138
91
|
];
|
|
139
92
|
return {
|
|
140
93
|
product_claims_added: productClaimsAdded,
|
|
@@ -144,8 +97,8 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
144
97
|
global_semantics_changed: materialDiff.global_semantics_changed,
|
|
145
98
|
checks_added: addedValues(new Set(beforeChecks.keys()), new Set(afterChecks.keys())),
|
|
146
99
|
checks_removed: checksRemoved,
|
|
147
|
-
negative_assertions_removed:
|
|
148
|
-
proof_surfaces_changed:
|
|
100
|
+
negative_assertions_removed: checkChanges.negative_assertions_removed,
|
|
101
|
+
proof_surfaces_changed: checkChanges.proof_surfaces_changed,
|
|
149
102
|
source_claims_added: sourceClaimsAdded,
|
|
150
103
|
source_claims_removed_or_changed: sourceClaimsRemovedOrChanged,
|
|
151
104
|
source_paths_removed_or_replaced: sourcePathsRemovedOrReplaced,
|
|
@@ -157,60 +110,42 @@ export function authorityRevisionDiff(previous, next, nextHashes, nextMaterials,
|
|
|
157
110
|
context_files_added: materialDiff.context_files_added,
|
|
158
111
|
context_files_removed: materialDiff.context_files_removed,
|
|
159
112
|
context_files_changed: materialDiff.context_files_changed,
|
|
160
|
-
owner_paths_expanded:
|
|
161
|
-
owner_context_refs_removed:
|
|
162
|
-
expected_change_paths_expanded:
|
|
163
|
-
allowed_paths_expanded:
|
|
164
|
-
forbidden_paths_removed:
|
|
165
|
-
runner_definitions_changed:
|
|
166
|
-
verification_inputs_added:
|
|
167
|
-
verification_inputs_removed_or_replaced:
|
|
168
|
-
input_paths_added:
|
|
169
|
-
input_paths_removed_or_narrowed:
|
|
170
|
-
expected_output_paths_removed_or_weakened:
|
|
171
|
-
artifacts_removed:
|
|
172
|
-
environment_requirements_removed:
|
|
173
|
-
bindings_removed_or_expanded:
|
|
174
|
-
obligations_removed_or_weakened:
|
|
175
|
-
rollback_or_recovery_weakened:
|
|
176
|
-
counterfactuals_removed:
|
|
177
|
-
population_weakened:
|
|
113
|
+
owner_paths_expanded: outcomeChanges.owner_paths_expanded,
|
|
114
|
+
owner_context_refs_removed: outcomeChanges.owner_context_refs_removed,
|
|
115
|
+
expected_change_paths_expanded: outcomeChanges.expected_change_paths_expanded,
|
|
116
|
+
allowed_paths_expanded: outcomeChanges.allowed_paths_expanded,
|
|
117
|
+
forbidden_paths_removed: outcomeChanges.forbidden_paths_removed,
|
|
118
|
+
runner_definitions_changed: checkChanges.runner_definitions_changed,
|
|
119
|
+
verification_inputs_added: checkChanges.verification_inputs_added,
|
|
120
|
+
verification_inputs_removed_or_replaced: checkChanges.verification_inputs_removed_or_replaced,
|
|
121
|
+
input_paths_added: checkChanges.input_paths_added,
|
|
122
|
+
input_paths_removed_or_narrowed: checkChanges.input_paths_removed_or_narrowed,
|
|
123
|
+
expected_output_paths_removed_or_weakened: checkChanges.expected_output_paths_removed_or_weakened,
|
|
124
|
+
artifacts_removed: checkChanges.artifacts_removed,
|
|
125
|
+
environment_requirements_removed: checkChanges.environment_requirements_removed,
|
|
126
|
+
bindings_removed_or_expanded: outcomeChanges.bindings_removed_or_expanded,
|
|
127
|
+
obligations_removed_or_weakened: outcomeChanges.obligations_removed_or_weakened,
|
|
128
|
+
rollback_or_recovery_weakened: outcomeChanges.rollback_or_recovery_weakened,
|
|
129
|
+
counterfactuals_removed: outcomeChanges.counterfactuals_removed,
|
|
130
|
+
population_weakened: outcomeChanges.population_weakened,
|
|
178
131
|
external_confirmations_changed: externalConfirmationsChanged,
|
|
179
132
|
external_confirmation_changes: externalConfirmationChanges,
|
|
180
133
|
...verifierDiff,
|
|
181
134
|
source_claims_changed: previous.authority_hashes.source_authority_hash !==
|
|
182
135
|
nextHashes.source_authority_hash,
|
|
183
136
|
risk_changed: riskChanged,
|
|
184
|
-
owner_or_path_boundary_changed:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
runner_or_verification_inputs_changed:
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
technical_obligations_changed:
|
|
195
|
-
|
|
137
|
+
owner_or_path_boundary_changed: outcomeChanges.owner_paths_expanded.length > 0 ||
|
|
138
|
+
outcomeChanges.owner_context_refs_removed.length > 0 ||
|
|
139
|
+
outcomeChanges.expected_change_paths_expanded.length > 0 ||
|
|
140
|
+
outcomeChanges.allowed_paths_expanded.length > 0 ||
|
|
141
|
+
outcomeChanges.forbidden_paths_removed.length > 0 ||
|
|
142
|
+
outcomeChanges.bindings_removed_or_expanded.length > 0,
|
|
143
|
+
runner_or_verification_inputs_changed: checkChanges.runner_definitions_changed.length > 0 ||
|
|
144
|
+
checkChanges.verification_inputs_removed_or_replaced.length > 0 ||
|
|
145
|
+
checkChanges.input_paths_removed_or_narrowed.length > 0 ||
|
|
146
|
+
checkChanges.expected_output_paths_removed_or_weakened.length > 0,
|
|
147
|
+
technical_obligations_changed: outcomeChanges.obligations_removed_or_weakened.length > 0 ||
|
|
148
|
+
outcomeChanges.rollback_or_recovery_weakened.length > 0,
|
|
196
149
|
reduction_reasons: [...new Set(reductionReasons)],
|
|
197
150
|
};
|
|
198
151
|
}
|
|
199
|
-
function keyedAuthorityChanges(before, after) {
|
|
200
|
-
const beforeByKey = new Map(before.map((item) => [item.key, item]));
|
|
201
|
-
const afterByKey = new Map(after.map((item) => [item.key, item]));
|
|
202
|
-
return [
|
|
203
|
-
...before
|
|
204
|
-
.filter((item) => !afterByKey.has(item.key))
|
|
205
|
-
.map((item) => `${item.key}:removed`),
|
|
206
|
-
...after
|
|
207
|
-
.filter((item) => !beforeByKey.has(item.key))
|
|
208
|
-
.map((item) => `${item.key}:added`),
|
|
209
|
-
...before
|
|
210
|
-
.filter((item) => {
|
|
211
|
-
const candidate = afterByKey.get(item.key);
|
|
212
|
-
return candidate !== undefined && !same(item, candidate);
|
|
213
|
-
})
|
|
214
|
-
.map((item) => `${item.key}:changed`),
|
|
215
|
-
].sort();
|
|
216
|
-
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProofSurface } from "./long-task-contract-types.js";
|
|
2
|
+
import type { DeliveryStageV2, ExecutionTargetV2, TargetProfileV2 } from "./long-task-semantic-contract-types.js";
|
|
2
3
|
import type { CompiledSourceItemV2 } from "./long-task-source-authority-types.js";
|
|
3
4
|
import type { WorkspaceManifestV2 } from "./long-task-workspace-runtime-types.js";
|
|
4
5
|
export interface AuthorityHashesV2 {
|
|
@@ -10,6 +11,9 @@ export interface AuthorityHashesV2 {
|
|
|
10
11
|
}
|
|
11
12
|
export interface ProductSemanticProjectionV2 {
|
|
12
13
|
task_goal: string;
|
|
14
|
+
target_profile: TargetProfileV2;
|
|
15
|
+
execution_targets: ExecutionTargetV2[];
|
|
16
|
+
stages: DeliveryStageV2[];
|
|
13
17
|
global_non_goals: Array<{
|
|
14
18
|
key: string;
|
|
15
19
|
statement: string;
|
|
@@ -17,7 +21,10 @@ export interface ProductSemanticProjectionV2 {
|
|
|
17
21
|
outcomes: Array<{
|
|
18
22
|
key: string;
|
|
19
23
|
title: string;
|
|
24
|
+
stage: string;
|
|
20
25
|
observable_result: string;
|
|
26
|
+
success_path_required: boolean;
|
|
27
|
+
degradation_path_required: boolean;
|
|
21
28
|
owner: {
|
|
22
29
|
label: string;
|
|
23
30
|
owner_surfaces: string[];
|
|
@@ -29,14 +36,28 @@ export interface ProductSemanticProjectionV2 {
|
|
|
29
36
|
}>;
|
|
30
37
|
controls: Array<{
|
|
31
38
|
key: string;
|
|
39
|
+
surface: string;
|
|
40
|
+
region: string;
|
|
32
41
|
location: string;
|
|
42
|
+
control_type: string;
|
|
43
|
+
label_content: string;
|
|
44
|
+
user_task: string;
|
|
45
|
+
visibility: string;
|
|
46
|
+
availability: string;
|
|
33
47
|
trigger: string;
|
|
34
48
|
input: string;
|
|
49
|
+
validation: string;
|
|
50
|
+
default_value: string;
|
|
51
|
+
interaction: string;
|
|
52
|
+
navigation_result: string;
|
|
35
53
|
loading_state: string;
|
|
36
54
|
empty_state: string;
|
|
37
55
|
success_state: string;
|
|
38
56
|
failure_state: string;
|
|
57
|
+
recovery: string;
|
|
58
|
+
permission: string;
|
|
39
59
|
feedback: string;
|
|
60
|
+
accessibility: string;
|
|
40
61
|
}>;
|
|
41
62
|
non_completing_outcomes: Array<{
|
|
42
63
|
key: string;
|
|
@@ -20,9 +20,13 @@ export function computeAuthorityHashes(contract) {
|
|
|
20
20
|
}),
|
|
21
21
|
product_authority_hash: hash({
|
|
22
22
|
goal: contract.task.goal,
|
|
23
|
+
target_profile: contract.task.target_profile,
|
|
24
|
+
execution_targets: contract.task.execution_targets,
|
|
25
|
+
stages: contract.stages,
|
|
23
26
|
global: contract.global.product,
|
|
24
27
|
outcomes: contract.outcomes.map((outcome) => ({
|
|
25
28
|
key: outcome.key,
|
|
29
|
+
stage: outcome.stage,
|
|
26
30
|
product: outcome.product,
|
|
27
31
|
})),
|
|
28
32
|
}),
|
|
@@ -51,6 +55,7 @@ export function computeAuthorityHashes(contract) {
|
|
|
51
55
|
}
|
|
52
56
|
export function outcomeAuthorityHash(outcome) {
|
|
53
57
|
return hash({
|
|
58
|
+
stage: outcome.stage,
|
|
54
59
|
product: outcome.product,
|
|
55
60
|
acceptance: {
|
|
56
61
|
checks: outcome.acceptance.checks.map(acceptanceCheck),
|
|
@@ -73,7 +78,7 @@ export function acceptanceSemanticsChanged(previous, next) {
|
|
|
73
78
|
export function isMonotonicAcceptanceStrengthening(previous, next) {
|
|
74
79
|
if (!acceptanceSemanticsChanged(previous, next))
|
|
75
80
|
return false;
|
|
76
|
-
if (!
|
|
81
|
+
if (!same(previous.global.acceptance.external_confirmations, next.global.acceptance.external_confirmations) ||
|
|
77
82
|
!subset(previous.global.acceptance.counterfactual_controls ?? [], next.global.acceptance.counterfactual_controls) ||
|
|
78
83
|
!checksStrengthened(previous.global.acceptance.checks, next.global.acceptance.checks))
|
|
79
84
|
return false;
|
|
@@ -119,8 +124,32 @@ function checksStrengthened(previous, next) {
|
|
|
119
124
|
const nextCheck = nextChecks.get(previousCheck.key);
|
|
120
125
|
if (!nextCheck ||
|
|
121
126
|
previousCheck.proof_surface !== nextCheck.proof_surface ||
|
|
122
|
-
!
|
|
123
|
-
!subset(previousCheck.
|
|
127
|
+
!same(previousCheck.execution_target, nextCheck.execution_target) ||
|
|
128
|
+
!subset(previousCheck.journey_roles, nextCheck.journey_roles) ||
|
|
129
|
+
!subset(previousCheck.scenario.given, nextCheck.scenario.given) ||
|
|
130
|
+
!subset(previousCheck.scenario.when, nextCheck.scenario.when) ||
|
|
131
|
+
!subset(previousCheck.verification_inputs, nextCheck.verification_inputs) ||
|
|
132
|
+
!subset(previousCheck.input_paths, nextCheck.input_paths) ||
|
|
133
|
+
!subset(previousCheck.expected_output_paths, nextCheck.expected_output_paths) ||
|
|
134
|
+
!subset(previousCheck.artifact_globs, nextCheck.artifact_globs) ||
|
|
135
|
+
!subset(previousCheck.environment_requirements, nextCheck.environment_requirements) ||
|
|
136
|
+
!assertionsStrengthened(previousCheck.positive_assertions, nextCheck.positive_assertions) ||
|
|
137
|
+
!assertionsStrengthened(previousCheck.negative_assertions, nextCheck.negative_assertions))
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
function assertionsStrengthened(previous, next) {
|
|
143
|
+
const nextAssertions = new Map(next.map((assertion) => [assertion.key, assertion]));
|
|
144
|
+
for (const previousAssertion of previous) {
|
|
145
|
+
const nextAssertion = nextAssertions.get(previousAssertion.key);
|
|
146
|
+
if (!nextAssertion ||
|
|
147
|
+
previousAssertion.criterion !== nextAssertion.criterion ||
|
|
148
|
+
!same(previousAssertion.claims, nextAssertion.claims) ||
|
|
149
|
+
previousAssertion.observation !== nextAssertion.observation ||
|
|
150
|
+
previousAssertion.operator !== nextAssertion.operator ||
|
|
151
|
+
!same(previousAssertion.expected, nextAssertion.expected) ||
|
|
152
|
+
!subset(previousAssertion.evidence_capabilities, nextAssertion.evidence_capabilities))
|
|
124
153
|
return false;
|
|
125
154
|
}
|
|
126
155
|
return true;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { CompiledCheckV2, RawCommandExecutionV2 } from "./long-task-delivery-types.js";
|
|
2
|
-
export declare function decodeCheckEvidence(check: CompiledCheckV2, exitCode: number, stdout: Buffer, stderr: Buffer): Pick<RawCommandExecutionV2, "execution_status" | "exit_code" | "observations" | "error">;
|
|
3
|
-
export declare function invalidEvidence(exitCode: number, error: string): Pick<RawCommandExecutionV2, "execution_status" | "exit_code" | "observations" | "error">;
|
|
2
|
+
export declare function decodeCheckEvidence(check: CompiledCheckV2, exitCode: number, stdout: Buffer, stderr: Buffer): Pick<RawCommandExecutionV2, "execution_status" | "exit_code" | "observations" | "evidence_records" | "error">;
|
|
3
|
+
export declare function invalidEvidence(exitCode: number, error: string): Pick<RawCommandExecutionV2, "execution_status" | "exit_code" | "observations" | "evidence_records" | "error">;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractPlaywrightEvidence } from "./long-task-playwright-evidence.js";
|
|
2
|
+
import { decodeEvidenceCapabilityRecords } from "./long-task-evidence-capability-policy.js";
|
|
2
3
|
export function decodeCheckEvidence(check, exitCode, stdout, stderr) {
|
|
3
4
|
if (check.runner.type === "playwright_test")
|
|
4
5
|
return decodePlaywright(check, exitCode, stdout, stderr);
|
|
@@ -9,13 +10,15 @@ export function decodeCheckEvidence(check, exitCode, stdout, stderr) {
|
|
|
9
10
|
.filter(Boolean);
|
|
10
11
|
try {
|
|
11
12
|
const payload = JSON.parse(lines.at(-1) ?? "");
|
|
12
|
-
if (payload.schema_version !== "long-task-check-result-v2"
|
|
13
|
+
if (payload.schema_version !== "long-task-check-result-v2" &&
|
|
14
|
+
payload.schema_version !== "long-task-check-result-v3")
|
|
13
15
|
return invalidEvidence(exitCode, "check_evidence_schema_invalid");
|
|
14
16
|
if (payload.execution_status === "blocked_external")
|
|
15
17
|
return {
|
|
16
18
|
execution_status: "blocked_external",
|
|
17
19
|
exit_code: exitCode,
|
|
18
20
|
observations: {},
|
|
21
|
+
evidence_records: [],
|
|
19
22
|
error: `blocked_external:${String(payload.reason ?? "unspecified")}`,
|
|
20
23
|
};
|
|
21
24
|
if (payload.execution_status !== "completed")
|
|
@@ -24,10 +27,14 @@ export function decodeCheckEvidence(check, exitCode, stdout, stderr) {
|
|
|
24
27
|
typeof payload.observations !== "object" ||
|
|
25
28
|
Array.isArray(payload.observations))
|
|
26
29
|
return invalidEvidence(exitCode, "check_evidence_observations_invalid");
|
|
30
|
+
const evidenceRecords = payload.schema_version === "long-task-check-result-v3"
|
|
31
|
+
? decodeEvidenceCapabilityRecords(payload.evidence_records)
|
|
32
|
+
: [];
|
|
27
33
|
return {
|
|
28
34
|
execution_status: "completed",
|
|
29
35
|
exit_code: exitCode,
|
|
30
36
|
observations: payload.observations,
|
|
37
|
+
evidence_records: evidenceRecords,
|
|
31
38
|
error: null,
|
|
32
39
|
};
|
|
33
40
|
}
|
|
@@ -40,6 +47,7 @@ export function invalidEvidence(exitCode, error) {
|
|
|
40
47
|
execution_status: "invalid_evidence",
|
|
41
48
|
exit_code: exitCode,
|
|
42
49
|
observations: {},
|
|
50
|
+
evidence_records: [],
|
|
43
51
|
error,
|
|
44
52
|
};
|
|
45
53
|
}
|
|
@@ -53,6 +61,7 @@ function decodePlaywright(check, exitCode, stdout, stderr) {
|
|
|
53
61
|
execution_status: "completed",
|
|
54
62
|
exit_code: exitCode,
|
|
55
63
|
observations: extracted.observations,
|
|
64
|
+
evidence_records: extracted.evidence_records,
|
|
56
65
|
error: null,
|
|
57
66
|
};
|
|
58
67
|
}
|
|
@@ -64,6 +73,7 @@ function decodePlaywright(check, exitCode, stdout, stderr) {
|
|
|
64
73
|
execution_status: "infrastructure_error",
|
|
65
74
|
exit_code: exitCode,
|
|
66
75
|
observations: {},
|
|
76
|
+
evidence_records: [],
|
|
67
77
|
error: `playwright_startup_failed:${message(error)}`,
|
|
68
78
|
};
|
|
69
79
|
return invalidEvidence(exitCode, `playwright_report_invalid:${message(error)}`);
|
|
@@ -2,6 +2,9 @@ import type { CompiledCheckV2 } from "./long-task-delivery-types.js";
|
|
|
2
2
|
export type CheckExecutionInputPolicy = "raw_execution" | "raw_execution_via_runner_freeze" | "per_check_evidence" | "progress_scope" | "final_gate_evidence" | "authority_metadata";
|
|
3
3
|
export declare const CHECK_EXECUTION_INPUT_POLICY: {
|
|
4
4
|
key: "authority_metadata";
|
|
5
|
+
journey_roles: "authority_metadata";
|
|
6
|
+
execution_target: "raw_execution";
|
|
7
|
+
scenario: "per_check_evidence";
|
|
5
8
|
proof_surface: "authority_metadata";
|
|
6
9
|
runner: "raw_execution";
|
|
7
10
|
verification_inputs: "raw_execution_via_runner_freeze";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
|
|
2
2
|
export const CHECK_EXECUTION_INPUT_POLICY = {
|
|
3
3
|
key: "authority_metadata",
|
|
4
|
+
journey_roles: "authority_metadata",
|
|
5
|
+
execution_target: "raw_execution",
|
|
6
|
+
scenario: "per_check_evidence",
|
|
4
7
|
proof_surface: "authority_metadata",
|
|
5
8
|
runner: "raw_execution",
|
|
6
9
|
verification_inputs: "raw_execution_via_runner_freeze",
|
|
@@ -14,6 +17,8 @@ export const CHECK_EXECUTION_INPUT_POLICY = {
|
|
|
14
17
|
export function rawExecutionInputProjection(check) {
|
|
15
18
|
const projection = {};
|
|
16
19
|
projection.evidence_adapter = check.evidence_adapter;
|
|
20
|
+
projection.execution_target_definition = check.execution_target_definition;
|
|
21
|
+
projection.known_execution_targets = check.known_execution_targets;
|
|
17
22
|
for (const field of Object.keys(CHECK_EXECUTION_INPUT_POLICY)) {
|
|
18
23
|
const policy = CHECK_EXECUTION_INPUT_POLICY[field];
|
|
19
24
|
if (policy === "raw_execution") {
|
|
@@ -17,6 +17,7 @@ export async function executeCheckRunner(check, snapshotRoot) {
|
|
|
17
17
|
execution_status: "blocked_external",
|
|
18
18
|
exit_code: -1,
|
|
19
19
|
observations: {},
|
|
20
|
+
evidence_records: [],
|
|
20
21
|
stdout_sha256: sha256Hex(""),
|
|
21
22
|
stderr_sha256: sha256Hex(""),
|
|
22
23
|
attempts: 0,
|
|
@@ -55,6 +56,7 @@ export async function executeCheckRunner(check, snapshotRoot) {
|
|
|
55
56
|
execution_status: "infrastructure_error",
|
|
56
57
|
exit_code: -1,
|
|
57
58
|
observations: {},
|
|
59
|
+
evidence_records: [],
|
|
58
60
|
stdout_sha256: sha256Hex(""),
|
|
59
61
|
stderr_sha256: sha256Hex(reason),
|
|
60
62
|
attempts: attempt,
|