project-tiny-context-harness 0.8.1 → 0.8.2

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.
Files changed (132) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +401 -395
  3. package/assets/README.md +628 -549
  4. package/assets/README.zh-CN.md +345 -339
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +70 -70
  7. package/assets/context_templates/architecture.md +28 -28
  8. package/assets/context_templates/area.md +34 -34
  9. package/assets/context_templates/context.toml +30 -30
  10. package/assets/context_templates/deployment.md +35 -35
  11. package/assets/context_templates/global.md +57 -57
  12. package/assets/context_templates/product-surface-contract.md +70 -70
  13. package/assets/context_templates/screen-contract.md +189 -189
  14. package/assets/context_templates/verification.md +32 -32
  15. package/assets/github/.gitkeep +1 -1
  16. package/assets/github/harness.yml +39 -39
  17. package/assets/make/.gitkeep +1 -1
  18. package/assets/make/ty-context.mk +48 -48
  19. package/assets/skills/context_development_engineer/SKILL.md +137 -137
  20. package/assets/skills/context_full_project_export/SKILL.md +28 -28
  21. package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
  22. package/assets/skills/context_product_plan/SKILL.md +88 -88
  23. package/assets/skills/context_surface_contract/SKILL.md +191 -191
  24. package/assets/skills/context_uiux_design/SKILL.md +172 -172
  25. package/assets/skills/design-resource-authoring/SKILL.md +85 -85
  26. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +136 -136
  27. package/assets/skills/design-resource-authoring/references/open-design-provider.md +135 -135
  28. package/assets/skills/design-resource-authoring/references/resource-selection.md +173 -173
  29. package/assets/skills/design-system-authoring/SKILL.md +57 -57
  30. package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
  31. package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
  32. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
  33. package/assets/skills/long-task-workflow/SKILL.md +100 -100
  34. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +75 -73
  35. package/assets/skills/long-task-workflow/references/contract-authoring.md +119 -115
  36. package/assets/skills/long-task-workflow/references/evidence-design.md +77 -76
  37. package/assets/skills/long-task-workflow/references/source-authoring.md +102 -99
  38. package/assets/skills/source-plan-authoring/SKILL.md +14 -14
  39. package/assets/tools/validate_context.py +442 -442
  40. package/dist/commands/design-resource.js +2 -2
  41. package/dist/commands/index.js +26 -26
  42. package/dist/commands/long-task-authoring.js +83 -9
  43. package/dist/commands/long-task.js +15 -15
  44. package/dist/lib/context-graph-snapshot.js +7 -0
  45. package/dist/lib/design-resource-handoff-shape-evidence.js +3 -0
  46. package/dist/lib/design-resource-handoff-types.d.ts +2 -0
  47. package/dist/lib/design-resource-handoff-validation-coverage.js +1 -0
  48. package/dist/lib/design-resource-handoff-validation-structure.js +2 -0
  49. package/dist/lib/execution-target-capabilities.d.ts +2 -0
  50. package/dist/lib/execution-target-capabilities.js +31 -0
  51. package/dist/lib/long-task-acceptance-shape.js +81 -20
  52. package/dist/lib/long-task-applicability-shape.d.ts +4 -0
  53. package/dist/lib/long-task-applicability-shape.js +54 -0
  54. package/dist/lib/long-task-assertions-v2.js +8 -0
  55. package/dist/lib/long-task-authoring-preflight-diagnostics.js +5 -0
  56. package/dist/lib/long-task-authoring-preflight-repair-order.js +3 -0
  57. package/dist/lib/long-task-authoring-preflight.js +12 -8
  58. package/dist/lib/long-task-authority-materials.js +46 -4
  59. package/dist/lib/long-task-authority-policy.d.ts +54 -0
  60. package/dist/lib/long-task-authority-policy.js +61 -0
  61. package/dist/lib/long-task-authority-types.d.ts +12 -2
  62. package/dist/lib/long-task-authority.js +9 -2
  63. package/dist/lib/long-task-check-shape.js +6 -1
  64. package/dist/lib/long-task-claim-definitions.js +27 -42
  65. package/dist/lib/long-task-claims.js +275 -146
  66. package/dist/lib/long-task-contract-types.d.ts +42 -8
  67. package/dist/lib/long-task-control-fields.d.ts +12 -0
  68. package/dist/lib/long-task-control-fields.js +66 -0
  69. package/dist/lib/long-task-control-types.d.ts +1 -0
  70. package/dist/lib/long-task-control-types.js +1 -0
  71. package/dist/lib/long-task-counterfactual-claim-policy.js +7 -0
  72. package/dist/lib/long-task-counterfactual-types.d.ts +12 -0
  73. package/dist/lib/long-task-delivery-compiler.js +1 -0
  74. package/dist/lib/long-task-delivery-preflight.js +24 -0
  75. package/dist/lib/long-task-delivery-shape.d.ts +1 -0
  76. package/dist/lib/long-task-delivery-shape.js +1 -0
  77. package/dist/lib/long-task-delivery-types.d.ts +1 -0
  78. package/dist/lib/long-task-delivery-types.js +1 -0
  79. package/dist/lib/long-task-delivery-validation.js +46 -0
  80. package/dist/lib/long-task-design-resource-handoff.js +48 -7
  81. package/dist/lib/long-task-evidence-capability-codec.js +37 -0
  82. package/dist/lib/long-task-evidence-capability-policy.js +80 -38
  83. package/dist/lib/long-task-evidence-capability-runtime.js +36 -0
  84. package/dist/lib/long-task-evidence-capability-types.d.ts +13 -1
  85. package/dist/lib/long-task-evidence-findings.js +3 -0
  86. package/dist/lib/long-task-evidence-sensitivity-policy.js +38 -0
  87. package/dist/lib/long-task-evidence-v2.js +7 -1
  88. package/dist/lib/long-task-final-integrity.d.ts +16 -0
  89. package/dist/lib/long-task-final-integrity.js +98 -0
  90. package/dist/lib/long-task-final-v2.js +17 -34
  91. package/dist/lib/long-task-outcome-parser.js +22 -4
  92. package/dist/lib/long-task-playwright-case-evidence.d.ts +2 -0
  93. package/dist/lib/long-task-playwright-case-evidence.js +10 -2
  94. package/dist/lib/long-task-playwright-evidence.d.ts +1 -0
  95. package/dist/lib/long-task-playwright-evidence.js +32 -0
  96. package/dist/lib/long-task-product-shape.d.ts +3 -1
  97. package/dist/lib/long-task-product-shape.js +100 -4
  98. package/dist/lib/long-task-requirement-shape.js +3 -0
  99. package/dist/lib/long-task-root-shape.js +12 -6
  100. package/dist/lib/long-task-runner-freeze.js +16 -0
  101. package/dist/lib/long-task-runtime-types.d.ts +11 -2
  102. package/dist/lib/long-task-semantic-assurance-policy.d.ts +4 -0
  103. package/dist/lib/long-task-semantic-assurance-policy.js +52 -0
  104. package/dist/lib/long-task-semantic-contract-types.d.ts +18 -1
  105. package/dist/lib/long-task-semantic-drift-migration.js +33 -2
  106. package/dist/lib/long-task-semantic-mutation.d.ts +7 -0
  107. package/dist/lib/long-task-semantic-mutation.js +81 -0
  108. package/dist/lib/long-task-shape-primitives.d.ts +1 -1
  109. package/dist/lib/long-task-shape-primitives.js +1 -0
  110. package/dist/lib/long-task-source-authority-types.d.ts +2 -0
  111. package/dist/lib/long-task-source-item-parser.d.ts +1 -1
  112. package/dist/lib/long-task-source-item-parser.js +150 -104
  113. package/dist/lib/long-task-source-markers.d.ts +12 -0
  114. package/dist/lib/long-task-source-markers.js +146 -0
  115. package/dist/lib/long-task-source-target-continuity.d.ts +1 -1
  116. package/dist/lib/long-task-source-target-continuity.js +80 -55
  117. package/dist/lib/long-task-source-target-index.js +7 -29
  118. package/dist/lib/long-task-status-v2.d.ts +1 -0
  119. package/dist/lib/long-task-status-v2.js +2 -2
  120. package/dist/lib/long-task-target-policy.js +20 -0
  121. package/dist/lib/long-task-ui-design-policy.js +27 -1
  122. package/dist/lib/long-task-ui-surface-shape.js +21 -1
  123. package/dist/lib/long-task-ui-surface-types.d.ts +7 -0
  124. package/dist/lib/long-task-verification-preview.d.ts +10 -0
  125. package/dist/lib/long-task-verifier-dependency-closure.d.ts +3 -0
  126. package/dist/lib/long-task-verifier-dependency-closure.js +179 -0
  127. package/dist/lib/long-task-verifier-v2.js +12 -2
  128. package/dist/lib/long-task-workspace.js +5 -1
  129. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +99 -25
  130. package/migrations/README.md +15 -15
  131. package/package.json +84 -84
  132. package/source-mappings.yaml +25 -25
