project-tiny-context-harness 0.7.2 → 0.7.4

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 (82) hide show
  1. package/README.md +7 -5
  2. package/assets/README.md +49 -14
  3. package/assets/README.zh-CN.md +26 -13
  4. package/assets/agents/AGENTS_CORE.md +5 -5
  5. package/assets/context_templates/global.md +1 -0
  6. package/assets/skills/context_development_engineer/SKILL.md +4 -1
  7. package/assets/skills/context_uiux_design/SKILL.md +19 -6
  8. package/assets/skills/long-task-workflow/SKILL.md +10 -9
  9. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +7 -5
  10. package/assets/skills/long-task-workflow/references/contract-authoring.md +24 -6
  11. package/assets/skills/long-task-workflow/references/evidence-design.md +14 -1
  12. package/assets/skills/source-plan-authoring/SKILL.md +2 -2
  13. package/dist/commands/long-task-authoring.js +25 -0
  14. package/dist/commands/long-task.js +3 -0
  15. package/dist/lib/design-md.d.ts +3 -0
  16. package/dist/lib/design-md.js +48 -55
  17. package/dist/lib/doctor.js +8 -0
  18. package/dist/lib/long-task-activation-validation.js +13 -2
  19. package/dist/lib/long-task-authoring-authority-preview.js +1 -0
  20. package/dist/lib/long-task-authority-material-diff.js +26 -0
  21. package/dist/lib/long-task-authority-materials.d.ts +2 -2
  22. package/dist/lib/long-task-authority-materials.js +6 -0
  23. package/dist/lib/long-task-authority-policy.d.ts +12 -0
  24. package/dist/lib/long-task-authority-policy.js +9 -0
  25. package/dist/lib/long-task-authority-revision-analysis.d.ts +33 -0
  26. package/dist/lib/long-task-authority-revision-analysis.js +91 -0
  27. package/dist/lib/long-task-authority-revision.js +93 -158
  28. package/dist/lib/long-task-authority-types.d.ts +7 -0
  29. package/dist/lib/long-task-authority.js +32 -3
  30. package/dist/lib/long-task-check-evidence-decoder.d.ts +2 -2
  31. package/dist/lib/long-task-check-evidence-decoder.js +11 -1
  32. package/dist/lib/long-task-check-execution-policy.d.ts +3 -0
  33. package/dist/lib/long-task-check-execution-policy.js +5 -0
  34. package/dist/lib/long-task-check-runner.js +2 -0
  35. package/dist/lib/long-task-check-shape.js +33 -3
  36. package/dist/lib/long-task-conformance-policy.d.ts +5 -0
  37. package/dist/lib/long-task-conformance-policy.js +35 -0
  38. package/dist/lib/long-task-contract-types.d.ts +14 -4
  39. package/dist/lib/long-task-delivery-compiler.js +1 -0
  40. package/dist/lib/long-task-delivery-parser.js +5 -2
  41. package/dist/lib/long-task-delivery-types.d.ts +2 -0
  42. package/dist/lib/long-task-delivery-types.js +2 -0
  43. package/dist/lib/long-task-delivery-validation.js +11 -0
  44. package/dist/lib/long-task-evidence-capability-codec.d.ts +2 -0
  45. package/dist/lib/long-task-evidence-capability-codec.js +231 -0
  46. package/dist/lib/long-task-evidence-capability-policy.d.ts +8 -0
  47. package/dist/lib/long-task-evidence-capability-policy.js +147 -0
  48. package/dist/lib/long-task-evidence-capability-runtime.d.ts +2 -0
  49. package/dist/lib/long-task-evidence-capability-runtime.js +86 -0
  50. package/dist/lib/long-task-evidence-capability-types.d.ts +74 -0
  51. package/dist/lib/long-task-evidence-capability-types.js +1 -0
  52. package/dist/lib/long-task-evidence-findings.js +5 -1
  53. package/dist/lib/long-task-evidence-v2.js +38 -23
  54. package/dist/lib/long-task-final-v2.js +42 -1
  55. package/dist/lib/long-task-outcome-parser.js +14 -3
  56. package/dist/lib/long-task-playwright-evidence.d.ts +2 -1
  57. package/dist/lib/long-task-playwright-evidence.js +70 -2
  58. package/dist/lib/long-task-progress.js +4 -0
  59. package/dist/lib/long-task-root-shape.d.ts +1 -0
  60. package/dist/lib/long-task-root-shape.js +84 -3
  61. package/dist/lib/long-task-runner-environment.js +1 -1
  62. package/dist/lib/long-task-runner-freeze.d.ts +2 -2
  63. package/dist/lib/long-task-runner-freeze.js +3 -1
  64. package/dist/lib/long-task-runtime-types.d.ts +13 -0
  65. package/dist/lib/long-task-semantic-contract-types.d.ts +36 -0
  66. package/dist/lib/long-task-semantic-contract-types.js +1 -0
  67. package/dist/lib/long-task-semantic-drift-migration.d.ts +3 -0
  68. package/dist/lib/long-task-semantic-drift-migration.js +68 -0
  69. package/dist/lib/long-task-shape-primitives.d.ts +3 -0
  70. package/dist/lib/long-task-shape-primitives.js +25 -0
  71. package/dist/lib/long-task-stage-policy.d.ts +4 -0
  72. package/dist/lib/long-task-stage-policy.js +120 -0
  73. package/dist/lib/long-task-status-projection.d.ts +4 -1
  74. package/dist/lib/long-task-status-projection.js +63 -3
  75. package/dist/lib/long-task-status-v2.d.ts +11 -1
  76. package/dist/lib/long-task-status-v2.js +25 -3
  77. package/dist/lib/long-task-target-policy.d.ts +6 -0
  78. package/dist/lib/long-task-target-policy.js +127 -0
  79. package/dist/lib/migrations.js +29 -0
  80. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +61 -7
  81. package/migrations/README.md +7 -0
  82. package/package.json +2 -2
