project-tiny-context-harness 0.8.12 → 0.8.16

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 (174) hide show
  1. package/README.md +62 -28
  2. package/assets/README.md +98 -45
  3. package/assets/README.zh-CN.md +68 -32
  4. package/assets/agents/AGENTS_CORE.md +10 -6
  5. package/assets/agents/long-task-implementation.toml +1 -1
  6. package/assets/skills/context_development_engineer/SKILL.md +9 -1
  7. package/assets/skills/design-resource-authoring/SKILL.md +7 -5
  8. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +2 -2
  9. package/assets/skills/design-resource-authoring/references/open-design-provider.md +22 -2
  10. package/assets/skills/design-resource-authoring/references/recovery-and-writeback.md +199 -0
  11. package/assets/skills/design-resource-authoring/references/resource-selection.md +2 -2
  12. package/assets/skills/long-task-workflow/SKILL.md +14 -12
  13. package/assets/skills/long-task-workflow/agents/openai.yaml +1 -1
  14. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +1 -1
  15. package/assets/skills/long-task-workflow/references/contract-authoring.md +27 -22
  16. package/assets/skills/long-task-workflow/references/evidence-design.md +49 -32
  17. package/assets/skills/long-task-workflow/references/source-authoring.md +2 -2
  18. package/dist/commands/design-resource-recovery.d.ts +1 -0
  19. package/dist/commands/design-resource-recovery.js +152 -0
  20. package/dist/commands/design-resource.js +20 -1
  21. package/dist/commands/index.js +1 -1
  22. package/dist/commands/long-task-revision.js +4 -4
  23. package/dist/lib/design-resource-reconciliation-codec.d.ts +2 -0
  24. package/dist/lib/design-resource-reconciliation-codec.js +174 -0
  25. package/dist/lib/design-resource-reconciliation-types.d.ts +62 -0
  26. package/dist/lib/design-resource-reconciliation-types.js +1 -0
  27. package/dist/lib/design-resource-reconciliation.d.ts +3 -0
  28. package/dist/lib/design-resource-reconciliation.js +224 -0
  29. package/dist/lib/design-resource-recovery-authority-policy.d.ts +8 -0
  30. package/dist/lib/design-resource-recovery-authority-policy.js +123 -0
  31. package/dist/lib/design-resource-recovery-catalog-resources.d.ts +6 -0
  32. package/dist/lib/design-resource-recovery-catalog-resources.js +121 -0
  33. package/dist/lib/design-resource-recovery-catalog-shape.d.ts +3 -0
  34. package/dist/lib/design-resource-recovery-catalog-shape.js +104 -0
  35. package/dist/lib/design-resource-recovery-catalog.d.ts +9 -0
  36. package/dist/lib/design-resource-recovery-catalog.js +103 -0
  37. package/dist/lib/design-resource-recovery-cleanup.d.ts +2 -0
  38. package/dist/lib/design-resource-recovery-cleanup.js +11 -0
  39. package/dist/lib/design-resource-recovery-codec-primitives.d.ts +19 -0
  40. package/dist/lib/design-resource-recovery-codec-primitives.js +92 -0
  41. package/dist/lib/design-resource-recovery-codec.d.ts +4 -0
  42. package/dist/lib/design-resource-recovery-codec.js +93 -0
  43. package/dist/lib/design-resource-recovery-current.d.ts +9 -0
  44. package/dist/lib/design-resource-recovery-current.js +41 -0
  45. package/dist/lib/design-resource-recovery-delta-policy.d.ts +5 -0
  46. package/dist/lib/design-resource-recovery-delta-policy.js +108 -0
  47. package/dist/lib/design-resource-recovery-files.d.ts +37 -0
  48. package/dist/lib/design-resource-recovery-files.js +204 -0
  49. package/dist/lib/design-resource-recovery-final-disposition-shape.d.ts +2 -0
  50. package/dist/lib/design-resource-recovery-final-disposition-shape.js +47 -0
  51. package/dist/lib/design-resource-recovery-patch-types.d.ts +54 -0
  52. package/dist/lib/design-resource-recovery-patch-types.js +1 -0
  53. package/dist/lib/design-resource-recovery-replay.d.ts +7 -0
  54. package/dist/lib/design-resource-recovery-replay.js +112 -0
  55. package/dist/lib/design-resource-recovery-repository-bindings.d.ts +9 -0
  56. package/dist/lib/design-resource-recovery-repository-bindings.js +49 -0
  57. package/dist/lib/design-resource-recovery-schema.d.ts +5 -0
  58. package/dist/lib/design-resource-recovery-schema.js +5 -0
  59. package/dist/lib/design-resource-recovery-shape.d.ts +10 -0
  60. package/dist/lib/design-resource-recovery-shape.js +184 -0
  61. package/dist/lib/design-resource-recovery-source-authority.d.ts +5 -0
  62. package/dist/lib/design-resource-recovery-source-authority.js +219 -0
  63. package/dist/lib/design-resource-recovery-text.d.ts +17 -0
  64. package/dist/lib/design-resource-recovery-text.js +186 -0
  65. package/dist/lib/design-resource-recovery-types.d.ts +197 -0
  66. package/dist/lib/design-resource-recovery-types.js +1 -0
  67. package/dist/lib/design-resource-recovery-writeback-policy.d.ts +5 -0
  68. package/dist/lib/design-resource-recovery-writeback-policy.js +326 -0
  69. package/dist/lib/design-resource-recovery-writeback-shape.d.ts +6 -0
  70. package/dist/lib/design-resource-recovery-writeback-shape.js +155 -0
  71. package/dist/lib/design-resource-recovery.d.ts +44 -0
  72. package/dist/lib/design-resource-recovery.js +216 -0
  73. package/dist/lib/long-task-acceptance-shape.js +8 -2
  74. package/dist/lib/long-task-activation-validation.js +13 -3
  75. package/dist/lib/long-task-admitted-observation-records.d.ts +25 -0
  76. package/dist/lib/long-task-admitted-observation-records.js +40 -0
  77. package/dist/lib/long-task-admitted-observation.d.ts +93 -0
  78. package/dist/lib/long-task-admitted-observation.js +201 -0
  79. package/dist/lib/long-task-artifacts.d.ts +1 -0
  80. package/dist/lib/long-task-artifacts.js +1 -0
  81. package/dist/lib/long-task-authority-material-diff.js +1 -0
  82. package/dist/lib/long-task-authority-policy.d.ts +2 -0
  83. package/dist/lib/long-task-authority-policy.js +2 -0
  84. package/dist/lib/long-task-authority-revision-brief.js +3 -1
  85. package/dist/lib/long-task-authority-revision-details.js +3 -1
  86. package/dist/lib/long-task-authority-revision-summary.js +6 -2
  87. package/dist/lib/long-task-authority-revision-types.d.ts +2 -0
  88. package/dist/lib/long-task-authority.js +2 -1
  89. package/dist/lib/long-task-check-execution-policy.js +5 -0
  90. package/dist/lib/long-task-check-runner.d.ts +2 -2
  91. package/dist/lib/long-task-check-runner.js +440 -23
  92. package/dist/lib/long-task-claims.d.ts +18 -0
  93. package/dist/lib/long-task-claims.js +35 -0
  94. package/dist/lib/long-task-compact-structure-targets.js +1 -0
  95. package/dist/lib/long-task-conformance-policy.js +3 -1
  96. package/dist/lib/long-task-counterfactual-claim-policy.d.ts +3 -4
  97. package/dist/lib/long-task-counterfactual-claim-policy.js +11 -3
  98. package/dist/lib/long-task-counterfactual-sandbox.js +1 -0
  99. package/dist/lib/long-task-counterfactual-types.d.ts +2 -0
  100. package/dist/lib/long-task-delivery-compiler.js +2 -0
  101. package/dist/lib/long-task-design-resource-method-binding.js +8 -2
  102. package/dist/lib/long-task-evidence-capability-policy.d.ts +3 -2
  103. package/dist/lib/long-task-evidence-capability-policy.js +114 -8
  104. package/dist/lib/long-task-evidence-capability-runtime.d.ts +5 -2
  105. package/dist/lib/long-task-evidence-capability-runtime.js +149 -5
  106. package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +9 -0
  107. package/dist/lib/long-task-evidence-sensitivity-policy.js +31 -1
  108. package/dist/lib/long-task-evidence-v2.d.ts +4 -4
  109. package/dist/lib/long-task-evidence-v2.js +321 -43
  110. package/dist/lib/long-task-exact-comparison.d.ts +16 -0
  111. package/dist/lib/long-task-exact-comparison.js +28 -0
  112. package/dist/lib/long-task-execution-observation.d.ts +24 -0
  113. package/dist/lib/long-task-execution-observation.js +332 -0
  114. package/dist/lib/long-task-explain-acceptance-link.d.ts +4 -0
  115. package/dist/lib/long-task-explain-acceptance-link.js +4 -0
  116. package/dist/lib/long-task-explain-claim-links.d.ts +2 -0
  117. package/dist/lib/long-task-explain-claim-links.js +2 -0
  118. package/dist/lib/long-task-explain-source-links.d.ts +6 -0
  119. package/dist/lib/long-task-final-v2.js +7 -4
  120. package/dist/lib/long-task-git.d.ts +26 -0
  121. package/dist/lib/long-task-git.js +130 -0
  122. package/dist/lib/long-task-json-pointer-observation.d.ts +59 -0
  123. package/dist/lib/long-task-json-pointer-observation.js +184 -0
  124. package/dist/lib/long-task-observation-artifact.d.ts +8 -0
  125. package/dist/lib/long-task-observation-artifact.js +58 -0
  126. package/dist/lib/long-task-observation-authority.d.ts +17 -0
  127. package/dist/lib/long-task-observation-authority.js +348 -0
  128. package/dist/lib/long-task-paths.js +2 -2
  129. package/dist/lib/long-task-process-observation.d.ts +6 -0
  130. package/dist/lib/long-task-process-observation.js +117 -0
  131. package/dist/lib/long-task-process-runtime-closure.d.ts +13 -0
  132. package/dist/lib/long-task-process-runtime-closure.js +207 -0
  133. package/dist/lib/long-task-progress.js +2 -0
  134. package/dist/lib/long-task-protected-files.d.ts +1 -1
  135. package/dist/lib/long-task-protected-files.js +1 -30
  136. package/dist/lib/long-task-risk.js +8 -3
  137. package/dist/lib/long-task-root-shape.js +10 -1
  138. package/dist/lib/long-task-runner-environment.d.ts +1 -1
  139. package/dist/lib/long-task-runner-environment.js +4 -4
  140. package/dist/lib/long-task-runner-freeze.d.ts +4 -2
  141. package/dist/lib/long-task-runner-freeze.js +128 -28
  142. package/dist/lib/long-task-runtime-types.d.ts +111 -0
  143. package/dist/lib/long-task-scoped-binding.d.ts +13 -0
  144. package/dist/lib/long-task-scoped-binding.js +11 -0
  145. package/dist/lib/long-task-semantic-contract-types.d.ts +1 -0
  146. package/dist/lib/long-task-semantic-fact-contract-closure.js +3 -3
  147. package/dist/lib/long-task-semantic-fact-evidence.d.ts +3 -3
  148. package/dist/lib/long-task-semantic-fact-evidence.js +75 -58
  149. package/dist/lib/long-task-source-claim-validation.js +4 -1
  150. package/dist/lib/long-task-source-target-continuity.d.ts +2 -2
  151. package/dist/lib/long-task-source-target-continuity.js +35 -2
  152. package/dist/lib/long-task-source-target-index.d.ts +3 -0
  153. package/dist/lib/long-task-source-target-index.js +19 -0
  154. package/dist/lib/long-task-stage-policy.js +10 -4
  155. package/dist/lib/long-task-static-observation-freeze.d.ts +83 -0
  156. package/dist/lib/long-task-static-observation-freeze.js +428 -0
  157. package/dist/lib/long-task-status-projection.js +5 -1
  158. package/dist/lib/long-task-target-policy.d.ts +1 -1
  159. package/dist/lib/long-task-target-policy.js +3 -0
  160. package/dist/lib/long-task-verifier-authority.js +2 -0
  161. package/dist/lib/long-task-verifier-dependency-closure.js +7 -3
  162. package/dist/lib/long-task-verifier-v2.js +70 -9
  163. package/dist/lib/long-task-workspace-manifest.d.ts +8 -0
  164. package/dist/lib/long-task-workspace-manifest.js +173 -0
  165. package/dist/lib/long-task-workspace-snapshot.d.ts +8 -0
  166. package/dist/lib/long-task-workspace-snapshot.js +176 -0
  167. package/dist/lib/long-task-workspace.d.ts +5 -26
  168. package/dist/lib/long-task-workspace.js +4 -444
  169. package/dist/lib/repository-path-safety.d.ts +14 -0
  170. package/dist/lib/repository-path-safety.js +126 -0
  171. package/dist/long-task-hook.js +12 -3
  172. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +53 -8
  173. package/migrations/README.md +77 -0
  174. package/package.json +1 -1
