project-tiny-context-harness 0.8.13 → 0.8.17

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 (103) hide show
  1. package/README.md +53 -28
  2. package/assets/README.md +52 -25
  3. package/assets/README.zh-CN.md +55 -26
  4. package/assets/agents/AGENTS_CORE.md +2 -2
  5. package/assets/agents/long-task-implementation.toml +1 -1
  6. package/assets/context_templates/screen-contract.md +16 -0
  7. package/assets/skills/context_development_engineer/SKILL.md +16 -30
  8. package/assets/skills/context_development_engineer/references/engineering-design-reasoning.md +93 -0
  9. package/assets/skills/context_surface_contract/SKILL.md +13 -2
  10. package/assets/skills/context_uiux_design/SKILL.md +7 -3
  11. package/assets/skills/context_uiux_design/references/task-uiux-analysis.md +82 -0
  12. package/assets/skills/design-resource-authoring/SKILL.md +14 -8
  13. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +18 -6
  14. package/assets/skills/design-resource-authoring/references/formal-selected-web-app-handoff.md +26 -8
  15. package/assets/skills/design-resource-authoring/references/implementation-feasibility.md +111 -0
  16. package/assets/skills/design-resource-authoring/references/open-design-provider.md +45 -7
  17. package/assets/skills/design-resource-authoring/references/recovery-and-writeback.md +7 -1
  18. package/assets/skills/design-resource-authoring/references/resource-selection.md +115 -3
  19. package/assets/skills/long-task-workflow/SKILL.md +9 -7
  20. package/assets/skills/long-task-workflow/agents/openai.yaml +1 -1
  21. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +1 -1
  22. package/dist/commands/design-resource.js +9 -2
  23. package/dist/commands/long-task-revision.js +4 -4
  24. package/dist/index.d.ts +1 -1
  25. package/dist/lib/design-resource-handoff-bundle.js +5 -0
  26. package/dist/lib/design-resource-handoff-input-types.d.ts +1 -1
  27. package/dist/lib/design-resource-handoff-manifest-projection.js +1 -0
  28. package/dist/lib/design-resource-handoff-set-integrity.js +1 -0
  29. package/dist/lib/design-resource-handoff-shape.js +6 -2
  30. package/dist/lib/design-resource-handoff-types.d.ts +5 -0
  31. package/dist/lib/design-resource-handoff-validation.js +12 -0
  32. package/dist/lib/design-resource-implementation-feasibility-model.d.ts +35 -0
  33. package/dist/lib/design-resource-implementation-feasibility-model.js +62 -0
  34. package/dist/lib/design-resource-implementation-feasibility-shape-sections.d.ts +43 -0
  35. package/dist/lib/design-resource-implementation-feasibility-shape-sections.js +142 -0
  36. package/dist/lib/design-resource-implementation-feasibility-shape.d.ts +4 -0
  37. package/dist/lib/design-resource-implementation-feasibility-shape.js +154 -0
  38. package/dist/lib/design-resource-implementation-feasibility-source-decision-projection.d.ts +24 -0
  39. package/dist/lib/design-resource-implementation-feasibility-source-decision-projection.js +106 -0
  40. package/dist/lib/design-resource-implementation-feasibility-source-decision.d.ts +21 -0
  41. package/dist/lib/design-resource-implementation-feasibility-source-decision.js +75 -0
  42. package/dist/lib/design-resource-implementation-feasibility-types.d.ts +135 -0
  43. package/dist/lib/design-resource-implementation-feasibility-types.js +37 -0
  44. package/dist/lib/design-resource-implementation-feasibility-validation-cells.d.ts +5 -0
  45. package/dist/lib/design-resource-implementation-feasibility-validation-cells.js +125 -0
  46. package/dist/lib/design-resource-implementation-feasibility-validation-document.d.ts +4 -0
  47. package/dist/lib/design-resource-implementation-feasibility-validation-document.js +167 -0
  48. package/dist/lib/design-resource-implementation-feasibility-validation-facts.d.ts +3 -0
  49. package/dist/lib/design-resource-implementation-feasibility-validation-facts.js +76 -0
  50. package/dist/lib/design-resource-implementation-feasibility-validation-realizations.d.ts +8 -0
  51. package/dist/lib/design-resource-implementation-feasibility-validation-realizations.js +76 -0
  52. package/dist/lib/design-resource-implementation-feasibility-validation-support.d.ts +10 -0
  53. package/dist/lib/design-resource-implementation-feasibility-validation-support.js +75 -0
  54. package/dist/lib/design-resource-implementation-feasibility-validation.d.ts +3 -0
  55. package/dist/lib/design-resource-implementation-feasibility-validation.js +138 -0
  56. package/dist/lib/design-resource-symbolic-fact-shape.js +3 -1
  57. package/dist/lib/design-resource-symbolic-fact-types.d.ts +5 -0
  58. package/dist/lib/design-resource-symbolic-fact-validation.js +13 -0
  59. package/dist/lib/long-task-activation-validation.js +77 -7
  60. package/dist/lib/long-task-authority-revision-brief.js +3 -1
  61. package/dist/lib/long-task-authority-revision-summary.js +6 -2
  62. package/dist/lib/long-task-authority-revision-types.d.ts +2 -0
  63. package/dist/lib/long-task-check-runner.js +3 -296
  64. package/dist/lib/long-task-command-process.d.ts +9 -0
  65. package/dist/lib/long-task-command-process.js +175 -0
  66. package/dist/lib/long-task-delivery-validation.d.ts +5 -2
  67. package/dist/lib/long-task-delivery-validation.js +4 -4
  68. package/dist/lib/long-task-design-feasibility-binding-owners.d.ts +6 -0
  69. package/dist/lib/long-task-design-feasibility-binding-owners.js +52 -0
  70. package/dist/lib/long-task-design-feasibility-binding.d.ts +13 -0
  71. package/dist/lib/long-task-design-feasibility-binding.js +114 -0
  72. package/dist/lib/long-task-design-feasibility-source-closure.d.ts +11 -0
  73. package/dist/lib/long-task-design-feasibility-source-closure.js +78 -0
  74. package/dist/lib/long-task-design-resource-handoff.d.ts +3 -3
  75. package/dist/lib/long-task-design-resource-handoff.js +39 -3
  76. package/dist/lib/long-task-design-resource-method-binding.js +16 -4
  77. package/dist/lib/long-task-freshness.js +1 -1
  78. package/dist/lib/long-task-git.d.ts +26 -0
  79. package/dist/lib/long-task-git.js +130 -0
  80. package/dist/lib/long-task-paths.js +1 -1
  81. package/dist/lib/long-task-process-runtime-closure.js +74 -42
  82. package/dist/lib/long-task-process-table.d.ts +12 -0
  83. package/dist/lib/long-task-process-table.js +119 -0
  84. package/dist/lib/long-task-process-tree.d.ts +9 -0
  85. package/dist/lib/long-task-process-tree.js +138 -0
  86. package/dist/lib/long-task-protected-files.d.ts +1 -1
  87. package/dist/lib/long-task-protected-files.js +1 -1
  88. package/dist/lib/long-task-ui-surface-policy.d.ts +2 -1
  89. package/dist/lib/long-task-ui-surface-policy.js +7 -4
  90. package/dist/lib/long-task-ui-surface-validation.d.ts +3 -1
  91. package/dist/lib/long-task-ui-surface-validation.js +2 -2
  92. package/dist/lib/long-task-verifier-authority.js +2 -0
  93. package/dist/lib/long-task-workspace-manifest.d.ts +8 -0
  94. package/dist/lib/long-task-workspace-manifest.js +173 -0
  95. package/dist/lib/long-task-workspace-snapshot.d.ts +8 -0
  96. package/dist/lib/long-task-workspace-snapshot.js +176 -0
  97. package/dist/lib/long-task-workspace.d.ts +4 -25
  98. package/dist/lib/long-task-workspace.js +3 -432
  99. package/dist/lib/repository-path-safety.d.ts +2 -0
  100. package/dist/lib/repository-path-safety.js +36 -0
  101. package/dist/long-task-hook.js +12 -3
  102. package/dist/public-types.d.ts +1 -0
  103. package/package.json +1 -1