@@ -74,18 +74,28 @@ export async function runDeliveryFinalGate(workdirInput) {
74
74
  const blocked = globalBlocked ||
75
75
  Object.values(outcomeResults).includes("blocked_external") ||
76
76
  run.findings.some((finding) => finding.code === "blocked_external");
77
+ const targetBlocked = compiled.global.acceptance.external_confirmations.some((confirmation) => confirmation.blocks_target);
77
78
  const workflowStatus = failed
78
79
  ? "needs_work"
79
- : blocked
80
+ : blocked || targetBlocked
80
81
  ? "blocked_external"
81
82
  : compiled.global.acceptance.external_confirmations.length
82
83
  ? "machine_accepted_external_pending"
83
84
  : "machine_accepted";
85
+ const targetState = workflowStatus === "machine_accepted" ||
86
+ workflowStatus === "machine_accepted_external_pending"
87
+ ? compiled.task.target_profile.required_state
88
+ : workflowStatus === "blocked_external"
89
+ ? "blocked_external"
90
+ : "not_accepted";
84
91
  return writeFinalReceipt(repository, active.workdir, {
85
92
  schema_version: "long-task-final-receipt-v2",
86
93
  authority_scope: "audit_only",
87
94
  reusable_for_acceptance: false,
88
95
  workflow_status: workflowStatus,
96
+ target_profile: compiled.task.target_profile,
97
+ target_state: targetState,
98
+ stage_results: projectStages(compiled, outcomeResults),
89
99
  compiled_identity: compiled.compiled_identity,
90
100
  contract_sha256: compiled.contract_sha256,
91
101
  snapshot_sha256: snapshot.manifest.snapshot_sha256,
@@ -107,6 +117,37 @@ export async function runDeliveryFinalGate(workdirInput) {
107
117
  await snapshot.dispose();
108
118
  }
109
119
  }
120
+ function projectStages(compiled, outcomes) {
121
+ const result = {};
122
+ const remaining = new Set(compiled.stages.map((stage) => stage.key));
123
+ while (remaining.size) {
124
+ let advanced = false;
125
+ for (const stage of compiled.stages) {
126
+ if (!remaining.has(stage.key))
127
+ continue;
128
+ if (stage.depends_on.some((dependency) => remaining.has(dependency)))
129
+ continue;
130
+ const owned = compiled.outcomes
131
+ .filter((outcome) => outcome.stage === stage.key)
132
+ .map((outcome) => outcomes[outcome.key]);
133
+ result[stage.key] = owned.includes("failed")
134
+ ? "failed"
135
+ : owned.includes("blocked_external")
136
+ ? "blocked_external"
137
+ : stage.depends_on.some((dependency) => result[dependency] !== "passed")
138
+ ? "blocked_dependency"
139
+ : "passed";
140
+ remaining.delete(stage.key);
141
+ advanced = true;
142
+ }
143
+ if (!advanced) {
144
+ for (const stage of remaining)
145
+ result[stage] = "blocked_dependency";
146
+ break;
147
+ }
148
+ }
149
+ return result;
150
+ }
110
151
  function projectOutcomes(outcomeKeys, checks, findings) {
111
152
  return Object.fromEntries(outcomeKeys.map((outcomeKey) => {
112
153
  const owned = checks.filter((check) => check.outcome_key === outcomeKey);
@@ -1,11 +1,18 @@
1
1
  import { parseCheck } from "./long-task-check-shape.js";
2
2
  import { normalizeRepositoryFile } from "./long-task-paths.js";
3
3
  import { parseRequirements } from "./long-task-requirement-shape.js";
4
- import { array, key, literal, nullable, object, parseBindings, parseControls, parseCounterfactuals, parseKeyedStatements, parseObligations, parseOwner, parsePopulation, parseRollback, repositoryPatterns, string, strings, } from "./long-task-delivery-shape.js";
4
+ import { array, boolean, key, literal, nullable, object, parseBindings, parseControls, parseCounterfactuals, parseKeyedStatements, parseObligations, parseOwner, parsePopulation, parseRollback, repositoryPatterns, string, strings, } from "./long-task-delivery-shape.js";
5
5
  import { parseStrictYaml } from "./strict-codec.js";
6
+ import { assertNoSemanticDriftMigration, semanticDriftOutcomeMigrationFields, } from "./long-task-semantic-drift-migration.js";
6
7
  export function parseOutcome(value, label) {
7
- const row = object(value, label, ["key", "title", "product", "technical", "acceptance"], ["depends_on"]);
8
- const product = object(row.product, `${label}.product`, ["observable_result", "owner"], ["requirements", "owner_surfaces", "controls", "non_completing_outcomes"]);
8
+ assertNoSemanticDriftMigration(semanticDriftOutcomeMigrationFields(value, label));
9
+ const row = object(value, label, ["key", "title", "stage", "product", "technical", "acceptance"], ["depends_on"]);
10
+ const product = object(row.product, `${label}.product`, [
11
+ "observable_result",
12
+ "success_path_required",
13
+ "degradation_path_required",
14
+ "owner",
15
+ ], ["requirements", "owner_surfaces", "controls", "non_completing_outcomes"]);
9
16
  const technical = object(row.technical, `${label}.technical`, ["expected_change_paths"], [
10
17
  "obligations",
11
18
  "allowed_support_paths",
@@ -18,11 +25,14 @@ export function parseOutcome(value, label) {
18
25
  return {
19
26
  key: key(row.key, `${label}.key`),
20
27
  title: string(row.title, `${label}.title`),
28
+ stage: key(row.stage, `${label}.stage`),
21
29
  depends_on: Object.hasOwn(row, "depends_on")
22
30
  ? strings(row.depends_on, `${label}.depends_on`).map((item, index) => key(item, `${label}.depends_on[${index}]`))
23
31
  : [],
24
32
  product: {
25
33
  observable_result: string(product.observable_result, `${label}.product.observable_result`),
34
+ success_path_required: boolean(product.success_path_required, `${label}.product.success_path_required`),
35
+ degradation_path_required: boolean(product.degradation_path_required, `${label}.product.degradation_path_required`),
26
36
  owner: parseOwner(product.owner, `${label}.product.owner`),
27
37
  requirements: Object.hasOwn(product, "requirements")
28
38
  ? parseRequirements(product.requirements, `${label}.product.requirements`)
@@ -78,6 +88,7 @@ export function parseOutcomeFragment(raw, relative) {
78
88
  "outcomes",
79
89
  "key",
80
90
  "title",
91
+ "stage",
81
92
  "depends_on",
82
93
  "product",
83
94
  "technical",
@@ -1,6 +1,7 @@
1
- import type { CompiledCheckV2 } from "./long-task-delivery-types.js";
1
+ import type { CompiledCheckV2, EvidenceCapabilityRecordV2 } from "./long-task-delivery-types.js";
2
2
  export interface PlaywrightEvidence {
3
3
  observations: Record<string, unknown>;
4
+ evidence_records: EvidenceCapabilityRecordV2[];
4
5
  error: string | null;
5
6
  }
6
7
  export declare function extractPlaywrightEvidence(check: CompiledCheckV2, report: Record<string, unknown>, exitCode: number): PlaywrightEvidence;
@@ -61,7 +61,33 @@ export function extractPlaywrightEvidence(check, report, exitCode) {
61
61
  }
62
62
  }
63
63
  observations["playwright.case_ids"] = cases.map((item) => item.id).sort();
64
- return { observations, error: null };
64
+ const evidenceRecords = [];
65
+ for (const item of cases) {
66
+ const assertion = [
67
+ ...check.positive_assertions,
68
+ ...check.negative_assertions,
69
+ ].find((candidate) => candidate.key === item.id);
70
+ if (assertion?.evidence_capabilities.includes("interaction_trace") &&
71
+ item.executed)
72
+ evidenceRecords.push({
73
+ assertion_key: assertion.key,
74
+ capability: "interaction_trace",
75
+ target_ref: check.execution_target.target_ref,
76
+ given_keys: item.given_keys,
77
+ action_keys: item.action_keys,
78
+ });
79
+ if (assertion?.evidence_capabilities.includes("target_runtime") &&
80
+ item.executed)
81
+ evidenceRecords.push({
82
+ assertion_key: assertion.key,
83
+ capability: "target_runtime",
84
+ target_ref: check.execution_target.target_ref,
85
+ root_entrypoint: check.execution_target_definition.root_entrypoint,
86
+ session_id: `playwright:${item.id}:${item.project_ids.join(",")}`,
87
+ cold_start: check.execution_target.entrypoint === "root",
88
+ });
89
+ }
90
+ return { observations, evidence_records: evidenceRecords, error: null };
65
91
  }
66
92
  function collectCases(report, declaredIds) {
67
93
  const cases = [];
@@ -139,6 +165,10 @@ function playwrightCase(id, test) {
139
165
  status === "expected" &&
140
166
  resultStatuses.length > 0 &&
141
167
  resultStatuses.at(-1) === "passed";
168
+ const traces = results.map((result) => scenarioTrace(result));
169
+ const givenKeys = traces[0]?.given_keys ?? [];
170
+ const actionKeys = traces[0]?.action_keys ?? [];
171
+ const traceConsistent = traces.every((trace) => same(trace.given_keys, givenKeys) && same(trace.action_keys, actionKeys));
142
172
  return {
143
173
  id,
144
174
  project_id: projectId,
@@ -150,6 +180,8 @@ function playwrightCase(id, test) {
150
180
  timed_out: timedOut,
151
181
  interrupted,
152
182
  status,
183
+ given_keys: traceConsistent ? givenKeys : [],
184
+ action_keys: traceConsistent ? actionKeys : [],
153
185
  };
154
186
  }
155
187
  function declaredCaseIds(check) {
@@ -227,6 +259,14 @@ function aggregateCases(instances) {
227
259
  unexpected_instances: unexpectedInstances,
228
260
  timed_out_instances: timedOutInstances,
229
261
  interrupted_instances: interruptedInstances,
262
+ given_keys: rows.length &&
263
+ rows.every((row) => same(row.given_keys, rows[0].given_keys))
264
+ ? rows[0].given_keys
265
+ : [],
266
+ action_keys: rows.length &&
267
+ rows.every((row) => same(row.action_keys, rows[0].action_keys))
268
+ ? rows[0].action_keys
269
+ : [],
230
270
  };
231
271
  })
232
272
  .sort((left, right) => left.id.localeCompare(right.id));
@@ -239,6 +279,34 @@ function record(value) {
239
279
  function integer(value) {
240
280
  return Number.isInteger(value) && Number(value) >= 0 ? Number(value) : null;
241
281
  }
282
+ function scenarioTrace(result) {
283
+ const givenKeys = [];
284
+ const actionKeys = [];
285
+ const visit = (value) => {
286
+ if (!Array.isArray(value))
287
+ return;
288
+ for (const item of value) {
289
+ const step = record(item);
290
+ if (!step)
291
+ continue;
292
+ if (typeof step.title === "string") {
293
+ const given = /^\[given:([a-z0-9][a-z0-9-]*)\]$/u.exec(step.title);
294
+ const action = /^\[action:([a-z0-9][a-z0-9-]*)\]$/u.exec(step.title);
295
+ if (given)
296
+ givenKeys.push(given[1]);
297
+ if (action)
298
+ actionKeys.push(action[1]);
299
+ }
300
+ visit(step.steps);
301
+ }
302
+ };
303
+ visit(result.steps);
304
+ return { given_keys: givenKeys, action_keys: actionKeys };
305
+ }
306
+ function same(left, right) {
307
+ return (left.length === right.length &&
308
+ left.every((value, index) => value === right[index]));
309
+ }
242
310
  function invalid(error) {
243
- return { observations: {}, error };
311
+ return { observations: {}, evidence_records: [], error };
244
312
  }
@@ -76,6 +76,10 @@ export function checkIdentity(check) {
76
76
  artifact_globs: check.artifact_globs,
77
77
  positive_assertions: check.positive_assertions,
78
78
  negative_assertions: check.negative_assertions,
79
+ journey_roles: check.journey_roles,
80
+ execution_target: check.execution_target,
81
+ execution_target_definition: check.execution_target_definition,
82
+ scenario: check.scenario,
79
83
  environment_requirements: check.environment_requirements,
80
84
  }));
81
85
  }
@@ -1,4 +1,5 @@
1
1
  import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
2
2
  export declare function parseTask(value: unknown): DeliveryContractV2["task"];
3
+ export declare function parseStages(value: unknown): DeliveryContractV2["stages"];
3
4
  export declare function parseRisk(value: unknown): DeliveryContractV2["risk"];
4
5
  export declare function parseGlobal(value: unknown): DeliveryContractV2["global"];
@@ -1,6 +1,6 @@
1
1
  import { parseGlobalCounterfactuals } from "./long-task-acceptance-shape.js";
2
2
  import { parseCheck } from "./long-task-check-shape.js";
3
- import { array, key, literal, object, parseKeyedPaths, parseKeyedStatements, repositoryFiles, string, strings, } from "./long-task-delivery-shape.js";
3
+ import { array, boolean, key, literal, object, parseKeyedPaths, parseKeyedStatements, repositoryFiles, string, strings, } from "./long-task-delivery-shape.js";
4
4
  const RISK_FACTS = [
5
5
  "public_api_or_schema_change",
6
6
  "persistent_data_change",
@@ -14,11 +14,59 @@ const RISK_FACTS = [
14
14
  "weak_observability",
15
15
  ];
16
16
  export function parseTask(value) {
17
- const row = object(value, "task", ["id", "title", "goal", "source_paths", "context_refs"], ["context_snapshot_mode"]);
17
+ const row = object(value, "task", [
18
+ "id",
19
+ "title",
20
+ "goal",
21
+ "target_profile",
22
+ "execution_targets",
23
+ "source_paths",
24
+ "context_refs",
25
+ ], ["context_snapshot_mode"]);
26
+ const targetProfile = object(row.target_profile, "task.target_profile", [
27
+ "key",
28
+ "description",
29
+ "required_state",
30
+ "required_target_refs",
31
+ ]);
18
32
  return {
19
33
  id: key(row.id, "task.id"),
20
34
  title: string(row.title, "task.title"),
21
35
  goal: string(row.goal, "task.goal"),
36
+ target_profile: {
37
+ key: key(targetProfile.key, "task.target_profile.key"),
38
+ description: string(targetProfile.description, "task.target_profile.description"),
39
+ required_state: literal(targetProfile.required_state, [
40
+ "implementation_complete",
41
+ "target_profile_usable",
42
+ "production_release_ready",
43
+ ], "task.target_profile.required_state"),
44
+ required_target_refs: strings(targetProfile.required_target_refs, "task.target_profile.required_target_refs").map((item, index) => key(item, `task.target_profile.required_target_refs[${index}]`)),
45
+ },
46
+ execution_targets: array(row.execution_targets, "task.execution_targets").map((item, index) => {
47
+ const label = `task.execution_targets[${index}]`;
48
+ const target = object(item, label, [
49
+ "key",
50
+ "description",
51
+ "role",
52
+ "runtime_family",
53
+ "root_entrypoint",
54
+ ]);
55
+ return {
56
+ key: key(target.key, `${label}.key`),
57
+ description: string(target.description, `${label}.description`),
58
+ role: literal(target.role, ["product", "support", "observer"], `${label}.role`),
59
+ runtime_family: literal(target.runtime_family, [
60
+ "browser",
61
+ "native",
62
+ "desktop",
63
+ "service",
64
+ "process",
65
+ "external",
66
+ ], `${label}.runtime_family`),
67
+ root_entrypoint: string(target.root_entrypoint, `${label}.root_entrypoint`),
68
+ };
69
+ }),
22
70
  source_paths: repositoryFiles(row.source_paths, "task.source_paths"),
23
71
  context_refs: repositoryFiles(row.context_refs, "task.context_refs"),
24
72
  context_snapshot_mode: Object.hasOwn(row, "context_snapshot_mode")
@@ -26,6 +74,23 @@ export function parseTask(value) {
26
74
  : "referenced",
27
75
  };
28
76
  }
77
+ export function parseStages(value) {
78
+ return array(value, "stages").map((item, index) => {
79
+ const label = `stages[${index}]`;
80
+ const row = object(item, label, [
81
+ "key",
82
+ "title",
83
+ "depends_on",
84
+ "gate_outcome",
85
+ ]);
86
+ return {
87
+ key: key(row.key, `${label}.key`),
88
+ title: string(row.title, `${label}.title`),
89
+ depends_on: strings(row.depends_on, `${label}.depends_on`).map((entry, dependencyIndex) => key(entry, `${label}.depends_on[${dependencyIndex}]`)),
90
+ gate_outcome: key(row.gate_outcome, `${label}.gate_outcome`),
91
+ };
92
+ });
93
+ }
29
94
  export function parseRisk(value) {
30
95
  const row = object(value, "risk", ["facts"], ["requested_level"]);
31
96
  const facts = object(row.facts, "risk.facts", [], [...RISK_FACTS]);
@@ -73,11 +138,27 @@ export function parseGlobal(value) {
73
138
  external_confirmations: Object.hasOwn(acceptance, "external_confirmations")
74
139
  ? array(acceptance.external_confirmations, "global.acceptance.external_confirmations").map((item, index) => {
75
140
  const label = `global.acceptance.external_confirmations[${index}]`;
76
- const entry = object(item, label, ["key", "description", "owner"]);
141
+ const entry = object(item, label, [
142
+ "key",
143
+ "description",
144
+ "owner",
145
+ "kind",
146
+ "impact_claims",
147
+ "blocks_target",
148
+ ]);
77
149
  return {
78
150
  key: key(entry.key, `${label}.key`),
79
151
  description: string(entry.description, `${label}.description`),
80
152
  owner: string(entry.owner, `${label}.owner`),
153
+ kind: literal(entry.kind, [
154
+ "functional_prerequisite",
155
+ "field_validation",
156
+ "production_release_gate",
157
+ "commercial_activation",
158
+ "expert_authority",
159
+ ], `${label}.kind`),
160
+ impact_claims: strings(entry.impact_claims, `${label}.impact_claims`),
161
+ blocks_target: boolean(entry.blocks_target, `${label}.blocks_target`),
81
162
  };
82
163
  })
83
164
  : [],
@@ -23,7 +23,7 @@ const BASE_ENVIRONMENT_KEYS = [
23
23
  ];
24
24
  export function runnerEnvironment(requirements) {
25
25
  const environment = {
26
- TY_CONTEXT_CHECK_PROTOCOL: "long-task-check-result-v2",
26
+ TY_CONTEXT_CHECK_PROTOCOL: "long-task-check-result-v3",
27
27
  };
28
28
  for (const key of BASE_ENVIRONMENT_KEYS)
29
29
  copyEnvironmentValue(environment, key);
@@ -1,2 +1,2 @@
1
- import type { CompiledCheckV2, DeliveryCheckV2, WorkspaceManifestV2 } from "./long-task-delivery-types.js";
2
- export declare function freezeDeliveryCheck(check: DeliveryCheckV2, outcomeKey: string | null, repository: string, baseline: WorkspaceManifestV2): Promise<CompiledCheckV2>;
1
+ import type { CompiledCheckV2, DeliveryCheckV2, ExecutionTargetV2, WorkspaceManifestV2 } from "./long-task-delivery-types.js";
2
+ export declare function freezeDeliveryCheck(check: DeliveryCheckV2, outcomeKey: string | null, repository: string, baseline: WorkspaceManifestV2, executionTarget: ExecutionTargetV2, knownExecutionTargets: ExecutionTargetV2[]): Promise<CompiledCheckV2>;
@@ -7,7 +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
- export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline) {
10
+ export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline, executionTarget, knownExecutionTargets) {
11
11
  const prefix = outcomeKey ? `CHECK.${outcomeKey}` : "CHECK.GLOBAL";
12
12
  const expectedOutputs = check.expected_output_paths.map((pattern, index) => assertRepositoryPattern(repository, pattern, `${check.key}.expected_output_paths[${index}]`));
13
13
  for (const [index, pattern] of check.input_paths.entries()) {
@@ -30,6 +30,8 @@ export async function freezeDeliveryCheck(check, outcomeKey, repository, baselin
30
30
  evidence_adapter: evidenceAdapterForRunner(check.runner.type),
31
31
  runner: await freezeRunner(check, repository, cwd, target, verificationInputHashes),
32
32
  verification_input_hashes: verificationInputHashes,
33
+ execution_target_definition: executionTarget,
34
+ known_execution_targets: knownExecutionTargets,
33
35
  };
34
36
  return {
35
37
  ...compiled,
@@ -1,6 +1,8 @@
1
1
  import type { DeliveryCheckV2, DeliveryContractV2, DeliveryOutcomeV2, DeliveryRunnerV2, ProofSurface } from "./long-task-contract-types.js";
2
+ import type { EvidenceCapabilityV2, ExecutionTargetV2 } from "./long-task-semantic-contract-types.js";
2
3
  import type { AuthorityHashesV2, ContextAuthoritySnapshotV2, InitialTaskBaseV2, NextAuthorityMaterialsV2, VerifierIdentityV2 } from "./long-task-authority-types.js";
3
4
  import type { EvidenceAdapter } from "./long-task-evidence-adapter-types.js";
5
+ import type { EvidenceCapabilityRecordV2 } from "./long-task-evidence-capability-types.js";
4
6
  import type { EffectiveRiskLevel, RiskFactName } from "./long-task-risk-types.js";
5
7
  import type { CompiledSourceItemV2 } from "./long-task-source-authority-types.js";
6
8
  import type { WorkspaceManifestV2 } from "./long-task-workspace-runtime-types.js";
@@ -21,6 +23,8 @@ export interface CompiledCheckV2 extends Omit<DeliveryCheckV2, "runner"> {
21
23
  evidence_adapter: EvidenceAdapter;
22
24
  verification_input_hashes: Record<string, string>;
23
25
  raw_execution_identity: string;
26
+ execution_target_definition: ExecutionTargetV2;
27
+ known_execution_targets: ExecutionTargetV2[];
24
28
  }
25
29
  export interface ProductClaimV2 {
26
30
  id: string;
@@ -88,6 +92,7 @@ export interface CompiledDeliveryContractV2 {
88
92
  task: DeliveryContractV2["task"];
89
93
  risk: DeliveryContractV2["risk"];
90
94
  source_claims: DeliveryContractV2["source_claims"];
95
+ stages: DeliveryContractV2["stages"];
91
96
  global: Omit<DeliveryContractV2["global"], "acceptance"> & {
92
97
  acceptance: {
93
98
  checks: CompiledCheckV2[];
@@ -123,6 +128,8 @@ export interface AssertionResultV2 {
123
128
  passed: boolean;
124
129
  claims: string[];
125
130
  observation: string;
131
+ evidence_capabilities: EvidenceCapabilityV2[];
132
+ evidence_complete: boolean;
126
133
  status: "passed" | "observation_missing" | "observation_type_mismatch" | "assertion_value_mismatch";
127
134
  expected?: unknown;
128
135
  actual?: unknown;
@@ -133,6 +140,7 @@ export interface RawCommandExecutionV2 {
133
140
  execution_status: "completed" | "blocked_external" | "infrastructure_error" | "invalid_evidence";
134
141
  exit_code: number;
135
142
  observations: Record<string, unknown>;
143
+ evidence_records: EvidenceCapabilityRecordV2[];
136
144
  stdout_sha256: string;
137
145
  stderr_sha256: string;
138
146
  attempts: number;
@@ -148,6 +156,7 @@ export interface CheckExecutionResultV2 {
148
156
  execution_identity: string;
149
157
  assertion_results: AssertionResultV2[];
150
158
  observations: Record<string, unknown>;
159
+ evidence_records: EvidenceCapabilityRecordV2[];
151
160
  artifact_hashes: Record<string, string>;
152
161
  claim_proofs: ClaimProofV2[];
153
162
  findings: LongTaskFindingV2[];
@@ -185,12 +194,16 @@ export interface TargetedVerificationResultV2 {
185
194
  completed_at: string;
186
195
  }
187
196
  export type OutcomeStatusV2 = "unverified" | "progress_passing" | "progress_failing" | "progress_stale" | "blocked_external";
197
+ export type StageStatusV2 = "locked" | "ready" | "unverified" | "progress_passing" | "progress_failing" | "progress_stale" | "blocked_external";
188
198
  export interface FinalReceiptV2 {
189
199
  schema_version: "long-task-final-receipt-v2";
190
200
  receipt_sha256: string;
191
201
  authority_scope: "audit_only";
192
202
  reusable_for_acceptance: false;
193
203
  workflow_status: "machine_accepted" | "machine_accepted_external_pending" | "needs_work" | "blocked_external";
204
+ target_profile: DeliveryContractV2["task"]["target_profile"];
205
+ target_state: DeliveryContractV2["task"]["target_profile"]["required_state"] | "not_accepted" | "blocked_external";
206
+ stage_results: Record<string, "passed" | "failed" | "blocked_external" | "blocked_dependency">;
194
207
  compiled_identity: string;
195
208
  contract_sha256: string;
196
209
  snapshot_sha256: string;
@@ -0,0 +1,36 @@
1
+ export interface KeyedStatementV2 {
2
+ key: string;
3
+ statement: string;
4
+ }
5
+ export type ExternalConfirmationKindV2 = "functional_prerequisite" | "field_validation" | "production_release_gate" | "commercial_activation" | "expert_authority";
6
+ export type TargetCompletionStateV2 = "implementation_complete" | "target_profile_usable" | "production_release_ready";
7
+ export type ExecutionTargetRuntimeFamilyV2 = "browser" | "native" | "desktop" | "service" | "process" | "external";
8
+ export interface TargetProfileV2 {
9
+ key: string;
10
+ description: string;
11
+ required_state: TargetCompletionStateV2;
12
+ required_target_refs: string[];
13
+ }
14
+ export interface ExecutionTargetV2 {
15
+ key: string;
16
+ description: string;
17
+ role: "product" | "support" | "observer";
18
+ runtime_family: ExecutionTargetRuntimeFamilyV2;
19
+ root_entrypoint: string;
20
+ }
21
+ export interface DeliveryStageV2 {
22
+ key: string;
23
+ title: string;
24
+ depends_on: string[];
25
+ gate_outcome: string;
26
+ }
27
+ 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" | "target_runtime" | "input_variation";
29
+ export interface CheckExecutionTargetV2 {
30
+ target_ref: string;
31
+ entrypoint: "root" | "internal";
32
+ }
33
+ export interface DeliveryScenarioV2 {
34
+ given: KeyedStatementV2[];
35
+ when: KeyedStatementV2[];
36
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare function semanticDriftMigrationFields(value: unknown): string[];
2
+ export declare function semanticDriftOutcomeMigrationFields(value: unknown, label: string): string[];
3
+ export declare function assertNoSemanticDriftMigration(fields: string[]): void;
@@ -0,0 +1,68 @@
1
+ export function semanticDriftMigrationFields(value) {
2
+ const root = row(value);
3
+ if (!root || root.schema_version !== "long-task-delivery-v2")
4
+ return [];
5
+ const missing = [];
6
+ required(root, "$", ["stages"], missing);
7
+ const task = row(root.task);
8
+ if (task) {
9
+ required(task, "task", ["target_profile", "execution_targets"], missing);
10
+ const profile = row(task.target_profile);
11
+ if (profile)
12
+ required(profile, "task.target_profile", ["required_target_refs"], missing);
13
+ }
14
+ for (const [index, outcome] of rows(root.outcomes).entries())
15
+ collectOutcome(outcome, `outcomes[${index}]`, missing);
16
+ const global = row(root.global);
17
+ const globalAcceptance = row(global?.acceptance);
18
+ collectChecks(globalAcceptance?.checks, "global.acceptance.checks", missing);
19
+ for (const [index, confirmation] of rows(globalAcceptance?.external_confirmations).entries())
20
+ required(confirmation, `global.acceptance.external_confirmations[${index}]`, ["kind", "impact_claims", "blocks_target"], missing);
21
+ return [...new Set(missing)].sort();
22
+ }
23
+ export function semanticDriftOutcomeMigrationFields(value, label) {
24
+ const missing = [];
25
+ const outcome = row(value);
26
+ if (outcome)
27
+ collectOutcome(outcome, label, missing);
28
+ return [...new Set(missing)].sort();
29
+ }
30
+ export function assertNoSemanticDriftMigration(fields) {
31
+ if (!fields.length)
32
+ return;
33
+ const detail = fields.slice(0, 24).join(",");
34
+ const suffix = fields.length > 24 ? `,+${fields.length - 24}-more` : "";
35
+ throw new Error(`long_task_delivery_v2_semantic_drift_migration_required:${detail}${suffix}`);
36
+ }
37
+ function collectOutcome(outcome, label, missing) {
38
+ required(outcome, label, ["stage"], missing);
39
+ const product = row(outcome.product);
40
+ if (product)
41
+ required(product, `${label}.product`, ["success_path_required", "degradation_path_required"], missing);
42
+ const acceptance = row(outcome.acceptance);
43
+ collectChecks(acceptance?.checks, `${label}.acceptance.checks`, missing);
44
+ }
45
+ function collectChecks(value, label, missing) {
46
+ for (const [index, check] of rows(value).entries()) {
47
+ const checkLabel = `${label}[${index}]`;
48
+ required(check, checkLabel, ["journey_roles", "execution_target", "scenario"], missing);
49
+ for (const polarity of ["positive_assertions", "negative_assertions"])
50
+ for (const [assertionIndex, assertion] of rows(check[polarity]).entries())
51
+ required(assertion, `${checkLabel}.${polarity}[${assertionIndex}]`, ["evidence_capabilities"], missing);
52
+ }
53
+ }
54
+ function required(value, label, keys, missing) {
55
+ for (const key of keys)
56
+ if (!Object.hasOwn(value, key))
57
+ missing.push(`${label}.${key}`);
58
+ }
59
+ function rows(value) {
60
+ return Array.isArray(value)
61
+ ? value.map(row).filter((item) => item !== null)
62
+ : [];
63
+ }
64
+ function row(value) {
65
+ return value && typeof value === "object" && !Array.isArray(value)
66
+ ? value
67
+ : null;
68
+ }
@@ -3,6 +3,7 @@ export declare function object(value: unknown, label: string, required: string[]
3
3
  export declare function array(value: unknown, label: string): unknown[];
4
4
  export declare function string(value: unknown, label: string): string;
5
5
  export declare function text(value: unknown, label: string): string;
6
+ export declare function boolean(value: unknown, label: string): boolean;
6
7
  export declare function strings(value: unknown, label: string): string[];
7
8
  export declare function repositoryFile(value: unknown, label: string): string;
8
9
  export declare function repositoryFiles(value: unknown, label: string): string[];
@@ -14,4 +15,6 @@ export declare function literal<T extends string>(value: unknown, allowed: reado
14
15
  export declare function key(value: unknown, label: string): string;
15
16
  export declare function nullable<T>(value: unknown, parser: (value: unknown) => T): T | null;
16
17
  export declare const PROOF_SURFACES: readonly ["ui_browser", "runtime_behavior", "api_contract", "data_state", "security_boundary", "population_coverage", "implementation_structure"];
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", "target_runtime", "input_variation"];
17
20
  export declare function fail(label: string, message: string): never;
@@ -27,6 +27,11 @@ export function text(value, label) {
27
27
  fail(label, "must be a string");
28
28
  return value;
29
29
  }
30
+ export function boolean(value, label) {
31
+ if (typeof value !== "boolean")
32
+ fail(label, "must be a boolean");
33
+ return value;
34
+ }
30
35
  export function strings(value, label) {
31
36
  return array(value, label).map((item, index) => string(item, `${label}[${index}]`));
32
37
  }
@@ -76,6 +81,26 @@ export const PROOF_SURFACES = [
76
81
  "population_coverage",
77
82
  "implementation_structure",
78
83
  ];
84
+ export const JOURNEY_ROLES = [
85
+ "success",
86
+ "degradation",
87
+ "recovery",
88
+ "stage_gate",
89
+ "conformance",
90
+ ];
91
+ export const EVIDENCE_CAPABILITIES = [
92
+ "presence",
93
+ "interaction_trace",
94
+ "state_delta",
95
+ "cross_surface_consistency",
96
+ "durable_readback",
97
+ "boundary_invocation",
98
+ "external_side_effect",
99
+ "failure_injection",
100
+ "visual_render",
101
+ "target_runtime",
102
+ "input_variation",
103
+ ];
79
104
  export function fail(label, message) {
80
105
  throw new Error(`delivery_contract_invalid:${label}:${message}`);
81
106
  }
@@ -0,0 +1,4 @@
1
+ import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
2
+ type Reporter = (message: string) => void;
3
+ export declare function validateDeliveryStages(contract: DeliveryContractV2, report?: Reporter): void;
4
+ export {};