@@ -1,6 +1,7 @@
1
1
  import { parseGlobalCounterfactuals } from "./long-task-acceptance-shape.js";
2
2
  import { parseCheck } from "./long-task-check-shape.js";
3
- import { array, boolean, key, literal, object, parseKeyedPaths, parseKeyedStatements, repositoryFiles, string, strings, } from "./long-task-delivery-shape.js";
3
+ import { array, boolean, key, literal, object, parseApplicableKeyedStatements, parseClaimApplicability, parseKeyedPaths, repositoryFiles, string, strings, } from "./long-task-delivery-shape.js";
4
+ import { EXECUTION_TARGET_CAPABILITIES } from "./execution-target-capabilities.js";
4
5
  const RISK_FACTS = [
5
6
  "public_api_or_schema_change",
6
7
  "persistent_data_change",
@@ -51,6 +52,7 @@ export function parseTask(value) {
51
52
  "role",
52
53
  "runtime_family",
53
54
  "root_entrypoint",
55
+ "capabilities",
54
56
  ]);
55
57
  return {
56
58
  key: key(target.key, `${label}.key`),
@@ -65,13 +67,14 @@ export function parseTask(value) {
65
67
  "external",
66
68
  ], `${label}.runtime_family`),
67
69
  root_entrypoint: string(target.root_entrypoint, `${label}.root_entrypoint`),