@@ -0,0 +1,138 @@
1
+ import { readFile, stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parseDesignResourceImplementationFeasibilityJson } from "./design-resource-implementation-feasibility-shape.js";
4
+ import { loadDesignResourceFeasibilityDecisionSource, } from "./design-resource-implementation-feasibility-source-decision.js";
5
+ import { validateFeasibilityDocument } from "./design-resource-implementation-feasibility-validation-document.js";
6
+ import { invalidFeasibility, unique, } from "./design-resource-implementation-feasibility-validation-support.js";
7
+ import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
8
+ import { sha256Hex } from "./strict-codec.js";
9
+ const FEASIBILITY_MAX_BYTES = 2_097_152;
10
+ const TECHNICAL_SOURCE_MAX_BYTES = 16_777_216;
11
+ export async function readAndValidateDesignResourceImplementationFeasibility(repository, handoffPath, inputs, targetModels, canonicalResourcePaths) {
12
+ unique(inputs.map((item) => item.key), "input_key_duplicate");
13
+ unique(inputs.map((item) => item.path), "input_path_duplicate");
14
+ unique(inputs.map((item) => item.target_ref), "input_target_duplicate");
15
+ for (const input of inputs)
16
+ if (!targetModels.has(input.target_ref))
17
+ invalidFeasibility("input_target_unknown", input.target_ref);
18
+ validateTargetInputCoverage(inputs, targetModels);
19
+ const loaded = [];
20
+ const sourcePathIdentities = new Map();
21
+ for (const input of inputs) {
22
+ const model = targetModels.get(input.target_ref);
23
+ if (!model)
24
+ invalidFeasibility("input_target_unknown", input.target_ref);
25
+ if (input.path === handoffPath)
26
+ invalidFeasibility("input_must_not_be_handoff", input.key);
27
+ if (canonicalResourcePaths.has(input.path))
28
+ invalidFeasibility("input_mixed_into_canonical_resources", input.path);
29
+ const file = await assertProtectedRepositoryFile(repository, path.resolve(repository, ...input.path.split("/")), `design_resource_feasibility:${input.key}`);
30
+ const size = (await stat(file)).size;
31
+ if (size > FEASIBILITY_MAX_BYTES)
32
+ invalidFeasibility("input_byte_limit_exceeded", `${input.key}:bytes=${size}:limit=${FEASIBILITY_MAX_BYTES}`);
33
+ const bytes = await readFile(file);
34
+ const digest = sha256Hex(bytes);
35
+ if (digest !== input.sha256)
36
+ invalidFeasibility("input_digest_mismatch", `${input.key}:${input.sha256}:${digest}`);
37
+ const content = bytes.toString("utf8");
38
+ if (!Buffer.from(content, "utf8").equals(bytes))
39
+ invalidFeasibility("input_utf8_invalid", input.key);
40
+ const document = parseDesignResourceImplementationFeasibilityJson(content);
41
+ if (document.key !== input.key)
42
+ invalidFeasibility("input_key_mismatch", `${input.key}:${document.key}`);
43
+ if (document.target_ref !== input.target_ref)
44
+ invalidFeasibility("input_target_mismatch", `${input.target_ref}:${document.target_ref}`);
45
+ const decisionSources = await validateTechnicalSourceRecords(repository, handoffPath, input.path, document.source_records, canonicalResourcePaths, sourcePathIdentities);
46
+ await validateFeasibilityDocument(repository, document, model, decisionSources);
47
+ loaded.push({
48
+ index: input,
49
+ document,
50
+ identity: {
51
+ key: input.key,
52
+ target_ref: input.target_ref,
53
+ path: input.path,
54
+ sha256: digest,
55
+ realization_mode: document.realization_mode,
56
+ component_family_cells: document.component_family_cells.length,
57
+ blockers: document.blockers.length,
58
+ },
59
+ });
60
+ }
61
+ return loaded;
62
+ }
63
+ function validateTargetInputCoverage(inputs, targetModels) {
64
+ if (!inputs.length)
65
+ return;
66
+ const indexedTargets = new Set(inputs.map((item) => item.target_ref));
67
+ for (const model of targetModels.values())
68
+ if (model.source_profile_kind !== "reference" &&
69
+ !indexedTargets.has(model.target_ref))
70
+ invalidFeasibility("implementation_target_input_missing", model.target_ref);
71
+ }
72
+ async function validateTechnicalSourceRecords(repository, handoffPath, inputPath, records, canonicalResourcePaths, sharedPathIdentities) {
73
+ const decisionSources = new Map();
74
+ unique(records.map((item) => item.key), "source_record_key_duplicate");
75
+ unique(records.map((item) => `${item.path}\0${item.locator.kind}\0${item.locator.value}`), "source_record_locator_duplicate");
76
+ for (const record of records) {
77
+ if (!record.roles.length)
78
+ invalidFeasibility("source_record_roles_required", record.key);
79
+ unique(record.roles, "source_record_role_duplicate", record.key);
80
+ if (record.path === handoffPath || record.path === inputPath)
81
+ invalidFeasibility("source_record_self_reference", `${record.key}:${record.path}`);
82
+ if (canonicalResourcePaths.has(record.path))
83
+ invalidFeasibility("technical_source_mixed_into_canonical_resources", record.path);
84
+ validateSharedSourceIdentity(record, sharedPathIdentities);
85
+ const file = await assertProtectedRepositoryFile(repository, path.resolve(repository, ...record.path.split("/")), `design_resource_feasibility_source:${record.key}`);
86
+ const size = (await stat(file)).size;
87
+ if (size > TECHNICAL_SOURCE_MAX_BYTES)
88
+ invalidFeasibility("source_record_byte_limit_exceeded", `${record.key}:bytes=${size}:limit=${TECHNICAL_SOURCE_MAX_BYTES}`);
89
+ const bytes = await readFile(file);
90
+ const digest = sha256Hex(bytes);
91
+ if (digest !== record.sha256)
92
+ invalidFeasibility("source_record_digest_mismatch", `${record.key}:${record.sha256}:${digest}`);
93
+ const decisionSource = validateSourceLocator(record, bytes);
94
+ if (decisionSource)
95
+ decisionSources.set(record.key, decisionSource);
96
+ }
97
+ return decisionSources;
98
+ }
99
+ function validateSharedSourceIdentity(record, sharedPathIdentities) {
100
+ const identity = `${record.media_type}\0${record.sha256}`;
101
+ const previous = sharedPathIdentities.get(record.path);
102
+ if (previous && previous !== identity)
103
+ invalidFeasibility("source_record_path_identity_conflict", record.path);
104
+ sharedPathIdentities.set(record.path, identity);
105
+ }
106
+ function validateSourceLocator(record, bytes) {
107
+ if (record.locator.kind === "whole_resource")
108
+ return null;
109
+ const content = bytes.toString("utf8");
110
+ if (!Buffer.from(content, "utf8").equals(bytes))
111
+ invalidFeasibility("source_record_utf8_invalid", record.key);
112
+ if (record.locator.kind === "source_item")
113
+ return loadDesignResourceFeasibilityDecisionSource(record, content);
114
+ if (record.locator.kind === "json_pointer") {
115
+ validateJsonPointer(record, content);
116
+ return null;
117
+ }
118
+ if (!content.includes(record.locator.value))
119
+ invalidFeasibility("source_record_locator_unresolved", `${record.key}:${record.locator.value}`);
120
+ return null;
121
+ }
122
+ function validateJsonPointer(record, content) {
123
+ let current;
124
+ try {
125
+ current = JSON.parse(content);
126
+ }
127
+ catch {
128
+ invalidFeasibility("source_record_json_invalid", record.key);
129
+ }
130
+ for (const raw of record.locator.value.slice(1).split("/")) {
131
+ const segment = raw.replace(/~1/gu, "/").replace(/~0/gu, "~");
132
+ if (!current ||
133
+ typeof current !== "object" ||
134
+ !Object.hasOwn(current, segment))
135
+ invalidFeasibility("source_record_locator_unresolved", `${record.key}:${record.locator.value}`);
136
+ current = current[segment];
137
+ }
138
+ }
@@ -1,5 +1,6 @@
1
1
  import { parseDesignResourceHandoffResources } from "./design-resource-handoff-shape-structure.js";