@@ -0,0 +1,332 @@
1
+ import { chmod, copyFile, mkdir, mkdtemp, rm } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { createJsonPointerExactBudget } from "./long-task-json-pointer-observation.js";
5
+ import { matchesRepoPattern } from "./long-task-paths.js";
6
+ import { StaticObservationFreezeError, createObservationInputFreezeBudget, freezeObservationInputFile, freezeStaticObservationCarrier, } from "./long-task-static-observation-freeze.js";
7
+ const PROCESS_INPUT_FREEZE_LIMITS = Object.freeze({
8
+ max_artifacts: 4_096,
9
+ max_file_bytes: 268_435_456,
10
+ max_total_artifact_bytes: 536_870_912,
11
+ });
12
+ function createProcessInputFreezeBudget() {
13
+ return createObservationInputFreezeBudget({
14
+ max_artifacts: PROCESS_INPUT_FREEZE_LIMITS.max_artifacts,
15
+ max_total_artifact_bytes: PROCESS_INPUT_FREEZE_LIMITS.max_total_artifact_bytes,
16
+ });
17
+ }
18
+ /**
19
+ * Freezes every selected Raw Execution group's observation inputs before the
20
+ * caller is allowed to start any runner. Keeping this as one owner prevents a
21
+ * prior execution from priming a later group's supposedly pre-run carrier.
22
+ */
23
+ export async function prepareExecutionObservationUniverse(input) {
24
+ const prepared = [];
25
+ const processInputBudget = createProcessInputFreezeBudget();
26
+ for (const checks of input.groups)
27
+ prepared.push(await prepareExecutionObservationGroupWithBudget({
28
+ checks,
29
+ snapshot_root: input.snapshot_root,
30
+ workspace_manifest: input.workspace_manifest,
31
+ protected_authority_paths: input.protected_authority_paths,
32
+ process_input_budget: processInputBudget,
33
+ }));
34
+ return prepared;
35
+ }
36
+ export async function prepareExecutionObservationGroup(input) {
37
+ return prepareExecutionObservationGroupWithBudget({
38
+ ...input,
39
+ process_input_budget: createProcessInputFreezeBudget(),
40
+ });
41
+ }
42
+ async function prepareExecutionObservationGroupWithBudget(input) {
43
+ if (!input.checks.length)
44
+ throw new Error("execution_observation_check_group_required");
45
+ const rawIdentity = input.checks[0].raw_execution_identity;
46
+ if (input.checks.some((check) => check.raw_execution_identity !== rawIdentity))
47
+ throw new Error("execution_observation_raw_identity_mismatch");
48
+ const states = authorityCarrierStates(input.checks, input.workspace_manifest);
49
+ const groups = observationCarrierGroups(states);
50
+ const exactBudget = createJsonPointerExactBudget();
51
+ const processInputBudget = input.process_input_budget;
52
+ const processExecution = states.some((state) => state.authority.authority === "package_process_json_exact");
53
+ const executionRoot = processExecution
54
+ ? await mkdtemp(path.join(os.tmpdir(), "ty-context-process-snapshot-"))
55
+ : input.snapshot_root;
56
+ if (processExecution)
57
+ await mkdir(path.resolve(executionRoot, input.checks[0].runner.resolved_cwd), { recursive: true });
58
+ for (const group of groups) {
59
+ if ((input.protected_authority_paths ?? []).some((pattern) => matchesRepoPattern(group.artifact_path, pattern))) {
60
+ for (const state of group.authority_states)
61
+ recordAuthorityFailure(state, "observation_expected_authority_forbidden");
62
+ continue;
63
+ }
64
+ try {
65
+ const includesStaticAuthority = group.authority_states.some((state) => state.authority.authority === "package_static_json_exact");
66
+ const includesProcessAuthority = group.authority_states.some((state) => state.authority.authority === "package_process_json_exact");
67
+ let sourceIdentity = null;
68
+ if (processExecution) {
69
+ const sourceFrozen = await freezeObservationInputFile({
70
+ snapshot_root: input.snapshot_root,
71
+ workspace_manifest: input.workspace_manifest,
72
+ artifact_path: group.artifact_path,
73
+ max_file_bytes: PROCESS_INPUT_FREEZE_LIMITS.max_file_bytes,
74
+ budget: processInputBudget,
75
+ });
76
+ try {
77
+ const target = path.resolve(executionRoot, ...group.artifact_path.split("/"));
78
+ await mkdir(path.dirname(target), { recursive: true });
79
+ await copyFile(path.resolve(input.snapshot_root, ...group.artifact_path.split("/")), target);
80
+ const verifiedSource = await sourceFrozen.verifyPostRun();
81
+ sourceIdentity = verifiedSource.pre_run_identity;
82
+ await chmod(target, sourceIdentity.mode & 0o777);
83
+ }
84
+ finally {
85
+ sourceFrozen.dispose();
86
+ }
87
+ }
88
+ group.frozen = includesStaticAuthority
89
+ ? await freezeStaticObservationCarrier({
90
+ snapshot_root: executionRoot,
91
+ workspace_manifest: input.workspace_manifest,
92
+ artifact_path: group.artifact_path,
93
+ budget: exactBudget,
94
+ input_freeze_budget: includesProcessAuthority
95
+ ? processInputBudget
96
+ : undefined,
97
+ })
98
+ : await freezeObservationInputFile({
99
+ snapshot_root: executionRoot,
100
+ workspace_manifest: input.workspace_manifest,
101
+ artifact_path: group.artifact_path,
102
+ max_file_bytes: PROCESS_INPUT_FREEZE_LIMITS.max_file_bytes,
103
+ budget: processInputBudget,
104
+ });
105
+ if (sourceIdentity &&
106
+ (group.frozen.pre_run_identity.content_sha256 !==
107
+ sourceIdentity.content_sha256 ||
108
+ group.frozen.pre_run_identity.size !== sourceIdentity.size))
109
+ throw new Error("process_observation_input_snapshot_copy_mismatch");
110
+ }
111
+ catch (error) {
112
+ const reason = observationFailureReason(error);
113
+ for (const state of group.authority_states)
114
+ recordAuthorityFailure(state, reason);
115
+ }
116
+ }
117
+ const processAuthorities = states
118
+ .filter((state) => state.authority.authority === "package_process_json_exact")
119
+ .map((state) => state.authority);
120
+ const processRuntimeClosureIdentities = [
121
+ ...new Set(input.checks
122
+ .filter((check) => (check.observation_authorities ?? []).some((authority) => authority.authority === "package_process_json_exact"))
123
+ .map((check) => check.process_runtime_closure?.closure_identity ?? null)),
124
+ ];
125
+ if (processExecution &&
126
+ (processRuntimeClosureIdentities.length !== 1 ||
127
+ processRuntimeClosureIdentities[0] === null))
128
+ throw new Error("process_runtime_closure_identity_mismatch");
129
+ let disposed = false;
130
+ const dispose = async () => {
131
+ if (disposed)
132
+ return;
133
+ disposed = true;
134
+ for (const group of groups)
135
+ group.frozen?.dispose();
136
+ if (processExecution)
137
+ await rm(executionRoot, { recursive: true, force: true });
138
+ };
139
+ return {
140
+ execution_root: executionRoot,
141
+ runner_context: {
142
+ snapshot_sha256: input.workspace_manifest.snapshot_sha256,
143
+ observation_authorities: processAuthorities,
144
+ ...(processExecution
145
+ ? {
146
+ process_runtime_closure_identity: processRuntimeClosureIdentities[0],
147
+ }
148
+ : {}),
149
+ },
150
+ finalize: async (raw) => {
151
+ try {
152
+ const verified = new Map();
153
+ for (const group of groups) {
154
+ if (!group.frozen)
155
+ continue;
156
+ try {
157
+ verified.set(group.artifact_path, await group.frozen.verifyPostRun());
158
+ }
159
+ catch (error) {
160
+ const reason = observationFailureReason(error);
161
+ for (const state of group.authority_states)
162
+ recordAuthorityFailure(state, reason);
163
+ }
164
+ }
165
+ return {
166
+ ...raw,
167
+ package_observations: finalizePackageObservations(states, verified, raw.package_observations ?? [], exactBudget),
168
+ };
169
+ }
170
+ finally {
171
+ await dispose();
172
+ }
173
+ },
174
+ dispose,
175
+ };
176
+ }
177
+ function authorityCarrierStates(checks, manifest) {
178
+ const states = [];
179
+ for (const check of checks)
180
+ for (const authority of check.observation_authorities ?? []) {
181
+ if (authority.authority !== "package_static_json_exact" &&
182
+ authority.authority !== "package_process_json_exact")
183
+ continue;
184
+ const state = {
185
+ check,
186
+ authority: authority,
187
+ artifact_paths: [],
188
+ reason: null,
189
+ };
190
+ const carrierPatterns = authority.carrier_refs.flatMap((carrier) => carrier.carrier_paths);
191
+ addPatternClosure(state, manifest, carrierPatterns);
192
+ if (authority.authority === "package_process_json_exact") {
193
+ const closure = check.process_runtime_closure;
194
+ if (!closure)
195
+ recordAuthorityFailure(state, "process_runtime_closure_identity_mismatch");
196
+ else
197
+ state.artifact_paths.push(...closure.allowed_runtime_files);
198
+ }
199
+ state.artifact_paths = [...new Set(state.artifact_paths)].sort();
200
+ if (authority.authority === "package_static_json_exact" &&
201
+ state.artifact_paths.length !== 1)
202
+ recordAuthorityFailure(state, "static_observation_manifest_invalid");
203
+ states.push(state);
204
+ }
205
+ return states;
206
+ }
207
+ function addPatternClosure(state, manifest, patterns) {
208
+ for (const pattern of new Set(patterns)) {
209
+ let matches;
210
+ try {
211
+ matches = manifest.files
212
+ .filter((file) => matchesRepoPattern(file.path, pattern))
213
+ .map((file) => file.path);
214
+ }
215
+ catch {
216
+ recordAuthorityFailure(state, "static_observation_manifest_invalid");
217
+ continue;
218
+ }
219
+ if (!matches.length) {
220
+ recordAuthorityFailure(state, "static_observation_not_in_pre_run_snapshot");
221
+ continue;
222
+ }
223
+ state.artifact_paths.push(...matches);
224
+ }
225
+ }
226
+ function observationCarrierGroups(states) {
227
+ const groups = new Map();
228
+ for (const state of states)
229
+ for (const artifactPath of state.artifact_paths) {
230
+ const existing = groups.get(artifactPath);
231
+ if (existing)
232
+ existing.authority_states.push(state);
233
+ else
234
+ groups.set(artifactPath, {
235
+ artifact_path: artifactPath,
236
+ authority_states: [state],
237
+ frozen: null,
238
+ });
239
+ }
240
+ return [...groups.values()].sort((left, right) => left.artifact_path.localeCompare(right.artifact_path));
241
+ }
242
+ function finalizePackageObservations(states, verified, submitted, budget) {
243
+ const processStates = states.filter((state) => state.authority.authority === "package_process_json_exact");
244
+ const observations = submitted.filter((candidate) => {
245
+ const matching = processStates.filter((state) => packageObservationMatchesAuthority(candidate, state.authority));
246
+ return !matching.some((state) => state.reason !== null);
247
+ });
248
+ for (const state of processStates)
249
+ if (state.reason)
250
+ observations.push(failedObservation(state.authority, state.reason));
251
+ for (const state of states.filter((candidate) => candidate.authority.authority === "package_static_json_exact")) {
252
+ if (state.reason) {
253
+ observations.push(failedObservation(state.authority, state.reason));
254
+ continue;
255
+ }
256
+ const carrier = verified.get(state.artifact_paths[0]);
257
+ if (!carrier || !isVerifiedStaticObservationCarrier(carrier)) {
258
+ observations.push(failedObservation(state.authority, "static_observation_not_in_pre_run_snapshot"));
259
+ continue;
260
+ }
261
+ try {
262
+ const extracted = carrier.extractJsonPointerExactValue({
263
+ locator: {
264
+ kind: "json_pointer",
265
+ value: state.authority.locator_policy.value,
266
+ },
267
+ sensitivity: "plain",
268
+ budget,
269
+ });
270
+ observations.push({
271
+ authority: "package_static_json_exact",
272
+ observation_identity: state.authority.observation_identity,
273
+ assertion_ref: state.authority.assertion_ref,
274
+ obligation_ref: state.authority.obligation_ref,
275
+ method: state.authority.method,
276
+ raw_value: extracted.raw_value,
277
+ observation: extracted.observation,
278
+ reason: null,
279
+ });
280
+ }
281
+ catch (error) {
282
+ observations.push(failedObservation(state.authority, observationFailureReason(error)));
283
+ }
284
+ }
285
+ return observations;
286
+ }
287
+ function isVerifiedStaticObservationCarrier(value) {
288
+ return "extractJsonPointerExactValue" in value;
289
+ }
290
+ function packageObservationMatchesAuthority(observation, authority) {
291
+ return (observation.authority === authority.authority &&
292
+ observation.observation_identity === authority.observation_identity &&
293
+ observation.assertion_ref === authority.assertion_ref &&
294
+ observation.obligation_ref === authority.obligation_ref &&
295
+ observation.method === authority.method);
296
+ }
297
+ function failedObservation(authority, reason) {
298
+ return {
299
+ authority: authority.authority,
300
+ observation_identity: authority.observation_identity,
301
+ assertion_ref: authority.assertion_ref,
302
+ obligation_ref: authority.obligation_ref,
303
+ method: authority.method,
304
+ raw_value: undefined,
305
+ observation: null,
306
+ reason,
307
+ };
308
+ }
309
+ function recordAuthorityFailure(state, reason) {
310
+ if (state.reason)
311
+ return;
312
+ state.reason =
313
+ state.authority.authority === "package_process_json_exact"
314
+ ? processInputFailureReason(reason)
315
+ : reason;
316
+ }
317
+ function processInputFailureReason(reason) {
318
+ if (reason === "observation_expected_authority_forbidden")
319
+ return reason;
320
+ if (reason === "process_runtime_closure_identity_mismatch")
321
+ return reason;
322
+ if (reason.startsWith("process_observation_input_"))
323
+ return reason;
324
+ if (reason.startsWith("static_observation_"))
325
+ return `process_observation_input_${reason.slice("static_observation_".length)}`;
326
+ return "process_observation_input_freeze_invalid";
327
+ }
328
+ function observationFailureReason(error) {
329
+ if (error instanceof StaticObservationFreezeError)
330
+ return error.code;
331
+ return error instanceof Error ? error.message : String(error);
332
+ }
@@ -21,12 +21,16 @@ export declare function explainAcceptanceLinks(contract: DeliveryContractV2, cov
21
21
  binding_ref: string;
22
22
  owning_outcome_key: string;
23
23
  expected_assertion_failures: string[];
24
+ preserved_assertions: string[];
25
+ allowed_fanout_assertions: string[];
24
26
  }[] | {
25
27
  key: string;
26
28
  claims: string[];
27
29
  binding_key: string;
28
30
  owning_outcome_key: string | null;
29
31
  expected_assertion_failures: string[];
32
+ preserved_assertions: string[];
33
+ allowed_fanout_assertions: string[];
30
34
  }[];