70
+ capabilities: strings(target.capabilities, `${label}.capabilities`).map((item, capabilityIndex) => literal(item, EXECUTION_TARGET_CAPABILITIES, `${label}.capabilities[${capabilityIndex}]`)),
68
71
  };
69
72
  }),
70
73
  source_paths: repositoryFiles(row.source_paths, "task.source_paths"),
71
74
  context_refs: repositoryFiles(row.context_refs, "task.context_refs"),
72
75
  context_snapshot_mode: Object.hasOwn(row, "context_snapshot_mode")
73
76
  ? literal(row.context_snapshot_mode, ["referenced", "full"], "task.context_snapshot_mode")
74
- : "referenced",
77
+ : "full",
75
78
  };
76
79
  }
77
80
  export function parseStages(value) {
@@ -107,25 +110,28 @@ export function parseRisk(value) {
107
110
  };
108
111
  }
109
112
  export function parseGlobal(value) {
110
- const row = object(value, "global", [], ["product", "technical", "acceptance"]);
113
+ const row = object(value, "global", [], ["applicability", "product", "technical", "acceptance"]);
111
114
  const product = object(Object.hasOwn(row, "product") ? row.product : {}, "global.product", [], ["non_goals"]);
112
115
  const technical = object(Object.hasOwn(row, "technical") ? row.technical : {}, "global.technical", [], ["constraints", "forbidden_paths", "forbidden_shortcuts"]);
113
116
  const acceptance = object(Object.hasOwn(row, "acceptance") ? row.acceptance : {}, "global.acceptance", [], ["checks", "counterfactual_controls", "external_confirmations"]);
114
117
  return {
118
+ applicability: Object.hasOwn(row, "applicability")
119
+ ? parseClaimApplicability(row.applicability, "global.applicability")
120
+ : [],
115
121
  product: {
116
122
  non_goals: Object.hasOwn(product, "non_goals")
117
- ? parseKeyedStatements(product.non_goals, "global.product.non_goals")
123
+ ? parseApplicableKeyedStatements(product.non_goals, "global.product.non_goals")
118
124
  : [],
119
125
  },
120
126
  technical: {
121
127
  constraints: Object.hasOwn(technical, "constraints")
122
- ? parseKeyedStatements(technical.constraints, "global.technical.constraints")
128
+ ? parseApplicableKeyedStatements(technical.constraints, "global.technical.constraints")
123
129
  : [],
124
130
  forbidden_paths: Object.hasOwn(technical, "forbidden_paths")
125
131
  ? parseKeyedPaths(technical.forbidden_paths, "global.technical.forbidden_paths")
126
132
  : [],
127
133
  forbidden_shortcuts: Object.hasOwn(technical, "forbidden_shortcuts")
128
- ? parseKeyedStatements(technical.forbidden_shortcuts, "global.technical.forbidden_shortcuts")
134
+ ? parseApplicableKeyedStatements(technical.forbidden_shortcuts, "global.technical.forbidden_shortcuts")
129
135
  : [],
130
136
  },
131
137
  acceptance: {
@@ -7,6 +7,7 @@ import { nearestRunnerFile, npmCliPath, npxCliPath, } from "./long-task-runner-f
7
7
  import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
8
8
  import { repoRelative, resolveInsideRepository, } from "./long-task-workspace.js";
9
9
  import { evidenceAdapterForRunner } from "./long-task-evidence-adapter-policy.js";
10
+ import { freezeLocalVerifierDependencyClosure, packageScriptVerifierRoots, } from "./long-task-verifier-dependency-closure.js";
10
11
  export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline, executionTarget, knownExecutionTargets, designConformanceTargets) {
11
12
  const prefix = outcomeKey ? `CHECK.${outcomeKey}` : "CHECK.GLOBAL";
12
13
  const expectedOutputs = check.expected_output_paths.map((pattern, index) => assertRepositoryPattern(repository, pattern, `${check.key}.expected_output_paths[${index}]`));
@@ -164,6 +165,21 @@ async function freezeVerificationInputs(check, repository, manifest, cwd, target
164
165
  const protectedFile = await assertProtectedRepositoryFile(repository, path.join(repository, ...relative.split("/")), `${check.key}.automatic_verification_input`);
165
166
  result[relative] = sha256Hex(await readFile(protectedFile));
166
167
  }
168
+ if (check.runner.type === "package_script") {
169
+ const packageJson = JSON.parse(await readFile(target, "utf8"));
170
+ const script = packageJson.scripts?.[check.runner.target];
171
+ if (typeof script !== "string" || !script.trim())
172
+ throw new Error(`package_script_not_found:${check.key}:${check.runner.target}`);
173
+ for (const relative of packageScriptVerifierRoots(script, repoRelative(repository, target), manifest)) {
174
+ const protectedFile = await assertProtectedRepositoryFile(repository, path.join(repository, ...relative.split("/")), `${check.key}.package_script_entry`);
175
+ result[relative] = sha256Hex(await readFile(protectedFile));
176
+ }
177
+ }
178
+ Object.assign(result, await freezeLocalVerifierDependencyClosure(repository, Object.keys(result), manifest, [
179
+ ...check.input_paths,
180
+ ...check.expected_output_paths,
181
+ ...check.artifact_globs,
182
+ ]));
167
183
  return sortRecord(result);
168
184
  }
169
185
  function sortRecord(value) {
@@ -32,20 +32,24 @@ export interface ProductClaimV2 {
32
32
  id: string;
33
33
  outcome_key: string;
34
34
  local_key: string;
35
- kind: "result" | "requirement" | "control" | "non_completing" | "obligation" | "forbidden_shortcut";
35
+ kind: "result" | "requirement" | "control" | "control_relation" | "non_completing" | "obligation" | "forbidden_shortcut";
36
36
  required_proof_surfaces: ProofSurface[];
37
+ required_polarity: "positive" | "negative";
38
+ applicability_refs: string[];
37
39
  }
38
40
  export interface GlobalClaimV2 {
39
41
  id: string;
40
42
  local_key: string;
41
43
  kind: "global_non_goal" | "global_constraint" | "global_forbidden_shortcut";
42
- required_polarity: "any" | "negative";
44
+ required_polarity: "positive" | "negative";
45
+ applicability_refs: string[];
43
46
  }
44
47
  export interface ClaimProofV2 {
45
48
  check_key: string;
46
49
  assertion_key: string | null;
47
50
  polarity: "positive" | "negative" | "population" | "counterfactual";
48
51
  proof_surface: ProofSurface;
52
+ applicability_ref: string | null;
49
53
  }
50
54
  export interface ClaimCoverageSummaryV2 {
51
55
  claims_total: number;
@@ -53,6 +57,8 @@ export interface ClaimCoverageSummaryV2 {
53
57
  uncovered_claims: string[];
54
58
  claims_by_global: Record<string, {
55
59
  covered: boolean;
60
+ applicability_refs: string[];
61
+ uncovered_applicability_refs: string[];
56
62
  proofs: ClaimProofV2[];
57
63
  }>;
58
64
  claims_by_outcome: Record<string, Record<string, {
@@ -60,6 +66,8 @@ export interface ClaimCoverageSummaryV2 {
60
66
  covered_surfaces: ProofSurface[];
61
67
  missing_surfaces: ProofSurface[];
62
68
  covered: boolean;
69
+ applicability_refs: string[];
70
+ uncovered_applicability_refs: string[];
63
71
  proofs: ClaimProofV2[];
64
72
  }>>;
65
73
  }
@@ -129,6 +137,7 @@ export interface AssertionResultV2 {
129
137
  polarity: "positive" | "negative";
130
138
  passed: boolean;
131
139
  claims: string[];
140
+ applicability_ref?: string;
132
141
  observation: string;
133
142
  evidence_capabilities: EvidenceCapabilityV2[];
134
143
  evidence_complete: boolean;
@@ -0,0 +1,4 @@
1
+ import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
2
+ type Reporter = (message: string) => void;
3
+ export declare function validateSemanticAssuranceShape(contract: DeliveryContractV2, report?: Reporter): void;
4
+ export {};
@@ -0,0 +1,52 @@
1
+ export function validateSemanticAssuranceShape(contract, report) {
2
+ if (contract.task.context_snapshot_mode !== "full")
3
+ issue(report, "long_task_full_context_required", contract.task.context_snapshot_mode);
4
+ validateApplicabilityScope("GLOBAL", contract.global.applicability, report);
5
+ for (const outcome of contract.outcomes)
6
+ validateApplicabilityScope(outcome.key, outcome.applicability, report);
7
+ }
8
+ function validateApplicabilityScope(scope, profiles, report) {
9
+ if (!profiles.length)
10
+ return;
11
+ let expectedDimensionKeys = null;
12
+ const cells = new Map();
13
+ for (const profile of profiles) {
14
+ if (!profile.dimensions.length)
15
+ issue(report, "applicability_dimensions_required", `${scope}:${profile.key}`);
16
+ const keys = profile.dimensions.map((dimension) => dimension.key);
17
+ if (new Set(keys).size !== keys.length)
18
+ issue(report, "applicability_dimension_duplicate", `${scope}:${profile.key}`);
19
+ const sortedKeys = [...keys].sort();
20
+ if (expectedDimensionKeys === null)
21
+ expectedDimensionKeys = sortedKeys;
22
+ else if (!same(expectedDimensionKeys, sortedKeys))
23
+ issue(report, "applicability_dimension_set_mismatch", `${scope}:${profile.key}:${expectedDimensionKeys.join(",")}:${sortedKeys.join(",")}`);
24
+ const dimensions = [...profile.dimensions]
25
+ .sort((left, right) => left.key.localeCompare(right.key))
26
+ .map((dimension) => `${dimension.key}=${dimension.value}`)
27
+ .join(",");
28
+ const cell = [
29
+ profile.target_ref,
30
+ profile.journey_role,
31
+ dimensions,
32
+ [...profile.given_refs].sort().join(","),
33
+ profile.when_refs.join(","),
34
+ ].join("|");
35
+ const owner = cells.get(cell);
36
+ if (owner)
37
+ issue(report, "applicability_cell_duplicate", `${scope}:${profile.key}:${owner}`);
38
+ else
39
+ cells.set(cell, profile.key);
40
+ }
41
+ }
42
+ function same(left, right) {
43
+ return (left.length === right.length &&
44
+ left.every((value, index) => value === right[index]));
45
+ }
46
+ function issue(report, code, detail) {
47
+ const message = `delivery_contract_invalid:${code}:${detail}`;
48
+ if (report)
49
+ report(message);
50
+ else
51
+ throw new Error(message);
52
+ }
@@ -1,7 +1,12 @@
1
+ import type { ExecutionTargetCapabilityV2 } from "./execution-target-capabilities.js";
2
+ export type { ExecutionTargetCapabilityV2 } from "./execution-target-capabilities.js";
1
3
  export interface KeyedStatementV2 {
2
4
  key: string;
3
5
  statement: string;
4
6
  }
7
+ export interface ApplicableKeyedStatementV2 extends KeyedStatementV2 {
8
+ applicability_refs: string[];
9
+ }
5
10
  export type ExternalConfirmationKindV2 = "functional_prerequisite" | "field_validation" | "production_release_gate" | "commercial_activation" | "expert_authority";
6
11
  export type TargetCompletionStateV2 = "implementation_complete" | "target_profile_usable" | "production_release_ready";
7
12
  export type ExecutionTargetRuntimeFamilyV2 = "browser" | "native" | "desktop" | "service" | "process" | "external";
@@ -17,6 +22,7 @@ export interface ExecutionTargetV2 {
17
22
  role: "product" | "support" | "observer";
18
23
  runtime_family: ExecutionTargetRuntimeFamilyV2;
19
24
  root_entrypoint: string;
25
+ capabilities: ExecutionTargetCapabilityV2[];
20
26
  }
21
27
  export interface DeliveryStageV2 {
22
28
  key: string;
@@ -25,7 +31,18 @@ export interface DeliveryStageV2 {
25
31
  gate_outcome: string;
26
32
  }
27
33
  export type DeliveryJourneyRoleV2 = "success" | "degradation" | "recovery" | "stage_gate" | "conformance";
28
- export type EvidenceCapabilityV2 = "presence" | "interaction_trace" | "state_delta" | "cross_surface_consistency" | "durable_readback" | "boundary_invocation" | "external_side_effect" | "failure_injection" | "visual_render" | "design_conformance" | "target_runtime" | "input_variation";
34
+ export interface ClaimApplicabilityV2 {
35
+ key: string;
36
+ target_ref: string;
37
+ journey_role: DeliveryJourneyRoleV2;
38
+ dimensions: Array<{
39
+ key: string;
40
+ value: string;
41
+ }>;
42
+ given_refs: string[];
43
+ when_refs: string[];
44
+ }
45
+ export type EvidenceCapabilityV2 = "presence" | "interaction_trace" | "state_delta" | "cross_surface_consistency" | "durable_readback" | "boundary_invocation" | "external_side_effect" | "failure_injection" | "visual_render" | "design_conformance" | "design_method" | "target_runtime" | "input_variation";
29
46
  export interface CheckExecutionTargetV2 {
30
47
  target_ref: string;
31
48
  entrypoint: "root" | "internal";
@@ -6,7 +6,12 @@ export function semanticDriftMigrationFields(value) {
6
6
  required(root, "$", ["stages"], missing);
7
7
  const task = row(root.task);
8
8
  if (task) {
9
- required(task, "task", ["target_profile", "execution_targets"], missing);
9
+ required(task, "task", ["target_profile", "execution_targets", "context_snapshot_mode"], missing);
10
+ if (Object.hasOwn(task, "context_snapshot_mode") &&
11
+ task.context_snapshot_mode !== "full")
12
+ missing.push("task.context_snapshot_mode=full");
13
+ for (const [index, target] of rows(task.execution_targets).entries())
14
+ required(target, `task.execution_targets[${index}]`, ["capabilities"], missing);
10
15
  const profile = row(task.target_profile);
11
16
  if (profile)
12
17
  required(profile, "task.target_profile", ["required_target_refs"], missing);
@@ -14,6 +19,7 @@ export function semanticDriftMigrationFields(value) {
14
19
  for (const [index, outcome] of rows(root.outcomes).entries())
15
20
  collectOutcome(outcome, `outcomes[${index}]`, missing);
16
21
  const global = row(root.global);
22
+ collectApplicability(global?.applicability, "global.applicability", missing);
17
23
  const globalAcceptance = row(global?.acceptance);
18
24
  collectChecks(globalAcceptance?.checks, "global.acceptance.checks", missing);
19
25
  for (const [index, confirmation] of rows(globalAcceptance?.external_confirmations).entries())
@@ -35,7 +41,8 @@ export function assertNoSemanticDriftMigration(fields) {
35
41
  throw new Error(`long_task_delivery_v2_semantic_drift_migration_required:${detail}${suffix}`);
36
42
  }
37
43
  function collectOutcome(outcome, label, missing) {
38
- required(outcome, label, ["stage"], missing);
44
+ required(outcome, label, ["stage", "applicability"], missing);
45
+ collectApplicability(outcome.applicability, `${label}.applicability`, missing);
39
46
  const product = row(outcome.product);
40
47
  if (product) {
41
48
  required(product, `${label}.product`, ["success_path_required", "degradation_path_required"], missing);
@@ -43,9 +50,33 @@ function collectOutcome(outcome, label, missing) {
43
50
  product.controls.length > 0 &&
44
51
  !Object.hasOwn(product, "surface_bindings"))
45
52
  missing.push(`${label}.product.surface_bindings`);
53
+ const relationClosure = row(product.control_relation_closure);
54
+ if (relationClosure && relationClosure.state !== "unresolved")
55
+ required(relationClosure, `${label}.product.control_relation_closure`, ["applicability_refs"], missing);
46
56
  }
47
57
  const acceptance = row(outcome.acceptance);
48
58
  collectChecks(acceptance?.checks, `${label}.acceptance.checks`, missing);
59
+ const population = row(acceptance?.population);
60
+ if (population) {
61
+ required(population, `${label}.acceptance.population`, ["universe_binding_key"], missing);
62
+ const observations = row(population.observations);
63
+ if (observations)
64
+ required(observations, `${label}.acceptance.population.observations`, ["universe_ids"], missing);
65
+ }
66
+ for (const [bindingIndex, binding] of rows(product?.surface_bindings).entries()) {
67
+ for (const [blockerIndex, blocker] of rows(binding.acceptance_blockers).entries())
68
+ required(blocker, `${label}.product.surface_bindings[${bindingIndex}].acceptance_blockers[${blockerIndex}]`, ["required_capabilities"], missing);
69
+ for (const [targetIndex, target] of rows(binding.design_targets).entries())
70
+ for (const [methodIndex, method] of rows(target.verification_method_bindings).entries()) {
71
+ required(method, `${label}.product.surface_bindings[${bindingIndex}].design_targets[${targetIndex}].verification_method_bindings[${methodIndex}]`, ["evidence_artifacts"], missing);
72
+ for (const [artifactIndex, artifact] of rows(method.evidence_artifacts).entries())
73
+ required(artifact, `${label}.product.surface_bindings[${bindingIndex}].design_targets[${targetIndex}].verification_method_bindings[${methodIndex}].evidence_artifacts[${artifactIndex}]`, ["observation_path"], missing);
74
+ }
75
+ }
76
+ }
77
+ function collectApplicability(value, label, missing) {
78
+ for (const [index, profile] of rows(value).entries())
79
+ required(profile, `${label}[${index}]`, ["dimensions"], missing);
49
80
  }
50
81
  function collectChecks(value, label, missing) {
51
82
  for (const [index, check] of rows(value).entries()) {
@@ -0,0 +1,7 @@
1
+ import type { CounterfactualMutationV2 } from "./long-task-delivery-types.js";
2
+ type NarrowMutation = Extract<CounterfactualMutationV2, {
3
+ type: "replace_json_value" | "replace_text";
4
+ }>;
5
+ export declare function applyNarrowSemanticMutation(root: string, mutation: NarrowMutation): Promise<void>;
6
+ export declare function mutateSemanticText(current: string, mutation: NarrowMutation, requireChange?: boolean): string;
7
+ export {};
@@ -0,0 +1,81 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { canonicalValueJson } from "./strict-codec.js";
4
+ export async function applyNarrowSemanticMutation(root, mutation) {
5
+ const target = path.join(root, ...mutation.path.split("/"));
6
+ const current = await readFile(target, "utf8");
7
+ const next = mutateSemanticText(current, mutation, false);
8
+ await writeFile(target, next, "utf8");
9
+ }
10
+ export function mutateSemanticText(current, mutation, requireChange = true) {
11
+ if (mutation.type === "replace_text") {
12
+ if (requireChange && mutation.match === mutation.replacement)
13
+ throw new Error("counterfactual_replacement_must_change_carrier");
14
+ const count = occurrences(current, mutation.match);
15
+ if (count !== 1)
16
+ throw new Error(`counterfactual_text_match_count:${count}`);
17
+ return current.replace(mutation.match, mutation.replacement);
18
+ }
19
+ let value;
20
+ try {
21
+ value = JSON.parse(current);
22
+ }
23
+ catch {
24
+ throw new Error("counterfactual_json_invalid");
25
+ }
26
+ const segments = mutation.pointer
27
+ .slice(1)
28
+ .split("/")
29
+ .map((segment) => segment.replace(/~1/gu, "/").replace(/~0/gu, "~"));
30
+ let owner = value;
31
+ for (const segment of segments.slice(0, -1))
32
+ owner = child(owner, segment, mutation.pointer);
33
+ const leaf = segments.at(-1);
34
+ if (!owner || typeof owner !== "object")
35
+ throw new Error(`counterfactual_json_pointer_unknown:${mutation.pointer}`);
36
+ if (Array.isArray(owner)) {
37
+ const index = arrayIndex(leaf, owner.length, mutation.pointer);
38
+ if (requireChange &&
39
+ canonicalValueJson(owner[index]) === canonicalValueJson(mutation.value))
40
+ throw new Error("counterfactual_replacement_must_change_carrier");
41
+ owner[index] = mutation.value;
42
+ }
43
+ else {
44
+ const record = owner;
45
+ if (!Object.hasOwn(record, leaf))
46
+ throw new Error(`counterfactual_json_pointer_unknown:${mutation.pointer}`);
47
+ if (requireChange &&
48
+ canonicalValueJson(record[leaf]) === canonicalValueJson(mutation.value))
49
+ throw new Error("counterfactual_replacement_must_change_carrier");
50
+ record[leaf] = mutation.value;
51
+ }
52
+ return `${JSON.stringify(value, null, 2)}\n`;
53
+ }
54
+ function child(value, segment, pointer) {
55
+ if (!value || typeof value !== "object")
56
+ throw new Error(`counterfactual_json_pointer_unknown:${pointer}`);
57
+ if (Array.isArray(value))
58
+ return value[arrayIndex(segment, value.length, pointer)];
59
+ if (!Object.hasOwn(value, segment))
60
+ throw new Error(`counterfactual_json_pointer_unknown:${pointer}`);
61
+ return value[segment];
62
+ }
63
+ function arrayIndex(value, length, pointer) {
64
+ if (!/^(?:0|[1-9][0-9]*)$/u.test(value))
65
+ throw new Error(`counterfactual_json_pointer_unknown:${pointer}`);
66
+ const index = Number(value);
67
+ if (!Number.isSafeInteger(index) || index >= length)
68
+ throw new Error(`counterfactual_json_pointer_unknown:${pointer}`);
69
+ return index;
70
+ }
71
+ function occurrences(value, search) {
72
+ let count = 0;
73
+ let offset = 0;
74
+ while (true) {
75
+ const index = value.indexOf(search, offset);
76
+ if (index < 0)
77
+ return count;
78
+ count += 1;
79
+ offset = index + search.length;
80
+ }
81
+ }
@@ -16,5 +16,5 @@ export declare function key(value: unknown, label: string): string;
16
16
  export declare function nullable<T>(value: unknown, parser: (value: unknown) => T): T | null;
17
17
  export declare const PROOF_SURFACES: readonly ["ui_browser", "runtime_behavior", "api_contract", "data_state", "security_boundary", "population_coverage", "implementation_structure"];
18
18
  export declare const JOURNEY_ROLES: readonly ["success", "degradation", "recovery", "stage_gate", "conformance"];
19
- export declare const EVIDENCE_CAPABILITIES: readonly ["presence", "interaction_trace", "state_delta", "cross_surface_consistency", "durable_readback", "boundary_invocation", "external_side_effect", "failure_injection", "visual_render", "design_conformance", "target_runtime", "input_variation"];
19
+ export declare const EVIDENCE_CAPABILITIES: readonly ["presence", "interaction_trace", "state_delta", "cross_surface_consistency", "durable_readback", "boundary_invocation", "external_side_effect", "failure_injection", "visual_render", "design_conformance", "design_method", "target_runtime", "input_variation"];
20
20
  export declare function fail(label: string, message: string): never;
@@ -99,6 +99,7 @@ export const EVIDENCE_CAPABILITIES = [
99
99
  "failure_injection",
100
100
  "visual_render",
101
101
  "design_conformance",
102
+ "design_method",
102
103
  "target_runtime",
103
104
  "input_variation",
104
105
  ];
@@ -1,8 +1,10 @@
1
1
  import type { RiskFactName } from "./long-task-risk-types.js";
2
2
  export type SourceItemKind = "outcome_result" | "requirement" | "control" | "acceptance" | "technical_obligation" | "non_completing" | "non_goal" | "forbidden_shortcut" | "risk_fact" | "external_confirmation" | "decision";
3
+ export type SourceItemAspect = "architecture";
3
4
  export interface CompiledSourceItemV2 {
4
5
  key: string;
5
6
  kind: SourceItemKind;
7
+ aspect?: SourceItemAspect;
6
8
  source_path: string;
7
9
  normalized_text: string;
8
10
  text_sha256: string;
@@ -1,3 +1,3 @@
1
1
  import type { CompiledSourceItemV2 } from "./long-task-delivery-types.js";
2
2
  export declare function parseSourceItems(sourcePath: string, content: string): CompiledSourceItemV2[];
3
- export declare function normalizeSourceItemText(value: string): string;
3
+ export { normalizeSourceItemText } from "./long-task-source-markers.js";