project-tiny-context-harness 0.8.10 → 0.8.12
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 +490 -472
- package/assets/README.md +762 -749
- package/assets/README.zh-CN.md +446 -431
- package/assets/agents/.gitkeep +1 -1
- package/assets/agents/AGENTS_CORE.md +17 -23
- package/assets/agents/long-task-implementation.toml +15 -0
- package/assets/context_templates/architecture.md +18 -18
- package/assets/context_templates/area.md +30 -30
- package/assets/context_templates/context.toml +24 -24
- package/assets/context_templates/deployment.md +35 -35
- package/assets/context_templates/global.md +56 -56
- package/assets/context_templates/product-surface-contract.md +70 -70
- package/assets/context_templates/screen-contract.md +189 -189
- package/assets/context_templates/verification.md +25 -25
- package/assets/github/.gitkeep +1 -1
- package/assets/github/harness.yml +39 -39
- package/assets/make/.gitkeep +1 -1
- package/assets/make/ty-context.mk +48 -48
- package/assets/skills/context_development_engineer/SKILL.md +64 -185
- package/assets/skills/context_full_project_export/SKILL.md +28 -28
- package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
- package/assets/skills/context_product_plan/SKILL.md +35 -101
- package/assets/skills/context_surface_contract/SKILL.md +194 -191
- package/assets/skills/context_uiux_design/SKILL.md +49 -172
- package/assets/skills/design-resource-authoring/SKILL.md +52 -88
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +51 -163
- package/assets/skills/design-resource-authoring/references/formal-selected-web-app-handoff.md +96 -0
- package/assets/skills/design-resource-authoring/references/open-design-provider.md +119 -119
- package/assets/skills/design-resource-authoring/references/resource-selection.md +158 -181
- package/assets/skills/design-system-authoring/SKILL.md +57 -57
- package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
- package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
- package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
- package/assets/skills/long-task-workflow/SKILL.md +71 -106
- package/assets/skills/long-task-workflow/agents/openai.yaml +1 -1
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +71 -69
- package/assets/skills/long-task-workflow/references/contract-authoring.md +98 -94
- package/assets/skills/long-task-workflow/references/evidence-design.md +67 -63
- package/assets/skills/long-task-workflow/references/source-authoring.md +90 -90
- package/assets/tools/validate_context.py +442 -442
- package/dist/commands/design-resource.js +9 -2
- package/dist/commands/enable.js +2 -0
- package/dist/commands/index.js +1 -1
- package/dist/commands/long-task-revision.js +8 -7
- package/dist/commands/sync.js +2 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +2 -1
- package/dist/lib/compact-authoring-support.d.ts +22 -0
- package/dist/lib/compact-authoring-support.js +143 -0
- package/dist/lib/compact-shared-structure-authoring.d.ts +5 -0
- package/dist/lib/compact-shared-structure-authoring.js +9 -0
- package/dist/lib/compact-shared-structure-types.d.ts +61 -0
- package/dist/lib/compact-shared-structure-types.js +1 -0
- package/dist/lib/compact-shared-structure-validation.d.ts +2 -0
- package/dist/lib/compact-shared-structure-validation.js +159 -0
- package/dist/lib/compact-shared-structures.d.ts +3 -0
- package/dist/lib/compact-shared-structures.js +204 -0
- package/dist/lib/design-resource-fact-enums.d.ts +4 -0
- package/dist/lib/design-resource-fact-enums.js +12 -0
- package/dist/lib/design-resource-fact-manifest-shape-evidence.js +2 -2
- package/dist/lib/design-resource-fact-manifest-validation.d.ts +2 -1
- package/dist/lib/design-resource-fact-policy.d.ts +2 -2
- package/dist/lib/design-resource-fact-types.d.ts +2 -2
- package/dist/lib/design-resource-handoff-bundle-draft.d.ts +11 -0
- package/dist/lib/design-resource-handoff-bundle-draft.js +40 -0
- package/dist/lib/design-resource-handoff-bundle.js +4 -28
- package/dist/lib/design-resource-handoff-input-types.d.ts +14 -0
- package/dist/lib/design-resource-handoff-input-types.js +1 -0
- package/dist/lib/design-resource-handoff-manifest-projection.d.ts +2 -1
- package/dist/lib/design-resource-handoff-parser.d.ts +2 -2
- package/dist/lib/design-resource-handoff-parser.js +2 -2
- package/dist/lib/design-resource-handoff-shape.d.ts +4 -1
- package/dist/lib/design-resource-handoff-shape.js +10 -0
- package/dist/lib/design-resource-handoff-snapshot.d.ts +1 -1
- package/dist/lib/design-resource-handoff-snapshot.js +4 -0
- package/dist/lib/design-resource-handoff-types.d.ts +0 -10
- package/dist/lib/design-resource-handoff-validation.d.ts +6 -2
- package/dist/lib/design-resource-handoff-validation.js +11 -0
- package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +4 -2
- package/dist/lib/design-resource-symbolic-applicability-authority.d.ts +7 -0
- package/dist/lib/design-resource-symbolic-applicability-authority.js +19 -0
- package/dist/lib/design-resource-symbolic-applicability-policy.d.ts +12 -0
- package/dist/lib/design-resource-symbolic-applicability-policy.js +79 -0
- package/dist/lib/design-resource-symbolic-applicability-profiles.d.ts +8 -0
- package/dist/lib/design-resource-symbolic-applicability-profiles.js +55 -0
- package/dist/lib/design-resource-symbolic-applicability-shape.d.ts +2 -0
- package/dist/lib/design-resource-symbolic-applicability-shape.js +76 -0
- package/dist/lib/design-resource-symbolic-applicability-validation.d.ts +7 -0
- package/dist/lib/design-resource-symbolic-applicability-validation.js +128 -0
- package/dist/lib/design-resource-symbolic-compilation.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-compilation.js +13 -0
- package/dist/lib/design-resource-symbolic-denotation.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-denotation.js +167 -0
- package/dist/lib/design-resource-symbolic-disposition-validation.d.ts +4 -0
- package/dist/lib/design-resource-symbolic-disposition-validation.js +28 -0
- package/dist/lib/design-resource-symbolic-fact-policy.d.ts +12 -0
- package/dist/lib/design-resource-symbolic-fact-policy.js +12 -0
- package/dist/lib/design-resource-symbolic-fact-shape.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-fact-shape.js +138 -0
- package/dist/lib/design-resource-symbolic-fact-types.d.ts +213 -0
- package/dist/lib/design-resource-symbolic-fact-types.js +1 -0
- package/dist/lib/design-resource-symbolic-fact-validation.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-fact-validation.js +86 -0
- package/dist/lib/design-resource-symbolic-indexes.d.ts +23 -0
- package/dist/lib/design-resource-symbolic-indexes.js +54 -0
- package/dist/lib/design-resource-symbolic-manifest-shape.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-manifest-shape.js +155 -0
- package/dist/lib/design-resource-symbolic-manifest-validation.d.ts +6 -0
- package/dist/lib/design-resource-symbolic-manifest-validation.js +132 -0
- package/dist/lib/design-resource-symbolic-noninterference-artifact.d.ts +33 -0
- package/dist/lib/design-resource-symbolic-noninterference-artifact.js +110 -0
- package/dist/lib/design-resource-symbolic-noninterference-equivalence.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-noninterference-equivalence.js +77 -0
- package/dist/lib/design-resource-symbolic-noninterference-recompute.d.ts +4 -0
- package/dist/lib/design-resource-symbolic-noninterference-recompute.js +146 -0
- package/dist/lib/design-resource-symbolic-noninterference-scope.d.ts +7 -0
- package/dist/lib/design-resource-symbolic-noninterference-scope.js +49 -0
- package/dist/lib/design-resource-symbolic-noninterference-shape.d.ts +2 -0
- package/dist/lib/design-resource-symbolic-noninterference-shape.js +152 -0
- package/dist/lib/design-resource-symbolic-noninterference-types.d.ts +103 -0
- package/dist/lib/design-resource-symbolic-noninterference-types.js +1 -0
- package/dist/lib/design-resource-symbolic-noninterference-validation.d.ts +5 -0
- package/dist/lib/design-resource-symbolic-noninterference-validation.js +62 -0
- package/dist/lib/design-resource-symbolic-oracle-fingerprint.d.ts +1 -0
- package/dist/lib/design-resource-symbolic-oracle-fingerprint.js +47 -0
- package/dist/lib/design-resource-symbolic-predicate-shape.d.ts +6 -0
- package/dist/lib/design-resource-symbolic-predicate-shape.js +123 -0
- package/dist/lib/design-resource-symbolic-production-closure.d.ts +4 -0
- package/dist/lib/design-resource-symbolic-production-closure.js +144 -0
- package/dist/lib/design-resource-symbolic-proof-authority-validation.d.ts +10 -0
- package/dist/lib/design-resource-symbolic-proof-authority-validation.js +68 -0
- package/dist/lib/design-resource-symbolic-proof-validation.d.ts +10 -0
- package/dist/lib/design-resource-symbolic-proof-validation.js +89 -0
- package/dist/lib/design-resource-symbolic-region-validation.d.ts +19 -0
- package/dist/lib/design-resource-symbolic-region-validation.js +146 -0
- package/dist/lib/design-resource-symbolic-resource-validation.d.ts +5 -0
- package/dist/lib/design-resource-symbolic-resource-validation.js +90 -0
- package/dist/lib/design-resource-symbolic-rule-shape.d.ts +27 -0
- package/dist/lib/design-resource-symbolic-rule-shape.js +158 -0
- package/dist/lib/design-resource-symbolic-safety-validation.d.ts +6 -0
- package/dist/lib/design-resource-symbolic-safety-validation.js +29 -0
- package/dist/lib/design-resource-symbolic-source-ir-evaluation.d.ts +19 -0
- package/dist/lib/design-resource-symbolic-source-ir-evaluation.js +74 -0
- package/dist/lib/design-resource-symbolic-source-ir-evidence.d.ts +44 -0
- package/dist/lib/design-resource-symbolic-source-ir-evidence.js +88 -0
- package/dist/lib/design-resource-symbolic-source-ir-oracle.d.ts +13 -0
- package/dist/lib/design-resource-symbolic-source-ir-oracle.js +96 -0
- package/dist/lib/design-resource-symbolic-source-ir-proof.d.ts +14 -0
- package/dist/lib/design-resource-symbolic-source-ir-proof.js +98 -0
- package/dist/lib/design-resource-symbolic-source-ir-shape.d.ts +2 -0
- package/dist/lib/design-resource-symbolic-source-ir-shape.js +38 -0
- package/dist/lib/design-resource-symbolic-source-ir-types.d.ts +17 -0
- package/dist/lib/design-resource-symbolic-source-ir-types.js +2 -0
- package/dist/lib/design-resource-symbolic-static-dependency-validation.d.ts +2 -0
- package/dist/lib/design-resource-symbolic-static-dependency-validation.js +83 -0
- package/dist/lib/design-resource-symbolic-structural-closure-validation.d.ts +6 -0
- package/dist/lib/design-resource-symbolic-structural-closure-validation.js +79 -0
- package/dist/lib/design-resource-symbolic-validation-support.d.ts +29 -0
- package/dist/lib/design-resource-symbolic-validation-support.js +111 -0
- package/dist/lib/design-resource-v1-capacity-header.d.ts +8 -0
- package/dist/lib/design-resource-v1-capacity-header.js +231 -0
- package/dist/lib/design-resource-v1-capacity.d.ts +5 -0
- package/dist/lib/design-resource-v1-capacity.js +45 -0
- package/dist/lib/init.js +1 -0
- package/dist/lib/long-task-activation-validation.js +2 -2
- package/dist/lib/long-task-authority-policy.d.ts +3 -0
- package/dist/lib/long-task-authority-policy.js +3 -0
- package/dist/lib/long-task-codex-agent-profile.d.ts +42 -0
- package/dist/lib/long-task-codex-agent-profile.js +276 -0
- package/dist/lib/long-task-compact-authoring-projections.d.ts +12 -0
- package/dist/lib/long-task-compact-authoring-projections.js +67 -0
- package/dist/lib/long-task-compact-authoring.d.ts +3 -0
- package/dist/lib/long-task-compact-authoring.js +173 -0
- package/dist/lib/long-task-compact-carrier.d.ts +7 -0
- package/dist/lib/long-task-compact-carrier.js +132 -0
- package/dist/lib/long-task-compact-parser.d.ts +14 -0
- package/dist/lib/long-task-compact-parser.js +123 -0
- package/dist/lib/long-task-compact-primitives.d.ts +22 -0
- package/dist/lib/long-task-compact-primitives.js +132 -0
- package/dist/lib/long-task-compact-projections.d.ts +4 -0
- package/dist/lib/long-task-compact-projections.js +153 -0
- package/dist/lib/long-task-compact-structure-targets.d.ts +2 -0
- package/dist/lib/long-task-compact-structure-targets.js +90 -0
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +1 -1
- package/dist/lib/long-task-counterfactual-sandbox.js +7 -5
- package/dist/lib/long-task-delivery-parser.d.ts +1 -0
- package/dist/lib/long-task-delivery-parser.js +38 -6
- package/dist/lib/long-task-design-resource-handoff.d.ts +2 -1
- package/dist/lib/long-task-design-resource-handoff.js +71 -11
- package/dist/lib/long-task-design-resource-method-binding.d.ts +8 -1
- package/dist/lib/long-task-design-resource-method-binding.js +150 -0
- package/dist/lib/long-task-evidence-capability-codec.js +256 -34
- package/dist/lib/long-task-evidence-capability-policy.js +28 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +271 -63
- package/dist/lib/long-task-evidence-capability-types.d.ts +70 -2
- package/dist/lib/long-task-evidence-v2.d.ts +1 -1
- package/dist/lib/long-task-evidence-v2.js +5 -5
- package/dist/lib/long-task-hook-install.d.ts +19 -2
- package/dist/lib/long-task-hook-install.js +288 -91
- package/dist/lib/long-task-playwright-capability-records.d.ts +2 -0
- package/dist/lib/long-task-playwright-capability-records.js +74 -2
- package/dist/lib/long-task-runner-freeze.d.ts +1 -1
- package/dist/lib/long-task-runner-freeze.js +4 -2
- package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
- package/dist/lib/long-task-semantic-fact-binding-types.d.ts +8 -0
- package/dist/lib/long-task-semantic-fact-closure.js +4 -1
- package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +1 -1
- package/dist/lib/long-task-semantic-fact-contract-closure.js +15 -3
- package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +1 -1
- package/dist/lib/long-task-semantic-fact-contract-facts.js +4 -1
- package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +1 -1
- package/dist/lib/long-task-semantic-fact-contract-proofs.js +12 -3
- package/dist/lib/long-task-semantic-fact-evidence.d.ts +5 -1
- package/dist/lib/long-task-semantic-fact-evidence.js +47 -4
- package/dist/lib/long-task-semantic-fact-shape.js +17 -6
- package/dist/lib/long-task-shape-primitives.d.ts +1 -1
- package/dist/lib/long-task-shape-primitives.js +1 -0
- package/dist/lib/long-task-source-item-parser.d.ts +2 -2
- package/dist/lib/long-task-source-item-parser.js +20 -11
- package/dist/lib/long-task-ui-design-policy.js +64 -4
- package/dist/lib/long-task-ui-surface-shape.js +195 -0
- package/dist/lib/long-task-ui-surface-types.d.ts +53 -0
- package/dist/lib/long-task-verifier-v2.js +1 -1
- package/dist/lib/long-task-worker-selection.d.ts +2 -0
- package/dist/lib/long-task-worker-selection.js +7 -0
- package/dist/lib/long-task-workspace-scope.js +3 -1
- package/dist/lib/long-task-workspace.js +11 -1
- package/dist/lib/migrations.js +58 -0
- package/dist/lib/profiles.js +0 -1
- package/dist/lib/semantic-fact-compact-authoring.d.ts +2 -0
- package/dist/lib/semantic-fact-compact-authoring.js +160 -0
- package/dist/lib/semantic-fact-compact-capacity.d.ts +9 -0
- package/dist/lib/semantic-fact-compact-capacity.js +40 -0
- package/dist/lib/semantic-fact-compact-carrier.d.ts +16 -0
- package/dist/lib/semantic-fact-compact-carrier.js +146 -0
- package/dist/lib/semantic-fact-compact-parser.d.ts +17 -0
- package/dist/lib/semantic-fact-compact-parser.js +168 -0
- package/dist/lib/semantic-fact-compact-revision.d.ts +11 -0
- package/dist/lib/semantic-fact-compact-revision.js +64 -0
- package/dist/lib/semantic-fact-compact-support.d.ts +23 -0
- package/dist/lib/semantic-fact-compact-support.js +159 -0
- package/dist/lib/semantic-fact-policy-census.d.ts +1 -0
- package/dist/lib/semantic-fact-policy-census.js +43 -0
- package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
- package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
- package/dist/lib/semantic-fact-source-parser.d.ts +5 -0
- package/dist/lib/semantic-fact-source-parser.js +47 -6
- package/dist/lib/structural-closure-cost.d.ts +79 -0
- package/dist/lib/structural-closure-cost.js +91 -0
- package/dist/lib/symbolic-denotation-dag-builder.d.ts +25 -0
- package/dist/lib/symbolic-denotation-dag-builder.js +176 -0
- package/dist/lib/symbolic-denotation-domain-validation.d.ts +3 -0
- package/dist/lib/symbolic-denotation-domain-validation.js +56 -0
- package/dist/lib/symbolic-denotation-engine.d.ts +32 -0
- package/dist/lib/symbolic-denotation-engine.js +140 -0
- package/dist/lib/symbolic-denotation-public.d.ts +11 -0
- package/dist/lib/symbolic-denotation-public.js +12 -0
- package/dist/lib/symbolic-denotation-runtime.d.ts +20 -0
- package/dist/lib/symbolic-denotation-runtime.js +90 -0
- package/dist/lib/symbolic-denotation-support.d.ts +11 -0
- package/dist/lib/symbolic-denotation-support.js +49 -0
- package/dist/lib/symbolic-denotation-types.d.ts +133 -0
- package/dist/lib/symbolic-denotation-types.js +18 -0
- package/dist/lib/symbolic-denotation-validation.d.ts +6 -0
- package/dist/lib/symbolic-denotation-validation.js +126 -0
- package/dist/lib/sync-engine.d.ts +1 -0
- package/dist/lib/sync-engine.js +4 -1
- package/dist/lib/upgrade.js +1 -0
- package/dist/long-task-hook.js +40 -1
- package/dist/public-types.d.ts +8 -0
- package/dist/public-types.js +1 -0
- package/dist/schemas/design-resource-symbolic-noninterference-artifact-v2.schema.json +289 -0
- package/dist/schemas/design-resource-symbolic-source-ir-v1.schema.json +130 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +390 -5
- package/migrations/README.md +15 -15
- package/package.json +2 -2
- package/source-mappings.yaml +28 -25
- package/assets/skills/source-plan-authoring/SKILL.md +0 -14
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const STABLE_REF = /^[a-z0-9][a-z0-9._:-]*$/u;
|
|
2
|
+
const SHA256 = /^[a-f0-9]{64}$/u;
|
|
3
|
+
export { longTaskCompactSharedStructureTargets } from "./long-task-compact-structure-targets.js";
|
|
4
|
+
export const LONG_TASK_COMPACT_CAPACITY_FIELDS = [
|
|
5
|
+
"claims",
|
|
6
|
+
"claim_projections",
|
|
7
|
+
"selector_members",
|
|
8
|
+
"structure_families",
|
|
9
|
+
"structure_references",
|
|
10
|
+
"structure_arguments",
|
|
11
|
+
"facts",
|
|
12
|
+
"obligations",
|
|
13
|
+
"assertions",
|
|
14
|
+
"canonical_bytes",
|
|
15
|
+
];
|
|
16
|
+
const PACKAGE_MAXIMUM = {
|
|
17
|
+
claims: 1_000_000,
|
|
18
|
+
claim_projections: 2_000_000,
|
|
19
|
+
selector_members: 5_000_000,
|
|
20
|
+
structure_families: 1_000_000,
|
|
21
|
+
structure_references: 10_000_000,
|
|
22
|
+
structure_arguments: 50_000_000,
|
|
23
|
+
facts: 1_000_000,
|
|
24
|
+
obligations: 2_000_000,
|
|
25
|
+
assertions: 5_000_000,
|
|
26
|
+
canonical_bytes: 256 * 1024 * 1024,
|
|
27
|
+
};
|
|
28
|
+
export function compactRequiredOutcome(value, outcomes, label) {
|
|
29
|
+
const ref = compactStableRef(value, `${label}.outcome_ref`);
|
|
30
|
+
const outcome = outcomes.get(ref);
|
|
31
|
+
if (!outcome)
|
|
32
|
+
compactFail(`${label}.outcome_ref`, `unknown outcome: ${ref}`);
|
|
33
|
+
return outcome;
|
|
34
|
+
}
|
|
35
|
+
export function compactResolveSelectors(value, selectors, label) {
|
|
36
|
+
if (Array.isArray(value))
|
|
37
|
+
return value.map((item, index) => compactResolveSelectors(item, selectors, `${label}[${index}]`));
|
|
38
|
+
if (!value || typeof value !== "object")
|
|
39
|
+
return value;
|
|
40
|
+
const row = value;
|
|
41
|
+
if (Object.keys(row).length === 1 && Object.hasOwn(row, "selector_ref")) {
|
|
42
|
+
const ref = compactStableRef(row.selector_ref, `${label}.selector_ref`);
|
|
43
|
+
const members = selectors.get(ref);
|
|
44
|
+
if (!members)
|
|
45
|
+
compactFail(`${label}.selector_ref`, `unknown selector: ${ref}`);
|
|
46
|
+
return [...members];
|
|
47
|
+
}
|
|
48
|
+
if (Object.hasOwn(row, "selector_ref"))
|
|
49
|
+
compactFail(label, "selector_ref must be the only key");
|
|
50
|
+
return Object.fromEntries(Object.entries(row).map(([key, item]) => [
|
|
51
|
+
key,
|
|
52
|
+
compactResolveSelectors(item, selectors, `${label}.${key}`),
|
|
53
|
+
]));
|
|
54
|
+
}
|
|
55
|
+
export function validateLongTaskCompactCapacity(capacity, measured, label) {
|
|
56
|
+
for (const field of LONG_TASK_COMPACT_CAPACITY_FIELDS) {
|
|
57
|
+
if (capacity.maximum[field] > PACKAGE_MAXIMUM[field])
|
|
58
|
+
compactFail(`${label}.capacity.maximum.${field}`, `exceeds package maximum ${PACKAGE_MAXIMUM[field]}`);
|
|
59
|
+
if (capacity.measured[field] !== measured[field])
|
|
60
|
+
compactFail(`${label}.capacity.measured.${field}`, `measured mismatch: ${capacity.measured[field]}:${measured[field]}`);
|
|
61
|
+
if (measured[field] > capacity.maximum[field])
|
|
62
|
+
compactFail(`${label}.capacity.maximum.${field}`, `capacity exceeded: ${measured[field]}:${capacity.maximum[field]}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function validateLongTaskCompactDeclaredMaximum(maximum, label) {
|
|
66
|
+
for (const field of LONG_TASK_COMPACT_CAPACITY_FIELDS)
|
|
67
|
+
if (maximum[field] > PACKAGE_MAXIMUM[field])
|
|
68
|
+
compactFail(`${label}.capacity.maximum.${field}`, `exceeds package maximum ${PACKAGE_MAXIMUM[field]}`);
|
|
69
|
+
}
|
|
70
|
+
export function compactUniqueRows(rows, field, label) {
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
for (const [index, row] of rows.entries()) {
|
|
73
|
+
const value = compactStableRef(row[field], `${label}.rows[${index}].${field}`);
|
|
74
|
+
if (seen.has(value))
|
|
75
|
+
compactFail(label, `duplicate ${field}: ${value}`);
|
|
76
|
+
seen.add(value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function compactStrictObject(value, label, fields) {
|
|
80
|
+
const row = compactPlainObject(value, label);
|
|
81
|
+
const allowed = new Set(fields);
|
|
82
|
+
const unknown = Object.keys(row).filter((key) => !allowed.has(key));
|
|
83
|
+
if (unknown.length)
|
|
84
|
+
compactFail(label, `unknown keys: ${unknown.join(",")}`);
|
|
85
|
+
const missing = fields.filter((field) => !Object.hasOwn(row, field));
|
|
86
|
+
if (missing.length)
|
|
87
|
+
compactFail(label, `missing keys: ${missing.join(",")}`);
|
|
88
|
+
return row;
|
|
89
|
+
}
|
|
90
|
+
export function compactPlainObject(value, label) {
|
|
91
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
92
|
+
compactFail(label, "must be an object");
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
export function compactArray(value, label) {
|
|
96
|
+
if (!Array.isArray(value))
|
|
97
|
+
compactFail(label, "must be an array");
|
|
98
|
+
return value;
|
|
99
|
+
}
|
|
100
|
+
export function compactStableRef(value, label) {
|
|
101
|
+
const result = compactNonemptyString(value, label);
|
|
102
|
+
if (!STABLE_REF.test(result))
|
|
103
|
+
compactFail(label, "must be a stable reference");
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
export function compactStableRefs(value, label) {
|
|
107
|
+
return compactArray(value, label).map((item, index) => compactStableRef(item, `${label}[${index}]`));
|
|
108
|
+
}
|
|
109
|
+
export function compactSha256(value, label) {
|
|
110
|
+
const result = compactNonemptyString(value, label);
|
|
111
|
+
if (!SHA256.test(result))
|
|
112
|
+
compactFail(label, "must be a lowercase SHA-256");
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
export function compactNonemptyString(value, label) {
|
|
116
|
+
if (typeof value !== "string" || !value.trim())
|
|
117
|
+
compactFail(label, "must be a non-empty string");
|
|
118
|
+
return value;
|
|
119
|
+
}
|
|
120
|
+
export function compactInteger(value, label) {
|
|
121
|
+
if (!Number.isInteger(value) || Number(value) < 0)
|
|
122
|
+
compactFail(label, "must be an integer >= 0");
|
|
123
|
+
return Number(value);
|
|
124
|
+
}
|
|
125
|
+
export function compactLiteral(value, values, label) {
|
|
126
|
+
if (typeof value !== "string" || !values.includes(value))
|
|
127
|
+
compactFail(label, `must be one of ${values.join(",")}`);
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
export function compactFail(label, message) {
|
|
131
|
+
throw new Error(`long_task_compact_carrier_invalid:${label}:${message}`);
|
|
132
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function prepareLongTaskCompactOutcomeTargets(outcomes: Record<string, unknown>[]): void;
|
|
2
|
+
export declare function materializeLongTaskCompactClaimProjections(projections: Record<string, unknown>[], claims: Map<string, Record<string, unknown>>, outcomes: Map<string, Record<string, unknown>>): void;
|
|
3
|
+
export declare function materializeLongTaskCompactFactBindings(facts: Record<string, unknown>[], obligations: Record<string, unknown>[], factByKey: Map<string, Record<string, unknown>>, templates: Map<string, Record<string, unknown>>, outcomes: Map<string, Record<string, unknown>>): void;
|
|
4
|
+
export declare function materializeLongTaskCompactAssertions(assertions: Record<string, unknown>[], claims: Map<string, Record<string, unknown>>, facts: Map<string, Record<string, unknown>>, outcomes: Map<string, Record<string, unknown>>): void;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { compactArray, compactFail, compactInteger, compactLiteral, compactNonemptyString, compactPlainObject, compactRequiredOutcome, compactSha256, compactStableRef, compactStableRefs, } from "./long-task-compact-primitives.js";
|
|
2
|
+
export function prepareLongTaskCompactOutcomeTargets(outcomes) {
|
|
3
|
+
for (const [index, outcome] of outcomes.entries()) {
|
|
4
|
+
const label = `outcomes[${index}]`;
|
|
5
|
+
if (Object.hasOwn(outcome, "semantic_fact_bindings"))
|
|
6
|
+
compactFail(label, "expanded semantic_fact_bindings cannot coexist");
|
|
7
|
+
const product = compactPlainObject(outcome.product, `${label}.product`);
|
|
8
|
+
const technical = compactPlainObject(outcome.technical, `${label}.technical`);
|
|
9
|
+
for (const field of ["requirements", "non_completing_outcomes"])
|
|
10
|
+
if (Object.hasOwn(product, field))
|
|
11
|
+
compactFail(`${label}.product.${field}`, "expanded projection cannot coexist");
|
|
12
|
+
for (const field of ["obligations", "forbidden_shortcuts"])
|
|
13
|
+
if (Object.hasOwn(technical, field))
|
|
14
|
+
compactFail(`${label}.technical.${field}`, "expanded projection cannot coexist");
|
|
15
|
+
product.requirements = [];
|
|
16
|
+
product.non_completing_outcomes = [];
|
|
17
|
+
technical.obligations = [];
|
|
18
|
+
technical.forbidden_shortcuts = [];
|
|
19
|
+
outcome.semantic_fact_bindings = {
|
|
20
|
+
manifest_ref: "",
|
|
21
|
+
facts: [],
|
|
22
|
+
proofs: [],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function materializeLongTaskCompactClaimProjections(projections, claims, outcomes) {
|
|
27
|
+
for (const [index, projection] of projections.entries()) {
|
|
28
|
+
const label = `compact_semantic_carrier.claim_projections.rows[${index}]`;
|
|
29
|
+
const outcome = compactRequiredOutcome(projection.outcome_ref, outcomes, label);
|
|
30
|
+
const claimKey = projection.claim_key === null
|
|
31
|
+
? null
|
|
32
|
+
: compactStableRef(projection.claim_key, `${label}.claim_key`);
|
|
33
|
+
const claim = claimKey ? claims.get(claimKey) : null;
|
|
34
|
+
if (claimKey && !claim)
|
|
35
|
+
compactFail(`${label}.claim_key`, `unknown claim: ${claimKey}`);
|
|
36
|
+
const statement = claim
|
|
37
|
+
? compactNonemptyString(claim.statement, `${label}.statement`)
|
|
38
|
+
: compactNonemptyString(projection.statement, `${label}.statement`);
|
|
39
|
+
const applicabilityRefs = compactStableRefs(projection.applicability_refs, `${label}.applicability_refs`);
|
|
40
|
+
const kind = compactLiteral(projection.projection_kind, [
|
|
41
|
+
"requirement",
|
|
42
|
+
"obligation",
|
|
43
|
+
"forbidden_shortcut",
|
|
44
|
+
"non_completing_outcome",
|
|
45
|
+
], `${label}.projection_kind`);
|
|
46
|
+
const product = compactPlainObject(outcome.product, `${label}.product`);
|
|
47
|
+
const technical = compactPlainObject(outcome.technical, `${label}.technical`);
|
|
48
|
+
const base = {
|
|
49
|
+
key: compactStableRef(projection.projection_key ?? projection.claim_key, `${label}.projection_key`),
|
|
50
|
+
statement,
|
|
51
|
+
applicability_refs: applicabilityRefs,
|
|
52
|
+
};
|
|
53
|
+
if (kind === "requirement" || kind === "obligation") {
|
|
54
|
+
const requiredProofSurfaces = compactStableRefs(projection.required_proof_surfaces, `${label}.required_proof_surfaces`);
|
|
55
|
+
const row = { ...base, required_proof_surfaces: requiredProofSurfaces };
|
|
56
|
+
if (kind === "requirement")
|
|
57
|
+
product.requirements.push(row);
|
|
58
|
+
else
|
|
59
|
+
technical.obligations.push(row);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
if (projection.required_proof_surfaces !== null)
|
|
63
|
+
compactFail(`${label}.required_proof_surfaces`, "must be null for statement-only projection");
|
|
64
|
+
if (kind === "forbidden_shortcut")
|
|
65
|
+
technical.forbidden_shortcuts.push(base);
|
|
66
|
+
else
|
|
67
|
+
product.non_completing_outcomes.push(base);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function materializeLongTaskCompactFactBindings(facts, obligations, factByKey, templates, outcomes) {
|
|
72
|
+
for (const [index, fact] of facts.entries()) {
|
|
73
|
+
const label = `compact_semantic_carrier.facts[${index}]`;
|
|
74
|
+
const outcome = compactRequiredOutcome(fact.outcome_ref, outcomes, label);
|
|
75
|
+
const binding = compactPlainObject(outcome.semantic_fact_bindings, `${label}.semantic_fact_bindings`);
|
|
76
|
+
if (!binding.manifest_ref)
|
|
77
|
+
binding.manifest_ref = compactStableRef(fact.manifest_ref, `${label}.manifest_ref`);
|
|
78
|
+
else if (binding.manifest_ref !== fact.manifest_ref)
|
|
79
|
+
compactFail(`${label}.manifest_ref`, "outcome manifest_ref mismatch");
|
|
80
|
+
binding.facts.push({
|
|
81
|
+
fact_ref: compactStableRef(fact.fact_key, `${label}.fact_key`),
|
|
82
|
+
fact_revision_digest: compactSha256(fact.fact_revision_digest, `${label}.fact_revision_digest`),
|
|
83
|
+
claim_ref: compactStableRef(fact.claim_ref, `${label}.claim_ref`),
|
|
84
|
+
applicability_ref: compactStableRef(fact.applicability_ref, `${label}.applicability_ref`),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
for (const [index, obligation] of obligations.entries()) {
|
|
88
|
+
const label = `compact_semantic_carrier.obligations.rows[${index}]`;
|
|
89
|
+
const outcome = compactRequiredOutcome(obligation.outcome_ref, outcomes, label);
|
|
90
|
+
const factKey = compactStableRef(obligation.fact_key, `${label}.fact_key`);
|
|
91
|
+
if (!factByKey.has(factKey))
|
|
92
|
+
compactFail(`${label}.fact_key`, `unknown fact: ${factKey}`);
|
|
93
|
+
const templateRef = compactStableRef(obligation.template_ref, `${label}.template_ref`);
|
|
94
|
+
const template = templates.get(templateRef);
|
|
95
|
+
if (!template)
|
|
96
|
+
compactFail(`${label}.template_ref`, `unknown template: ${templateRef}`);
|
|
97
|
+
const overrides = compactPlainObject(obligation.overrides, `${label}.overrides`);
|
|
98
|
+
if (["proof_ref", "fact_ref", "obligation_revision_digest"].some((field) => Object.hasOwn(overrides, field)))
|
|
99
|
+
compactFail(`${label}.overrides`, "identity fields cannot be overridden");
|
|
100
|
+
const binding = compactPlainObject(outcome.semantic_fact_bindings, `${label}.semantic_fact_bindings`);
|
|
101
|
+
binding.proofs.push({
|
|
102
|
+
...template,
|
|
103
|
+
...overrides,
|
|
104
|
+
proof_ref: compactStableRef(obligation.obligation_key, `${label}.obligation_key`),
|
|
105
|
+
obligation_revision_digest: compactSha256(obligation.obligation_revision_digest, `${label}.obligation_revision_digest`),
|
|
106
|
+
fact_ref: factKey,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function materializeLongTaskCompactAssertions(assertions, claims, facts, outcomes) {
|
|
111
|
+
for (const [index, projection] of assertions.entries()) {
|
|
112
|
+
const label = `compact_semantic_carrier.assertion_projections.rows[${index}]`;
|
|
113
|
+
const outcome = compactRequiredOutcome(projection.outcome_ref, outcomes, label);
|
|
114
|
+
const acceptance = compactPlainObject(outcome.acceptance, `${label}.acceptance`);
|
|
115
|
+
const checkRef = compactStableRef(projection.check_ref, `${label}.check_ref`);
|
|
116
|
+
const check = compactArray(acceptance.checks, `${label}.checks`)
|
|
117
|
+
.map((item, checkIndex) => compactPlainObject(item, `${label}.checks[${checkIndex}]`))
|
|
118
|
+
.find((item) => item.key === checkRef);
|
|
119
|
+
if (!check)
|
|
120
|
+
compactFail(`${label}.check_ref`, `unknown check: ${checkRef}`);
|
|
121
|
+
const criterionKind = compactLiteral(projection.criterion_kind, ["claim_statement", "semantic_fact"], `${label}.criterion_kind`);
|
|
122
|
+
const criterionRef = compactStableRef(projection.criterion_ref, `${label}.criterion_ref`);
|
|
123
|
+
let criterion;
|
|
124
|
+
if (criterionKind === "claim_statement") {
|
|
125
|
+
const claim = claims.get(criterionRef);
|
|
126
|
+
if (!claim)
|
|
127
|
+
compactFail(`${label}.criterion_ref`, `unknown claim: ${criterionRef}`);
|
|
128
|
+
criterion = compactNonemptyString(claim.statement, `${label}.criterion`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
if (!facts.has(criterionRef))
|
|
132
|
+
compactFail(`${label}.criterion_ref`, `unknown fact: ${criterionRef}`);
|
|
133
|
+
criterion = `The current candidate satisfies the exact Source Fact ${criterionRef}.`;
|
|
134
|
+
}
|
|
135
|
+
const assertion = {
|
|
136
|
+
key: compactStableRef(projection.key, `${label}.key`),
|
|
137
|
+
criterion,
|
|
138
|
+
claims: compactStableRefs(projection.claims, `${label}.claims`),
|
|
139
|
+
applicability_ref: compactStableRef(projection.applicability_ref, `${label}.applicability_ref`),
|
|
140
|
+
observation: compactNonemptyString(projection.observation, `${label}.observation`),
|
|
141
|
+
evidence_capabilities: compactStableRefs(projection.evidence_capabilities, `${label}.evidence_capabilities`),
|
|
142
|
+
operator: compactNonemptyString(projection.operator, `${label}.operator`),
|
|
143
|
+
expected: projection.expected,
|
|
144
|
+
};
|
|
145
|
+
const positive = compactArray(check.positive_assertions, `${label}.positive_assertions`);
|
|
146
|
+
if (positive.some((item) => compactPlainObject(item, label).key === assertion.key))
|
|
147
|
+
compactFail(`${label}.key`, `duplicate assertion: ${assertion.key}`);
|
|
148
|
+
const position = compactInteger(projection.position, `${label}.position`);
|
|
149
|
+
if (position > positive.length)
|
|
150
|
+
compactFail(`${label}.position`, `position exceeds current assertion length: ${position}:${positive.length}`);
|
|
151
|
+
positive.splice(position, 0, assertion);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const BASE_STRUCTURE_BOUNDARY_BY_FIELD = {
|
|
2
|
+
path_globs: "contract.path-set",
|
|
3
|
+
expected_change_paths: "contract.path-set",
|
|
4
|
+
input_paths: "contract.check.input-paths",
|
|
5
|
+
verification_inputs: "contract.check.verification-inputs",
|
|
6
|
+
scenario: "contract.check.scenario",
|
|
7
|
+
expected_output_paths: "contract.check.output-paths",
|
|
8
|
+
mutation: "contract.counterfactual.mutation",
|
|
9
|
+
execution_target: "contract.check.execution-target",
|
|
10
|
+
artifact_globs: "contract.check.artifact-globs",
|
|
11
|
+
journey_roles: "contract.check.journey-roles",
|
|
12
|
+
carrier_paths: "contract.binding.carrier-paths",
|
|
13
|
+
preserved_assertions: "contract.counterfactual.preserved-assertions",
|
|
14
|
+
expected_assertion_failures: "contract.counterfactual.expected-assertion-failures",
|
|
15
|
+
};
|
|
16
|
+
export function longTaskCompactSharedStructureTargets(root, carrier) {
|
|
17
|
+
const targets = [];
|
|
18
|
+
for (const [field, boundary] of [
|
|
19
|
+
["claim_catalog", "contract.claim"],
|
|
20
|
+
["claim_projections", "contract.claim-projection"],
|
|
21
|
+
["obligations", "contract.obligation"],
|
|
22
|
+
["assertion_projections", "contract.assertion"],
|
|
23
|
+
])
|
|
24
|
+
addCompactTableTargets(targets, carrier[field], boundary);
|
|
25
|
+
if (Array.isArray(carrier.fact_sets))
|
|
26
|
+
for (const factSet of carrier.fact_sets)
|
|
27
|
+
addCompactTableTargets(targets, factSet, "contract.fact");
|
|
28
|
+
if (Array.isArray(carrier.proof_templates))
|
|
29
|
+
for (const template of carrier.proof_templates) {
|
|
30
|
+
const row = plainRecord(template);
|
|
31
|
+
if (row && Object.hasOwn(row, "binding"))
|
|
32
|
+
addTarget(targets, row, "binding", "contract.proof.policy");
|
|
33
|
+
}
|
|
34
|
+
for (const [key, value] of Object.entries(root)) {
|
|
35
|
+
if (key === "compact_semantic_carrier")
|
|
36
|
+
continue;
|
|
37
|
+
collectBaseTargets(targets, value);
|
|
38
|
+
}
|
|
39
|
+
return targets;
|
|
40
|
+
}
|
|
41
|
+
function collectBaseTargets(targets, value) {
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
value.forEach((item) => collectBaseTargets(targets, item));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const row = plainRecord(value);
|
|
47
|
+
if (!row)
|
|
48
|
+
return;
|
|
49
|
+
for (const [key, child] of Object.entries(row)) {
|
|
50
|
+
const boundary = BASE_STRUCTURE_BOUNDARY_BY_FIELD[key];
|
|
51
|
+
if (boundary && child && typeof child === "object") {
|
|
52
|
+
addTarget(targets, row, key, boundary);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
collectBaseTargets(targets, child);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function addCompactTableTargets(targets, value, boundary) {
|
|
59
|
+
const table = plainRecord(value);
|
|
60
|
+
if (!table || !Array.isArray(table.columns) || !Array.isArray(table.rows))
|
|
61
|
+
return;
|
|
62
|
+
const columns = table.columns.map(String);
|
|
63
|
+
const defaults = plainRecord(table.defaults);
|
|
64
|
+
if (defaults)
|
|
65
|
+
for (const key of Object.keys(defaults))
|
|
66
|
+
if (defaults[key] && typeof defaults[key] === "object")
|
|
67
|
+
addTarget(targets, defaults, key, `${boundary}.default.${key}`);
|
|
68
|
+
for (const rowValue of table.rows) {
|
|
69
|
+
if (!Array.isArray(rowValue) || rowValue.length !== columns.length)
|
|
70
|
+
continue;
|
|
71
|
+
for (const [index, column] of columns.entries())
|
|
72
|
+
if (rowValue[index] && typeof rowValue[index] === "object")
|
|
73
|
+
addTarget(targets, rowValue, index, `${boundary}.${column}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function addTarget(targets, parent, key, boundary) {
|
|
77
|
+
const indexed = parent;
|
|
78
|
+
targets.push({
|
|
79
|
+
boundary,
|
|
80
|
+
read: () => indexed[key],
|
|
81
|
+
write: (value) => {
|
|
82
|
+
indexed[key] = value;
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function plainRecord(value) {
|
|
87
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
88
|
+
? value
|
|
89
|
+
: null;
|
|
90
|
+
}
|
|
@@ -8,6 +8,6 @@ type RemoveTree = (target: string, options: {
|
|
|
8
8
|
force: true;
|
|
9
9
|
}) => Promise<void>;
|
|
10
10
|
type Wait = (milliseconds: number) => Promise<void>;
|
|
11
|
-
export declare function createCounterfactualSandbox(snapshotRoot: string, check: CompiledCheckV2, control: CounterfactualControlV2 | GlobalCounterfactualControlV2, bindingCarrierPaths: string[], manifest?: WorkspaceManifestV2): Promise<CounterfactualSandboxV2>;
|
|
11
|
+
export declare function createCounterfactualSandbox(snapshotRoot: string, check: CompiledCheckV2, control: CounterfactualControlV2 | GlobalCounterfactualControlV2, bindingCarrierPaths: string[], manifest?: WorkspaceManifestV2, protectedAuthorityPaths?: readonly string[]): Promise<CounterfactualSandboxV2>;
|
|
12
12
|
export declare function removeCounterfactualSandboxRoot(root: string, removeTree?: RemoveTree, wait?: Wait): Promise<void>;
|
|
13
13
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { copyFile, cp, lstat, mkdir, mkdtemp, readlink, realpath, rm, symlink, } from "node:fs/promises";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { matchesRepoPattern } from "./long-task-paths.js";
|
|
4
|
+
import { matchesRepoPattern, normalizeRepositoryFile, } from "./long-task-paths.js";
|
|
5
5
|
const TRANSIENT_REMOVE_CODES = new Set([
|
|
6
6
|
"EBUSY",
|
|
7
7
|
"EMFILE",
|
|
@@ -11,7 +11,7 @@ const TRANSIENT_REMOVE_CODES = new Set([
|
|
|
11
11
|
]);
|
|
12
12
|
const REMOVE_RETRY_LIMIT = process.platform === "win32" ? 6 : 2;
|
|
13
13
|
const REMOVE_RETRY_DELAY_MS = 100;
|
|
14
|
-
export async function createCounterfactualSandbox(snapshotRoot, check, control, bindingCarrierPaths, manifest) {
|
|
14
|
+
export async function createCounterfactualSandbox(snapshotRoot, check, control, bindingCarrierPaths, manifest, protectedAuthorityPaths = []) {
|
|
15
15
|
const root = await mkdtemp(path.join(os.tmpdir(), "ty-context-counterfactual-"));
|
|
16
16
|
if (!manifest) {
|
|
17
17
|
await cp(snapshotRoot, root, {
|
|
@@ -44,9 +44,11 @@ export async function createCounterfactualSandbox(snapshotRoot, check, control,
|
|
|
44
44
|
if (requirement.kind === "directory")
|
|
45
45
|
patterns.push(`${requirement.target}/**`);
|
|
46
46
|
}
|
|
47
|
-
const
|
|
48
|
-
.map((file) => file.path)
|
|
49
|
-
.
|
|
47
|
+
const candidates = new Set([
|
|
48
|
+
...manifest.files.map((file) => file.path),
|
|
49
|
+
...protectedAuthorityPaths.map((file, index) => normalizeRepositoryFile(file, `counterfactual.protected_authority_paths[${index}]`)),
|
|
50
|
+
]);
|
|
51
|
+
const selected = [...candidates].filter((relative) => exactPaths.has(relative) ||
|
|
50
52
|
patterns.some((pattern) => matchesRepoPattern(relative, pattern)));
|
|
51
53
|
await copyInBatches(snapshotRoot, root, selected);
|
|
52
54
|
await mkdir(path.join(root, check.runner.resolved_cwd), { recursive: true });
|
|
@@ -11,3 +11,4 @@ export interface ParseDeliveryContractOptions {
|
|
|
11
11
|
export declare function parseDeliveryContract(workdir: string): Promise<DeliveryContractV2>;
|
|
12
12
|
export declare function parseDeliveryContractBundle(workdirInput: string, repositoryInput?: string, options?: ParseDeliveryContractOptions): Promise<ParsedDeliveryContractV2>;
|
|
13
13
|
export declare function parseDeliveryContractText(raw: string): DeliveryContractV2;
|
|
14
|
+
export declare function parseDeliveryContractTextForMigration(raw: string): DeliveryContractV2;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { materializeLongTaskCompactCarrier, materializeLongTaskCompactCarrierForMigration, } from "./long-task-compact-carrier.js";
|
|
3
4
|
import { parseStrictYaml, sha256Hex } from "./strict-codec.js";
|
|
4
5
|
import { validateDeliveryContractStructure } from "./long-task-delivery-validation.js";
|
|
5
6
|
import { parseOutcome, parseOutcomeFragment, safeFragmentPath, } from "./long-task-outcome-parser.js";
|
|
@@ -20,7 +21,11 @@ export async function parseDeliveryContractBundle(workdirInput, repositoryInput,
|
|
|
20
21
|
? path.resolve(repositoryInput)
|
|
21
22
|
: await repositoryRoot(workdir);
|
|
22
23
|
const raw = await readFile(await assertProtectedRepositoryFile(repository, file, "delivery_contract"), "utf8");
|
|
23
|
-
|
|
24
|
+
let root = parseRoot(raw, true);
|
|
25
|
+
if (Object.hasOwn(root, "compact_semantic_carrier")) {
|
|
26
|
+
root = materializeLongTaskCompactCarrier(root).root;
|
|
27
|
+
assertNoSemanticDriftMigration(semanticDriftMigrationFields(root));
|
|
28
|
+
}
|
|
24
29
|
const hasInline = Object.hasOwn(root, "outcomes");
|
|
25
30
|
const hasFiles = Object.hasOwn(root, "outcome_files");
|
|
26
31
|
if (hasInline === hasFiles)
|
|
@@ -64,7 +69,19 @@ export async function parseDeliveryContractBundle(workdirInput, repositoryInput,
|
|
|
64
69
|
};
|
|
65
70
|
}
|
|
66
71
|
export function parseDeliveryContractText(raw) {
|
|
67
|
-
|
|
72
|
+
return parseDeliveryContractTextInternal(raw, false);
|
|
73
|
+
}
|
|
74
|
+
export function parseDeliveryContractTextForMigration(raw) {
|
|
75
|
+
return parseDeliveryContractTextInternal(raw, true);
|
|
76
|
+
}
|
|
77
|
+
function parseDeliveryContractTextInternal(raw, allowLegacyCarrier) {
|
|
78
|
+
let root = parseRoot(raw, false);
|
|
79
|
+
if (Object.hasOwn(root, "compact_semantic_carrier")) {
|
|
80
|
+
root = (allowLegacyCarrier
|
|
81
|
+
? materializeLongTaskCompactCarrierForMigration(root)
|
|
82
|
+
: materializeLongTaskCompactCarrier(root)).root;
|
|
83
|
+
assertNoSemanticDriftMigration(semanticDriftMigrationFields(root));
|
|
84
|
+
}
|
|
68
85
|
const contract = parseContractRoot(root, array(root.outcomes, "outcomes").map((item, index) => parseOutcome(item, `outcomes[${index}]`)));
|
|
69
86
|
validateDeliveryContractStructure(contract);
|
|
70
87
|
return contract;
|
|
@@ -77,16 +94,31 @@ function parseRoot(raw, bundle) {
|
|
|
77
94
|
decoded.schema_version ===
|
|
78
95
|
"long-task-delivery-v1")
|
|
79
96
|
throw new Error("long_task_delivery_v1_retired_use_v2");
|
|
80
|
-
|
|
81
|
-
|
|
97
|
+
if (!decoded ||
|
|
98
|
+
typeof decoded !== "object" ||
|
|
99
|
+
Array.isArray(decoded) ||
|
|
100
|
+
!Object.hasOwn(decoded, "compact_semantic_carrier"))
|
|
101
|
+
assertNoSemanticDriftMigration(semanticDriftMigrationFields(decoded));
|
|
102
|
+
const root = object(decoded, "$", [
|
|
82
103
|
"schema_version",
|
|
83
104
|
"semantic_fact_manifest",
|
|
84
105
|
"task",
|
|
85
|
-
"source_claims",
|
|
86
106
|
"stages",
|
|
87
107
|
"risk",
|
|
88
108
|
"global",
|
|
89
|
-
], bundle
|
|
109
|
+
], bundle
|
|
110
|
+
? [
|
|
111
|
+
"source_claims",
|
|
112
|
+
"compact_semantic_carrier",
|
|
113
|
+
"outcomes",
|
|
114
|
+
"outcome_files",
|
|
115
|
+
]
|
|
116
|
+
: ["source_claims", "compact_semantic_carrier", "outcomes"]);
|
|
117
|
+
const hasExpanded = Object.hasOwn(root, "source_claims");
|
|
118
|
+
const hasCompact = Object.hasOwn(root, "compact_semantic_carrier");
|
|
119
|
+
if (hasExpanded === hasCompact)
|
|
120
|
+
throw new Error("delivery_contract_invalid:$:exactly one of source_claims or compact_semantic_carrier is required");
|
|
121
|
+
return root;
|
|
90
122
|
}
|
|
91
123
|
function parseContractRoot(root, outcomes) {
|
|
92
124
|
literal(root.schema_version, ["long-task-delivery-v2"], "schema_version");
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DesignResourceHandoffPreflightV1, DesignResourceHandoffTargetV1 } from "./design-resource-handoff-types.js";
|
|
2
|
+
import type { DesignResourceHandoffPreflightV2 } from "./design-resource-symbolic-fact-types.js";
|
|
2
3
|
import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
|
|
3
4
|
export interface ContractDesignTarget {
|
|
4
5
|
outcome_key: string;
|
|
@@ -10,7 +11,7 @@ export interface IndexedHandoffTarget {
|
|
|
10
11
|
target: DesignResourceHandoffTargetV1;
|
|
11
12
|
}
|
|
12
13
|
export interface LongTaskDesignHandoffConsumer {
|
|
13
|
-
consume(preflight: DesignResourceHandoffPreflightV1): void;
|
|
14
|
+
consume(preflight: DesignResourceHandoffPreflightV1 | DesignResourceHandoffPreflightV2): void;
|
|
14
15
|
finish(): void;
|
|
15
16
|
}
|
|
16
17
|
export declare function validateLongTaskDesignResourceHandoffs(contract: DeliveryContractV2, repository: string): Promise<void>;
|
|
@@ -2,8 +2,8 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { containsDesignResourceHandoff, parseDesignResourceHandoffMarkdown, } from "./design-resource-handoff-parser.js";
|
|
4
4
|
import { createDesignResourceHandoffSetIntegrity } from "./design-resource-handoff-set-integrity.js";
|
|
5
|
-
import {
|
|
6
|
-
import { assertSameSet, designSourceItemClaims, invalid, validateTargetIdentity, validateVerificationMethodBindings, } from "./long-task-design-resource-method-binding.js";
|
|
5
|
+
import { preflightParsedDesignResourceHandoffAny } from "./design-resource-handoff-validation.js";
|
|
6
|
+
import { assertSameSet, designSourceItemClaims, invalid, validateTargetIdentity, validateSymbolicTargetIdentity, validateSymbolicVerificationMethodBindings, validateVerificationMethodBindings, } from "./long-task-design-resource-method-binding.js";
|
|
7
7
|
import { validateLongTaskDesignTargetCapabilities } from "./long-task-design-target-capabilities.js";
|
|
8
8
|
import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
|
|
9
9
|
export async function validateLongTaskDesignResourceHandoffs(contract, repository) {
|
|
@@ -15,7 +15,7 @@ export async function validateLongTaskDesignResourceHandoffs(contract, repositor
|
|
|
15
15
|
const content = await readFile(file, "utf8");
|
|
16
16
|
if (!containsDesignResourceHandoff(content))
|
|
17
17
|
continue;
|
|
18
|
-
consumer.consume(await
|
|
18
|
+
consumer.consume(await preflightParsedDesignResourceHandoffAny(repository, parseDesignResourceHandoffMarkdown(sourcePath, content)));
|
|
19
19
|
}
|
|
20
20
|
consumer.finish();
|
|
21
21
|
}
|
|
@@ -32,9 +32,30 @@ export function createLongTaskDesignHandoffConsumer(contract) {
|
|
|
32
32
|
let duplicate = null;
|
|
33
33
|
const unbound = [];
|
|
34
34
|
const handoffSetIntegrity = createDesignResourceHandoffSetIntegrity(invalid);
|
|
35
|
+
const allSourceItems = new Set();
|
|
36
|
+
const resourcePaths = new Map();
|
|
37
|
+
let crossVersionIssue = null;
|
|
38
|
+
const recordCrossVersionIssue = (code, detail) => {
|
|
39
|
+
crossVersionIssue ??= { code, detail };
|
|
40
|
+
};
|
|
35
41
|
return {
|
|
36
42
|
consume(preflight) {
|
|
37
|
-
|
|
43
|
+
for (const sourceItem of preflight.source_item_keys) {
|
|
44
|
+
if (allSourceItems.has(sourceItem))
|
|
45
|
+
recordCrossVersionIssue("handoff_set_source_item_duplicate", sourceItem);
|
|
46
|
+
else
|
|
47
|
+
allSourceItems.add(sourceItem);
|
|
48
|
+
}
|
|
49
|
+
for (const resource of preflight.handoff.resources) {
|
|
50
|
+
const identity = JSON.stringify(resource);
|
|
51
|
+
const previous = resourcePaths.get(resource.path);
|
|
52
|
+
if (previous && previous !== identity)
|
|
53
|
+
recordCrossVersionIssue("handoff_set_resource_path_conflict", resource.path);
|
|
54
|
+
else
|
|
55
|
+
resourcePaths.set(resource.path, identity);
|
|
56
|
+
}
|
|
57
|
+
if (!("preflight_schema_version" in preflight))
|
|
58
|
+
handoffSetIntegrity.consume(preflight);
|
|
38
59
|
for (const target of preflight.handoff.targets) {
|
|
39
60
|
if (indexedTargetKeys.has(target.key)) {
|
|
40
61
|
duplicate ??= target.key;
|
|
@@ -46,13 +67,27 @@ export function createLongTaskDesignHandoffConsumer(contract) {
|
|
|
46
67
|
unbound.push(target.key);
|
|
47
68
|
continue;
|
|
48
69
|
}
|
|
49
|
-
const indexedTarget = { preflight, target };
|
|
50
70
|
consumed.add(target.key);
|
|
51
71
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
72
|
+
if ("preflight_schema_version" in preflight) {
|
|
73
|
+
const indexedTarget = {
|
|
74
|
+
preflight,
|
|
75
|
+
target,
|
|
76
|
+
};
|
|
77
|
+
validateSymbolicTargetIdentity(contractTarget, indexedTarget);
|
|
78
|
+
validateSymbolicCoverageClaims(contract, contractTarget, indexedTarget);
|
|
79
|
+
validateBlockerBindings(contract, contractTarget, indexedTarget);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const indexedTarget = {
|
|
83
|
+
preflight,
|
|
84
|
+
target: target,
|
|
85
|
+
};
|
|
86
|
+
validateTargetIdentity(contractTarget, indexedTarget);
|
|
87
|
+
validateLongTaskDesignTargetCapabilities(contract, contractTarget, indexedTarget);
|
|
88
|
+
validateCoverageClaims(contract, contractTarget, indexedTarget);
|
|
89
|
+
validateBlockerBindings(contract, contractTarget, indexedTarget);
|
|
90
|
+
}
|
|
56
91
|
}
|
|
57
92
|
catch (error) {
|
|
58
93
|
validationErrors.set(target.key, error);
|
|
@@ -63,6 +98,8 @@ export function createLongTaskDesignHandoffConsumer(contract) {
|
|
|
63
98
|
if (duplicate)
|
|
64
99
|
invalid("handoff_target_duplicate", duplicate);
|
|
65
100
|
handoffSetIntegrity.finish();
|
|
101
|
+
if (crossVersionIssue)
|
|
102
|
+
invalid(crossVersionIssue.code, crossVersionIssue.detail);
|
|
66
103
|
for (const contractTarget of contractTargets) {
|
|
67
104
|
if (!consumed.has(contractTarget.target.key))
|
|
68
105
|
invalid("target_handoff_missing", contractTarget.target.key);
|
|
@@ -74,6 +111,23 @@ export function createLongTaskDesignHandoffConsumer(contract) {
|
|
|
74
111
|
},
|
|
75
112
|
};
|
|
76
113
|
}
|
|
114
|
+
function validateSymbolicCoverageClaims(contract, contractTarget, indexed) {
|
|
115
|
+
const claims = new Map(contract.source_claims.map((item) => [item.key, item]));
|
|
116
|
+
const rows = indexed.preflight.handoff.coverage.filter((row) => row.target_ref === contractTarget.target.key);
|
|
117
|
+
if (!rows.length)
|
|
118
|
+
invalid("v2_target_covered_claims_required", contractTarget.target.key);
|
|
119
|
+
const sourceItemRefs = [
|
|
120
|
+
...new Set([
|
|
121
|
+
...rows.flatMap((row) => row.source_item_refs),
|
|
122
|
+
...indexed.preflight.manifest.fact_rules.flatMap((rule) => rule.source_item_refs),
|
|
123
|
+
...indexed.preflight.manifest.disposition_regions.flatMap((region) => region.source_item_refs),
|
|
124
|
+
]),
|
|
125
|
+
];
|
|
126
|
+
const claimsBySourceItem = new Map();
|
|
127
|
+
for (const sourceItemRef of sourceItemRefs)
|
|
128
|
+
claimsBySourceItem.set(sourceItemRef, designSourceItemClaims(contract, contractTarget, indexed, sourceItemRef, claims));
|
|
129
|
+
validateSymbolicVerificationMethodBindings(contract, contractTarget, indexed, claimsBySourceItem);
|
|
130
|
+
}
|
|
77
131
|
function validateCoverageClaims(contract, contractTarget, indexed) {
|
|
78
132
|
const target = contractTarget.target;
|
|
79
133
|
const check = contract.outcomes
|
|
@@ -103,8 +157,14 @@ function validateBlockerBindings(contract, contractTarget, indexed) {
|
|
|
103
157
|
item.key,
|
|
104
158
|
item,
|
|
105
159
|
]));
|
|
106
|
-
const availableMethods = new Set(
|
|
107
|
-
|
|
160
|
+
const availableMethods = new Set([
|
|
161
|
+
...contractTarget.target.verification_method_bindings,
|
|
162
|
+
...(contractTarget.target.symbolic_method_bindings ?? []),
|
|
163
|
+
].map((item) => item.method));
|
|
164
|
+
const blockers = "preflight_schema_version" in indexed.preflight
|
|
165
|
+
? indexed.preflight.manifest.acceptance_blockers
|
|
166
|
+
: indexed.preflight.handoff.acceptance_blockers;
|
|
167
|
+
for (const blocker of blockers) {
|
|
108
168
|
if (!blocker.target_refs.includes(contractTarget.target.key))
|
|
109
169
|
continue;
|
|
110
170
|
const contractBlocker = bound.get(blocker.key);
|