31
35
  } | {
32
36
  type: string;
@@ -81,6 +81,8 @@ function acceptanceCounterfactuals(contract, scope, outcomeKey, checkKey, assert
81
81
  binding_ref: control.binding_ref,
82
82
  owning_outcome_key: control.binding_ref.split(".")[0],
83
83
  expected_assertion_failures: control.expected_assertion_failures,
84
+ preserved_assertions: control.preserved_assertions,
85
+ allowed_fanout_assertions: control.allowed_fanout_assertions,
84
86
  }));
85
87
  const outcome = contract.outcomes.find((item) => item.key === outcomeKey);
86
88
  return (outcome?.acceptance.counterfactual_controls ?? [])
@@ -92,5 +94,7 @@ function acceptanceCounterfactuals(contract, scope, outcomeKey, checkKey, assert
92
94
  binding_key: control.binding_key,
93
95
  owning_outcome_key: outcomeKey,
94
96
  expected_assertion_failures: control.expected_assertion_failures,
97
+ preserved_assertions: control.preserved_assertions,
98
+ allowed_fanout_assertions: control.allowed_fanout_assertions,
95
99
  }));
96
100
  }
@@ -39,6 +39,8 @@ export declare function explainGlobalClaimLinks(contract: DeliveryContractV2, co
39
39
  owner_paths: string[];
40
40
  carrier_paths: string[];
41
41
  expected_assertion_failures: string[];
42
+ preserved_assertions: string[];
43
+ allowed_fanout_assertions: string[];
42
44
  mutation: import("./long-task-counterfactual-types.js").CounterfactualMutationV2;
43
45
  }[];