2
2
  import { contractKey, sourceItemKeys, stableKey, stableKeys, } from "./design-resource-handoff-shape-primitives.js";
3
+ import { parseDesignResourceTechnicalFeasibilityInputs } from "./design-resource-implementation-feasibility-shape.js";
3
4
  import { array, literal, object, repositoryFile, string, strings, } from "./long-task-shape-primitives.js";
4
5
  export { parseDesignResourceObservableRuleManifestJson, parseDesignResourceObservableRuleManifestShape, } from "./design-resource-symbolic-manifest-shape.js";
5
6
  export function parseDesignResourceSymbolicHandoffShape(value) {
@@ -14,13 +15,14 @@ export function parseDesignResourceSymbolicHandoffShape(value) {
14
15
  "targets",
15
16
  "coverage",
16
17
  "proposal",
17
- ]);
18
+ ], ["technical_feasibility_inputs"]);
18
19
  return {
19
20
  schema_version: literal(root.schema_version, ["design-resource-handoff-v2"], `${label}.schema_version`),
20
21
  representation: literal(root.representation, ["symbolic_rules_v2"], `${label}.representation`),
21
22
  intent: literal(root.intent, ["implementation_handoff"], `${label}.intent`),
22
23
  scope: parseScope(root.scope, label),
23
24
  provenance: parseProvenance(root.provenance, label),
25
+ technical_feasibility_inputs: parseDesignResourceTechnicalFeasibilityInputs(root.technical_feasibility_inputs ?? [], `${label}.technical_feasibility_inputs`),
24
26
  resources: parseDesignResourceHandoffResources(root.resources),
25
27
  targets: parseTargets(root.targets, label),
26
28
  coverage: parseCoverage(root.coverage, label),
@@ -3,6 +3,7 @@ import type { DesignResourceEnvironmentV1, DesignResourceFactLineageV1, DesignRe
3
3
  import type { DesignResourceHandoffBlockerV1, DesignResourceHandoffResourceV1, DesignResourceHandoffSubjectV1, DesignResourceSourceProfileKind, DesignResourceVerificationMethod } from "./design-resource-handoff-types.js";
4
4
  import type { CompiledSymbolicDenotationV1, SymbolicDenotationAxisDomain, SymbolicDenotationDisposition, SymbolicDenotationPredicate, SymbolicExtensionalPointV1 } from "./symbolic-denotation-types.js";
5
5
  import type { DesignResourceSymbolicNoninterferenceCertificateV2 } from "./design-resource-symbolic-noninterference-types.js";
6
+ import type { DesignResourceImplementationFeasibilityIdentityV1, DesignResourceImplementationFeasibilityV1, DesignResourceTechnicalFeasibilityInputV1 } from "./design-resource-implementation-feasibility-types.js";
6
7
  export type { DesignResourceSymbolicNoninterferenceArtifactV2, DesignResourceSymbolicNoninterferenceCertificateV2, DesignResourceSymbolicNoninterferenceDerivedResultV2, DesignResourceSymbolicNoninterferenceEquivalenceCaseV2, DesignResourceSymbolicNoninterferenceFailureWitnessV1, DesignResourceSymbolicNoninterferenceInputBindingV2, DesignResourceSymbolicNoninterferenceProofMethodV2, DesignResourceSymbolicNoninterferenceProofV2, DesignResourceSymbolicStaticDependencyNodeV2, DesignResourceSymbolicStaticDependencyRootV2, } from "./design-resource-symbolic-noninterference-types.js";
7
8
  export interface DesignResourceSymbolicPopulationV2 {
8
9
  key: string;
@@ -175,6 +176,7 @@ export interface DesignResourceHandoffV2 {
175
176
  model: string;
176
177
  design_system_id: string;
177
178
  };
179
+ technical_feasibility_inputs: DesignResourceTechnicalFeasibilityInputV1[];
178
180
  resources: DesignResourceHandoffResourceV1[];
179
181
  targets: DesignResourceSymbolicHandoffTargetV2[];
180
182
  coverage: DesignResourceSymbolicHandoffCoverageV2[];
@@ -199,6 +201,9 @@ export interface DesignResourceHandoffPreflightV2 extends ParsedDesignResourceHa
199
201
  status: "ready";
200
202
  manifest: DesignResourceObservableRuleManifestV2;
201
203
  resource_hashes: Record<string, string>;
204
+ technical_feasibility_documents: DesignResourceImplementationFeasibilityV1[];
205
+ technical_feasibility_identities: DesignResourceImplementationFeasibilityIdentityV1[];
206
+ limitations: string[];
202
207
  rule_projections: DesignResourceSymbolicRuleProjectionV2[];
203
208
  metrics: {
204
209
  semantic_obligations: number;
@@ -7,6 +7,8 @@ import { validateSymbolicCoverage } from "./design-resource-symbolic-region-vali
7
7
  import { assertSameSet, invalid, requireExactRefs, unique, } from "./design-resource-symbolic-validation-support.js";
8
8
  import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
9
9
  import { sha256Hex } from "./strict-codec.js";
10
+ import { createV2ImplementationFeasibilityTargetModel } from "./design-resource-implementation-feasibility-model.js";
11
+ import { readAndValidateDesignResourceImplementationFeasibility } from "./design-resource-implementation-feasibility-validation.js";
10
12
  export { designResourceSymbolicCertificateKey, designResourceSymbolicCombinedRuleDigest, designResourceSymbolicDependencyEdge, designResourceSymbolicNoninterferenceProofDigest, designResourceSymbolicObligationKey, designResourceSymbolicRuleKey, } from "./design-resource-symbolic-validation-support.js";
11
13
  const V2_MANIFEST_MAX_BYTES = 8_388_608;
12
14
  export async function preflightParsedDesignResourceSymbolicHandoff(repository, parsed) {
@@ -37,12 +39,23 @@ export async function preflightParsedDesignResourceSymbolicHandoff(repository, p
37
39
  invalid("v2_manifest_identity_mismatch", `${manifest.scope_key}:${manifest.target_key}`);
38
40
  const validated = validateDesignResourceSymbolicManifest(manifest, parsed, resources, contents);
39
41
  validateSymbolicCoverage(parsed, manifest);
42
+ const feasibility = await readAndValidateDesignResourceImplementationFeasibility(repository, parsed.handoff_path, handoff.technical_feasibility_inputs, new Map([
43
+ [
44
+ target.key,
45
+ createV2ImplementationFeasibilityTargetModel(target, manifest),
46
+ ],
47
+ ]), new Set(handoff.resources.map((resource) => resource.path)));
40
48
  return {
41
49
  ...parsed,
42
50
  preflight_schema_version: "design-resource-handoff-preflight-v2",
43
51
  status: "ready",
44
52
  manifest,
45
53
  resource_hashes: resourceHashes,
54
+ technical_feasibility_documents: feasibility.map((item) => item.document),
55
+ technical_feasibility_identities: feasibility.map((item) => item.identity),
56
+ limitations: target.source_profile.kind !== "reference" && !feasibility.length
57
+ ? ["technical feasibility not declared"]
58
+ : [],
46
59
  rule_projections: validated.ruleProjections,
47
60
  metrics: validated.metrics,
48
61
  };
@@ -19,11 +19,14 @@ import { captureWorkspaceManifest, repoRelative, } from "./long-task-workspace.j
19
19
  export async function validateContractForActivation(options) {
20
20
  const { contract, repository, workdir, mode } = options;
21
21
  const diagnostics = options.diagnostics ?? [];
22
+ const structureOptions = {
23
+ allowDeferredDesignComponentBindingClosure: true,
24
+ };
22
25
  if (mode === "collect")
23
- for (const error of deliveryContractStructureDiagnostics(contract))
26
+ for (const error of deliveryContractStructureDiagnostics(contract, structureOptions))
24
27
  addDiagnosticError(diagnostics, error);
25
28
  else
26
- validateDeliveryContractStructure(contract);
29
+ validateDeliveryContractStructure(contract, structureOptions);
27
30
  const claims = await attempt(mode, diagnostics, () => compileProductClaimCoverage(contract));
28
31
  if (mode === "fail_fast") {
29
32
  const decisions = contract.source_claims
@@ -45,7 +48,7 @@ export async function validateContractForActivation(options) {
45
48
  : undefined);
46
49
  return items;
47
50
  });
48
- await attempt(mode, diagnostics, () => validateLongTaskDesignResourceHandoffs(contract, repository));
51
+ await attempt(mode, diagnostics, () => validateLongTaskDesignResourceHandoffs(contract, repository, sourceItems ?? []));
49
52
  const risk = await attempt(mode, diagnostics, () => {
50
53
  const decision = classifyLongTaskRisk(contract);
51
54
  validateRiskProof(contract, decision);
@@ -83,11 +86,15 @@ export async function validateContractForActivation(options) {
83
86
  const outcomes = [];
84
87
  for (const outcome of contract.outcomes) {
85
88
  const checks = [];
89
+ const blockedDesignAssertionRefsByCheck = new Map();
86
90
  for (const check of outcome.acceptance.checks) {
87
91
  const executionTarget = contract.task.execution_targets.find((target) => target.key === check.execution_target.target_ref);
88
92
  if (!executionTarget)
89
93
  continue;
90
- const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets, designTargetsForCheck(outcome, check.key), semanticFactClosure?.expectations_by_check.get(check.key) ?? [], scopeDeliveryBindings(outcome.key, outcome.technical.bindings), outcome.product.owner.path_globs, sourceBackedExecutionTargets.get(executionTarget.key) ?? null, observationAuthorityPaths), outcome.key, check.key);
94
+ const blockedDesignAssertionRefs = externallyBlockedDesignAssertionRefs(outcome, check, contract.global.acceptance.external_confirmations);
95
+ blockedDesignAssertionRefsByCheck.set(check.key, blockedDesignAssertionRefs);
96
+ const machineCheck = projectMachineCheck(check, blockedDesignAssertionRefs);
97
+ const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(machineCheck, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets, designTargetsForCheck(outcome, check.key, contract.global.acceptance.external_confirmations), semanticFactClosure?.expectations_by_check.get(check.key) ?? [], scopeDeliveryBindings(outcome.key, outcome.technical.bindings), outcome.product.owner.path_globs, sourceBackedExecutionTargets.get(executionTarget.key) ?? null, observationAuthorityPaths), outcome.key, check.key);
91
98
  if (frozen)
92
99
  checks.push(frozen);
93
100
  }
@@ -96,7 +103,12 @@ export async function validateContractForActivation(options) {
96
103
  internal_id: `OUT.${outcome.key}`,
97
104
  generated_claims: claims?.by_outcome[outcome.key] ?? [],
98
105
  risk_reasons: risk?.reasons_by_outcome[outcome.key] ?? [],
99
- acceptance: { ...outcome.acceptance, checks },
106
+ acceptance: {
107
+ ...outcome.acceptance,
108
+ checks,
109
+ counterfactual_controls: outcome.acceptance.counterfactual_controls.map((control) => projectCounterfactualControl(control, outcome.acceptance.checks.find((check) => check.key === control.check_key), blockedDesignAssertionRefsByCheck.get(control.check_key) ??
110
+ new Set())),
111
+ },
100
112
  });
101
113
  }
102
114
  const allChecks = [
@@ -130,9 +142,11 @@ export async function validateContractForActivation(options) {
130
142
  outcomes,
131
143
  };
132
144
  }
133
- function designTargetsForCheck(outcome, checkKey) {
145
+ function designTargetsForCheck(outcome, checkKey, confirmations) {
134
146
  return (outcome.product.surface_bindings ?? []).flatMap((binding) => binding.design_targets
135
- .filter((target) => target.conformance_check_ref === checkKey)
147
+ .filter((target) => target.conformance_check_ref === checkKey &&
148
+ !confirmations.some((confirmation) => confirmation.blocks_target &&
149
+ confirmation.impact_claims.some((claimRef) => target.claim_refs.some((targetClaimRef) => claimRef === `${outcome.key}.${targetClaimRef}`))))
136
150
  .map((target) => ({
137
151
  ...target,
138
152
  surface_binding_ref: binding.key,
@@ -140,6 +154,62 @@ function designTargetsForCheck(outcome, checkKey) {
140
154
  target_ref: binding.target_ref,
141
155
  })));
142
156
  }
157
+ function externallyBlockedDesignAssertionRefs(outcome, check, confirmations) {
158
+ const refs = new Set();
159
+ const impactedClaims = new Set();
160
+ for (const binding of outcome.product.surface_bindings ?? [])
161
+ for (const target of binding.design_targets) {
162
+ if (target.conformance_check_ref !== check.key)
163
+ continue;
164
+ const blocked = confirmations.some((confirmation) => confirmation.blocks_target &&
165
+ confirmation.impact_claims.some((claimRef) => target.claim_refs.some((targetClaimRef) => claimRef === `${outcome.key}.${targetClaimRef}`)));
166
+ if (!blocked)
167
+ continue;
168
+ for (const confirmation of confirmations)
169
+ if (confirmation.blocks_target &&
170
+ confirmation.impact_claims.some((claimRef) => target.claim_refs.some((targetClaimRef) => claimRef === `${outcome.key}.${targetClaimRef}`)))
171
+ for (const claimRef of confirmation.impact_claims)
172
+ impactedClaims.add(claimRef);
173
+ refs.add(target.conformance_assertion_ref);
174
+ for (const method of target.verification_method_bindings)
175
+ refs.add(method.assertion_ref);
176
+ for (const method of target.symbolic_method_bindings ?? [])
177
+ refs.add(method.assertion_ref);
178
+ if (target.symbolic_certificate_binding)
179
+ refs.add(target.symbolic_certificate_binding.assertion_ref);
180
+ }
181
+ for (const assertion of [
182
+ ...check.positive_assertions,
183
+ ...check.negative_assertions,
184
+ ])
185
+ if (assertion.evidence_capabilities.includes("state_delta") &&
186
+ assertion.claims.length > 0 &&
187
+ assertion.claims.every((claimRef) => impactedClaims.has(`${outcome.key}.${claimRef}`)))
188
+ refs.add(assertion.key);
189
+ return refs;
190
+ }
191
+ function projectMachineCheck(check, externallyBlockedAssertionRefs) {
192
+ if (!externallyBlockedAssertionRefs.size)
193
+ return check;
194
+ return {
195
+ ...check,
196
+ positive_assertions: check.positive_assertions.filter((assertion) => !externallyBlockedAssertionRefs.has(assertion.key)),
197
+ negative_assertions: check.negative_assertions.filter((assertion) => !externallyBlockedAssertionRefs.has(assertion.key)),
198
+ };
199
+ }
200
+ function projectCounterfactualControl(control, check, externallyBlockedAssertionRefs) {
201
+ if (!check || !externallyBlockedAssertionRefs.size)
202
+ return control;
203
+ const externallyBlockedClaims = new Set([...check.positive_assertions, ...check.negative_assertions]
204
+ .filter((assertion) => externallyBlockedAssertionRefs.has(assertion.key))
205
+ .flatMap((assertion) => assertion.claims));
206
+ return {
207
+ ...control,
208
+ claims: control.claims.filter((claimRef) => !externallyBlockedClaims.has(claimRef)),
209
+ expected_assertion_failures: control.expected_assertion_failures.filter((assertionRef) => !externallyBlockedAssertionRefs.has(assertionRef)),
210
+ preserved_assertions: control.preserved_assertions.filter((assertionRef) => !externallyBlockedAssertionRefs.has(assertionRef)),
211
+ };
212
+ }
143
213
  async function attempt(mode, diagnostics, action, outcomeKey, checkKey) {
144
214
  try {
145
215
  return await action();
@@ -15,7 +15,9 @@ export function buildAuthorityRevisionDecisionBrief(summary, changeClass, approv
15
15
  addCategory(summary.source_or_claims_changed, "Source/Claims", detail("Source or Claim authority changed", summary.source_claim_changes));
16
16
  addCategory(summary.context_authority_changed, "Context authority", "Controlling Context authority changed.");
17
17
  addCategory(summary.acceptance_or_proof_weakened, "acceptance/proof", detail("Acceptance or proof was reduced", summary.proof_reductions));
18
- addCategory(summary.verifier_or_runner_changed, "verifier/runner", "Verifier or runner authority changed.");
18
+ addCategory(summary.verifier_or_runner_changed, "verifier/runner", summary.verifier_content_changed
19
+ ? detail("Verifier content changed; prior evidence is invalid and semantic preservation is not independently established", summary.verifier_files_changed)
20
+ : "Verifier or runner authority changed.");
19
21
  addCategory(summary.write_scope_expanded, "write scope", detail("Owner or allowed write scope expanded", uniqueSorted([
20
22
  ...summary.expanded_owner_paths,
21
23
  ...summary.expanded_expected_change_paths,
@@ -59,7 +59,6 @@ const PROOF_REDUCTION_REASONS = new Set([
59
59
  "rollback_or_recovery_weakened",
60
60
  "counterfactual_removed",
61
61
  "population_weakened",
62
- "verifier_content_changed",
63
62
  "acceptance_not_monotonic",
64
63
  ]);
65
64
  export function classifyAuthorityRevision(diff) {
@@ -136,6 +135,8 @@ export function summarizeAuthorityRevision(diff, outcomeKeys) {
136
135
  verifier_or_runner_changed: diff.verifier_content_changed ||
137
136
  diff.verifier_runtime_locator_changed ||
138
137
  diff.runner_definitions_changed.length > 0,
138
+ verifier_content_changed: diff.verifier_content_changed,
139
+ verifier_files_changed: uniqueSorted(diff.verifier_files_changed),
139
140
  write_scope_expanded: diff.owner_or_path_boundary_changed,
140
141
  risk_changed: diff.risk_changed,
141
142
  external_confirmations_changed: diff.external_confirmations_changed,
@@ -184,13 +185,16 @@ export function projectAuthorityRevisionDecision(value) {
184
185
  ? {
185
186
  ...computedSummary,
186
187
  ...storedSummary,
188
+ acceptance_or_proof_weakened: computedSummary.acceptance_or_proof_weakened,
189
+ verifier_content_changed: computedSummary.verifier_content_changed,
190
+ verifier_files_changed: computedSummary.verifier_files_changed,
187
191
  semantic_fields_changed: storedSummary.semantic_fields_changed ??
188
192
  computedSummary.semantic_fields_changed,
189
193
  source_claim_changes: storedSummary.source_claim_changes ??
190
194
  computedSummary.source_claim_changes,
191
195
  product_claim_changes: storedSummary.product_claim_changes ??
192
196
  computedSummary.product_claim_changes,
193
- proof_reductions: storedSummary.proof_reductions ?? computedSummary.proof_reductions,
197
+ proof_reductions: computedSummary.proof_reductions,
194
198
  external_confirmation_changes: storedSummary.external_confirmation_changes ??
195
199
  computedSummary.external_confirmation_changes,
196
200
  user_decision_reasons: storedSummary.user_decision_reasons ??
@@ -7,6 +7,8 @@ export interface AuthorityRevisionApprovalSummaryV2 {
7
7
  context_authority_changed: boolean;
8
8
  acceptance_or_proof_weakened: boolean;
9
9
  verifier_or_runner_changed: boolean;
10
+ verifier_content_changed: boolean;
11
+ verifier_files_changed: string[];
10
12
  write_scope_expanded: boolean;
11
13
  risk_changed: boolean;
12
14
  external_confirmations_changed: boolean;