44
46
  }[];
@@ -58,6 +58,8 @@ export function explainGlobalClaimLinks(contract, coverage, disposition) {
58
58
  owner_paths: outcome?.product.owner.path_globs ?? [],
59
59
  carrier_paths: binding?.carrier_paths ?? [],
60
60
  expected_assertion_failures: control.expected_assertion_failures,
61
+ preserved_assertions: control.preserved_assertions,
62
+ allowed_fanout_assertions: control.allowed_fanout_assertions,
61
63
  mutation: control.mutation,
62
64
  };
63
65
  }),
@@ -21,12 +21,16 @@ export declare function explainSourceLinks(contract: DeliveryContractV2, coverag
21
21
  binding_ref: string;
22
22
  owning_outcome_key: string;
23
23
  expected_assertion_failures: string[];
24
+ preserved_assertions: string[];
25
+ allowed_fanout_assertions: string[];
24
26
  }[] | {
25
27
  key: string;
26
28
  claims: string[];
27
29
  binding_key: string;
28
30
  owning_outcome_key: string | null;
29
31
  expected_assertion_failures: string[];
32
+ preserved_assertions: string[];
33
+ allowed_fanout_assertions: string[];
30
34
  }[];
31
35
  canonical_target: import("./long-task-source-target-index.js").CanonicalSourceTarget | null;
32
36
  } | {
@@ -75,6 +79,8 @@ export declare function explainSourceLinks(contract: DeliveryContractV2, coverag
75
79
  owner_paths: string[];
76
80
  carrier_paths: string[];
77
81
  expected_assertion_failures: string[];
82
+ preserved_assertions: string[];
83
+ allowed_fanout_assertions: string[];
78
84
  mutation: import("./long-task-counterfactual-types.js").CounterfactualMutationV2;
79
85
  }[];
80
86
  canonical_target: import("./long-task-source-target-index.js").CanonicalSourceTarget | null;
@@ -1,4 +1,5 @@
1
1
  import { compileDeliveryContract } from "./long-task-delivery-compiler.js";
2
+ import { outcomeResultExternallyBlocked } from "./long-task-claims.js";
2
3
  import { captureFinalGateProtectedInputIdentity, finalGateIntegrityFindings, } from "./long-task-final-integrity.js";
3
4
  import { assertMatchingActiveBinding, loadActiveLongTaskAuthority, writeFinalReceipt, } from "./long-task-state.js";
4
5
  import { assertVerifierAuthorityCurrent, deliveryCompileFreshness, } from "./long-task-freshness.js";
@@ -47,7 +48,7 @@ export async function runDeliveryFinalGate(workdirInput) {
47
48
  workspace_identity_before: before.identity,
48
49
  protected_inputs_before: protectedInputsBefore,
49
50
  })));
50
- const outcomeResults = projectOutcomes(compiled.outcomes.map((outcome) => outcome.key), run.check_results, run.findings);
51
+ const outcomeResults = projectOutcomes(compiled, run.check_results, run.findings);
51
52
  const globalChecks = run.check_results.filter((check) => check.outcome_key === null);
52
53
  const globalHardFailure = globalChecks.some((check) => check.status !== "passed" && check.status !== "blocked_external");
53
54
  const globalBlocked = globalChecks.some((check) => check.status === "blocked_external");
@@ -131,13 +132,15 @@ function projectStages(compiled, outcomes) {
131
132
  }
132
133
  return result;
133
134
  }
134
- function projectOutcomes(outcomeKeys, checks, findings) {
135
- return Object.fromEntries(outcomeKeys.map((outcomeKey) => {
135
+ function projectOutcomes(compiled, checks, findings) {
136
+ return Object.fromEntries(compiled.outcomes.map((outcome) => {
137
+ const outcomeKey = outcome.key;
136
138
  const owned = checks.filter((check) => check.outcome_key === outcomeKey);
137
139
  const ownFindings = findings.filter((finding) => finding.outcome_key === outcomeKey || finding.outcome_key === null);
138
140
  const status = owned.some((check) => check.status !== "passed" && check.status !== "blocked_external") || ownFindings.some((finding) => finding.code !== "blocked_external")
139
141
  ? "failed"
140
- : owned.some((check) => check.status === "blocked_external")
142
+ : outcomeResultExternallyBlocked(compiled, outcomeKey) ||
143
+ owned.some((check) => check.status === "blocked_external")
141
144
  ? "blocked_external"
142
145
  : "passed";
143
146
  return [outcomeKey, status];
@@ -0,0 +1,26 @@
1
+ export declare class GitCommandError extends Error {
2
+ readonly exitCode: number | null;
3
+ readonly signal: NodeJS.Signals | null;
4
+ readonly stdoutBytes: number;
5
+ readonly stderrBytes: number;
6
+ constructor(exitCode: number | null, signal: NodeJS.Signals | null, argv: string[], stdout: Buffer, stderr: Buffer);
7
+ }
8
+ export declare function repositoryRoot(start: string): Promise<string>;
9
+ export declare function gitCommonDir(root: string): Promise<string>;
10
+ export declare function currentGitState(root: string): Promise<{
11
+ head: string;
12
+ tree: string;
13
+ dirty: string[];
14
+ }>;
15
+ export declare function currentGitTree(root: string): Promise<string>;
16
+ export declare function gitPath(root: string, pathSpec: string): Promise<string>;
17
+ export declare function gitConfigGet(root: string, name: string): Promise<string | null>;
18
+ export declare function gitEffectiveConfigGet(root: string, name: string): Promise<string | null>;
19
+ export declare function gitConfigSet(root: string, name: string, value: string): Promise<void>;
20
+ export declare function gitConfigUnset(root: string, name: string): Promise<void>;
21
+ export declare function repoRelative(rootInput: string, fileInput: string): string;
22
+ export declare function gitOutput(root: string, argv: string[]): Promise<string>;
23
+ export declare function gitVoid(root: string, argv: string[]): Promise<void>;
24
+ export declare function gitBuffer(root: string, argv: string[]): Promise<Buffer>;
25
+ export declare function gitBufferInput(root: string, argv: string[], input?: Buffer): Promise<Buffer>;
26
+ export declare function splitGitZero(value: Buffer): string[];
@@ -0,0 +1,130 @@
1
+ import { spawn } from "node:child_process";
2
+ import { stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export class GitCommandError extends Error {
5
+ exitCode;
6
+ signal;
7
+ stdoutBytes;
8
+ stderrBytes;
9
+ constructor(exitCode, signal, argv, stdout, stderr) {
10
+ const stderrText = stderr.toString("utf8").trim();
11
+ super(`git_exit:${exitCode ?? "null"}:${argv.join(" ")}:signal=${signal ?? "none"}:stdout_bytes=${stdout.length}:stderr=${stderrText}`);
12
+ this.name = "GitCommandError";
13
+ this.exitCode = exitCode;
14
+ this.signal = signal;
15
+ this.stdoutBytes = stdout.length;
16
+ this.stderrBytes = stderr.length;
17
+ }
18
+ }
19
+ export async function repositoryRoot(start) {
20
+ const resolved = path.resolve(start);
21
+ const gitEntry = await stat(path.join(resolved, ".git")).catch(() => null);
22
+ if (gitEntry?.isDirectory() || gitEntry?.isFile())
23
+ return resolved;
24
+ return path.resolve(await gitOutput(resolved, ["rev-parse", "--show-toplevel"]));
25
+ }
26
+ export async function gitCommonDir(root) {
27
+ return path.resolve(await gitOutput(root, [
28
+ "rev-parse",
29
+ "--path-format=absolute",
30
+ "--git-common-dir",
31
+ ]));
32
+ }
33
+ export async function currentGitState(root) {
34
+ const [head, tree, raw] = await Promise.all([
35
+ gitOutput(root, ["rev-parse", "HEAD"]),
36
+ gitOutput(root, ["rev-parse", "HEAD^{tree}"]),
37
+ gitOutput(root, ["status", "--short", "--untracked-files=all"]),
38
+ ]);
39
+ return {
40
+ head,
41
+ tree,
42
+ dirty: raw ? raw.split(/\r?\n/u).filter(Boolean) : [],
43
+ };
44
+ }
45
+ export async function currentGitTree(root) {
46
+ return gitOutput(root, ["rev-parse", "HEAD^{tree}"]);
47
+ }
48
+ export async function gitPath(root, pathSpec) {
49
+ return path.resolve(await gitOutput(root, [
50
+ "rev-parse",
51
+ "--path-format=absolute",
52
+ "--git-path",
53
+ pathSpec,
54
+ ]));
55
+ }
56
+ export async function gitConfigGet(root, name) {
57
+ try {
58
+ return await gitOutput(root, ["config", "--local", "--get", name]);
59
+ }
60
+ catch (error) {
61
+ if (error instanceof GitCommandError && error.exitCode === 1)
62
+ return null;
63
+ throw error;
64
+ }
65
+ }
66
+ export async function gitEffectiveConfigGet(root, name) {
67
+ try {
68
+ return await gitOutput(root, ["config", "--get", name]);
69
+ }
70
+ catch (error) {
71
+ if (error instanceof GitCommandError && error.exitCode === 1)
72
+ return null;
73
+ throw error;
74
+ }
75
+ }
76
+ export async function gitConfigSet(root, name, value) {
77
+ await gitVoid(root, ["config", "--local", name, value]);
78
+ }
79
+ export async function gitConfigUnset(root, name) {
80
+ try {
81
+ await gitVoid(root, ["config", "--local", "--unset-all", name]);
82
+ }
83
+ catch (error) {
84
+ if (!(error instanceof GitCommandError) || error.exitCode !== 5)
85
+ throw error;
86
+ }
87
+ }
88
+ export function repoRelative(rootInput, fileInput) {
89
+ const value = path
90
+ .relative(path.resolve(rootInput), path.resolve(fileInput))
91
+ .replace(/\\/gu, "/");
92
+ if (value.startsWith("../") || path.isAbsolute(value))
93
+ throw new Error(`path_outside_repository:${fileInput}`);
94
+ return value;
95
+ }
96
+ export async function gitOutput(root, argv) {
97
+ return (await gitBuffer(root, argv)).toString("utf8").trim();
98
+ }
99
+ export async function gitVoid(root, argv) {
100
+ await gitBuffer(root, argv);
101
+ }
102
+ export async function gitBuffer(root, argv) {
103
+ return gitBufferInput(root, argv);
104
+ }
105
+ export async function gitBufferInput(root, argv, input) {
106
+ return new Promise((resolve, reject) => {
107
+ const child = spawn("git", argv, {
108
+ cwd: root,
109
+ shell: false,
110
+ windowsHide: true,
111
+ });
112
+ const stdout = [];
113
+ const stderr = [];
114
+ child.stdout.on("data", (chunk) => stdout.push(chunk));
115
+ child.stderr.on("data", (chunk) => stderr.push(chunk));
116
+ child.on("error", reject);
117
+ child.stdin.end(input);
118
+ child.on("close", (code, signal) => {
119
+ const stdoutBytes = Buffer.concat(stdout);
120
+ const stderrBytes = Buffer.concat(stderr);
121
+ if (code === 0)
122
+ resolve(stdoutBytes);
123
+ else
124
+ reject(new GitCommandError(code, signal, argv, stdoutBytes, stderrBytes));
125
+ });
126
+ });
127
+ }
128
+ export function splitGitZero(value) {
129
+ return value.toString("utf8").split("\0").filter(Boolean);
130
+ }
@@ -0,0 +1,59 @@
1
+ export declare const JSON_POINTER_EXACT_CAPABILITY = "json-pointer-exact-v1";
2
+ export declare const JSON_POINTER_EXACT_ORACLE_IDENTITY = "ty-context-json-pointer-exact";
3
+ export declare const JSON_POINTER_EXACT_ORACLE_VERSION = "1.0.0";
4
+ export declare const JSON_POINTER_EXACT_METHODS: readonly ["exact_value", "content", "component_state"];
5
+ export declare const JSON_POINTER_EXACT_LIMITS: Readonly<{
6
+ max_file_bytes: 1048576;
7
+ max_depth: 64;
8
+ max_pointer_bytes: 4096;
9
+ max_pointer_segments: 128;
10
+ max_canonical_value_bytes: 262144;
11
+ max_artifacts_per_check: 256;
12
+ max_total_artifact_bytes: 16777216;
13
+ }>;
14
+ export declare const JSON_POINTER_EXACT_SPEC_SHA256: string;
15
+ export interface JsonPointerExactBudget {
16
+ readonly seen_artifact_paths: Set<string>;
17
+ total_artifact_bytes: number;
18
+ }
19
+ export interface JsonPointerExactLocator {
20
+ kind: string;
21
+ value: string;
22
+ }
23
+ export interface JsonPointerExactObservation {
24
+ capability: typeof JSON_POINTER_EXACT_CAPABILITY;
25
+ artifact_path: string;
26
+ artifact_sha256: string;
27
+ locator: {
28
+ kind: "json_pointer";
29
+ value: string;
30
+ };
31
+ value_sha256: string;
32
+ canonical_value_bytes: number;
33
+ sensitivity: "plain";
34
+ }
35
+ export declare function createJsonPointerExactBudget(): JsonPointerExactBudget;
36
+ export declare function isJsonPointerExactOracle(oracle: {
37
+ trust?: string;
38
+ identity?: string;
39
+ version?: string;
40
+ sha256?: string | null;
41
+ }): boolean;
42
+ export declare function extractJsonPointerExactObservationFromBytes(input: {
43
+ artifact_path: string;
44
+ bytes: Uint8Array;
45
+ locator: JsonPointerExactLocator;
46
+ sensitivity: string;
47
+ budget?: JsonPointerExactBudget;
48
+ }): JsonPointerExactObservation;
49
+ export declare function validateJsonPointerExactLocator(locator: JsonPointerExactLocator): {
50
+ kind: "json_pointer";
51
+ value: string;
52
+ };
53
+ export declare function normalizeObservationArtifactPath(value: string): string;
54
+ export declare function invalidObservation(code: string): Error;
55
+ export declare function observationErrorMessage(error: unknown): string;
56
+ export declare function resolveJsonPointer(root: unknown, pointer: string): unknown;
57
+ export declare function parseJsonWithoutDuplicateKeys(content: string): unknown;
58
+ export declare function decodeUtf8Json(bytes: Uint8Array): string;
59
+ export declare function assertJsonTree(value: unknown, depth: number): void;