project-tiny-context-harness 0.7.9 → 0.8.0

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 (150) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +393 -380
  3. package/assets/README.md +567 -557
  4. package/assets/README.zh-CN.md +339 -326
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +66 -64
  7. package/assets/context_templates/architecture.md +33 -33
  8. package/assets/context_templates/area.md +39 -39
  9. package/assets/context_templates/context.toml +30 -30
  10. package/assets/context_templates/deployment.md +35 -35
  11. package/assets/context_templates/global.md +52 -51
  12. package/assets/context_templates/product-surface-contract.md +70 -70
  13. package/assets/context_templates/screen-contract.md +186 -177
  14. package/assets/context_templates/verification.md +32 -32
  15. package/assets/github/.gitkeep +1 -1
  16. package/assets/github/harness.yml +41 -41
  17. package/assets/make/.gitkeep +1 -1
  18. package/assets/make/ty-context.mk +48 -48
  19. package/assets/skills/context_development_engineer/SKILL.md +135 -131
  20. package/assets/skills/context_full_project_export/SKILL.md +70 -70
  21. package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
  22. package/assets/skills/context_product_plan/SKILL.md +88 -87
  23. package/assets/skills/context_surface_contract/SKILL.md +191 -191
  24. package/assets/skills/context_uiux_design/SKILL.md +158 -154
  25. package/assets/skills/design-resource-authoring/SKILL.md +84 -79
  26. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +136 -108
  27. package/assets/skills/design-resource-authoring/references/open-design-provider.md +133 -127
  28. package/assets/skills/design-resource-authoring/references/resource-selection.md +173 -173
  29. package/assets/skills/design-system-authoring/SKILL.md +57 -57
  30. package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
  31. package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -47
  32. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
  33. package/assets/skills/long-task-workflow/SKILL.md +100 -92
  34. package/assets/skills/long-task-workflow/agents/openai.yaml +4 -4
  35. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +76 -59
  36. package/assets/skills/long-task-workflow/references/contract-authoring.md +116 -105
  37. package/assets/skills/long-task-workflow/references/evidence-design.md +78 -75
  38. package/assets/skills/long-task-workflow/references/source-authoring.md +101 -98
  39. package/assets/skills/normal-long-task/SKILL.md +12 -12
  40. package/assets/skills/source-plan-authoring/SKILL.md +14 -14
  41. package/assets/tools/validate_context.py +442 -442
  42. package/dist/commands/design-resource.d.ts +1 -0
  43. package/dist/commands/design-resource.js +32 -0
  44. package/dist/commands/index.js +4 -0
  45. package/dist/commands/long-task-command-args.d.ts +1 -0
  46. package/dist/commands/long-task-command-args.js +6 -0
  47. package/dist/commands/long-task-revision.js +16 -4
  48. package/dist/commands/long-task.js +12 -5
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/dist/lib/design-md.js +3 -1
  52. package/dist/lib/design-resource-handoff-file-primitives.d.ts +4 -0
  53. package/dist/lib/design-resource-handoff-file-primitives.js +14 -0
  54. package/dist/lib/design-resource-handoff-file-validation.d.ts +2 -0
  55. package/dist/lib/design-resource-handoff-file-validation.js +142 -0
  56. package/dist/lib/design-resource-handoff-parser.d.ts +3 -0
  57. package/dist/lib/design-resource-handoff-parser.js +29 -0
  58. package/dist/lib/design-resource-handoff-policy.d.ts +3 -0
  59. package/dist/lib/design-resource-handoff-policy.js +36 -0
  60. package/dist/lib/design-resource-handoff-shape-evidence.d.ts +4 -0
  61. package/dist/lib/design-resource-handoff-shape-evidence.js +84 -0
  62. package/dist/lib/design-resource-handoff-shape-primitives.d.ts +9 -0
  63. package/dist/lib/design-resource-handoff-shape-primitives.js +44 -0
  64. package/dist/lib/design-resource-handoff-shape-structure.d.ts +5 -0
  65. package/dist/lib/design-resource-handoff-shape-structure.js +118 -0
  66. package/dist/lib/design-resource-handoff-shape.d.ts +2 -0
  67. package/dist/lib/design-resource-handoff-shape.js +75 -0
  68. package/dist/lib/design-resource-handoff-types.d.ts +139 -0
  69. package/dist/lib/design-resource-handoff-types.js +46 -0
  70. package/dist/lib/design-resource-handoff-validation-coverage.d.ts +4 -0
  71. package/dist/lib/design-resource-handoff-validation-coverage.js +168 -0
  72. package/dist/lib/design-resource-handoff-validation-primitives.d.ts +11 -0
  73. package/dist/lib/design-resource-handoff-validation-primitives.js +26 -0
  74. package/dist/lib/design-resource-handoff-validation-structure.d.ts +6 -0
  75. package/dist/lib/design-resource-handoff-validation-structure.js +93 -0
  76. package/dist/lib/design-resource-handoff-validation.d.ts +3 -0
  77. package/dist/lib/design-resource-handoff-validation.js +78 -0
  78. package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +3 -0
  79. package/dist/lib/design-resource-handoff-web-dependency-validation.js +70 -0
  80. package/dist/lib/long-task-activation-validation.js +14 -2
  81. package/dist/lib/long-task-authoring-preflight-diagnostics.js +7 -0
  82. package/dist/lib/long-task-authoring-preflight.js +39 -1
  83. package/dist/lib/long-task-authority-material-diff.js +14 -0
  84. package/dist/lib/long-task-authority-materials.js +21 -0
  85. package/dist/lib/long-task-authority-policy.d.ts +33 -0
  86. package/dist/lib/long-task-authority-policy.js +36 -0
  87. package/dist/lib/long-task-authority-revision-analysis.d.ts +1 -0
  88. package/dist/lib/long-task-authority-revision-analysis.js +30 -0
  89. package/dist/lib/long-task-authority-revision-brief.d.ts +3 -0
  90. package/dist/lib/long-task-authority-revision-brief.js +74 -0
  91. package/dist/lib/long-task-authority-revision-details.js +16 -16
  92. package/dist/lib/long-task-authority-revision-diagnosis.d.ts +1 -1
  93. package/dist/lib/long-task-authority-revision-diagnosis.js +8 -0
  94. package/dist/lib/long-task-authority-revision-enforcement.js +7 -3
  95. package/dist/lib/long-task-authority-revision-summary.d.ts +3 -0
  96. package/dist/lib/long-task-authority-revision-summary.js +133 -21
  97. package/dist/lib/long-task-authority-revision-types.d.ts +19 -1
  98. package/dist/lib/long-task-authority-revision.js +5 -0
  99. package/dist/lib/long-task-authority-types.d.ts +2 -0
  100. package/dist/lib/long-task-authority.js +10 -2
  101. package/dist/lib/long-task-check-execution-policy.js +2 -0
  102. package/dist/lib/long-task-claim-definitions.js +1 -5
  103. package/dist/lib/long-task-contract-types.d.ts +2 -0
  104. package/dist/lib/long-task-counterfactual-sandbox.d.ts +7 -0
  105. package/dist/lib/long-task-counterfactual-sandbox.js +27 -1
  106. package/dist/lib/long-task-delivery-compiler.js +26 -8
  107. package/dist/lib/long-task-delivery-types.d.ts +1 -0
  108. package/dist/lib/long-task-delivery-types.js +1 -0
  109. package/dist/lib/long-task-delivery-validation.js +3 -0
  110. package/dist/lib/long-task-design-resource-handoff.d.ts +2 -0
  111. package/dist/lib/long-task-design-resource-handoff.js +177 -0
  112. package/dist/lib/long-task-evidence-capability-codec.js +19 -0
  113. package/dist/lib/long-task-evidence-capability-policy.js +4 -0
  114. package/dist/lib/long-task-evidence-capability-runtime.js +25 -0
  115. package/dist/lib/long-task-evidence-capability-types.d.ts +9 -1
  116. package/dist/lib/long-task-outcome-parser.js +11 -1
  117. package/dist/lib/long-task-paths.d.ts +0 -1
  118. package/dist/lib/long-task-paths.js +0 -4
  119. package/dist/lib/long-task-playwright-case-evidence.d.ts +43 -0
  120. package/dist/lib/long-task-playwright-case-evidence.js +152 -0
  121. package/dist/lib/long-task-playwright-evidence.js +19 -152
  122. package/dist/lib/long-task-runner-freeze.d.ts +2 -2
  123. package/dist/lib/long-task-runner-freeze.js +2 -1
  124. package/dist/lib/long-task-runtime-types.d.ts +2 -0
  125. package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
  126. package/dist/lib/long-task-semantic-drift-migration.js +6 -1
  127. package/dist/lib/long-task-shape-primitives.d.ts +1 -1
  128. package/dist/lib/long-task-shape-primitives.js +1 -0
  129. package/dist/lib/long-task-status-v2.js +12 -7
  130. package/dist/lib/long-task-ui-design-policy.d.ts +17 -0
  131. package/dist/lib/long-task-ui-design-policy.js +128 -0
  132. package/dist/lib/long-task-ui-surface-policy.d.ts +4 -0
  133. package/dist/lib/long-task-ui-surface-policy.js +109 -0
  134. package/dist/lib/long-task-ui-surface-shape.d.ts +2 -0
  135. package/dist/lib/long-task-ui-surface-shape.js +94 -0
  136. package/dist/lib/long-task-ui-surface-types.d.ts +44 -0
  137. package/dist/lib/long-task-ui-surface-types.js +1 -0
  138. package/dist/lib/long-task-ui-surface-validation.d.ts +11 -0
  139. package/dist/lib/long-task-ui-surface-validation.js +62 -0
  140. package/dist/lib/long-task-verification-preview.d.ts +55 -0
  141. package/dist/lib/long-task-verification-preview.js +120 -0
  142. package/dist/lib/long-task-verifier-v2.js +11 -18
  143. package/dist/lib/long-task-workspace-scope.d.ts +38 -0
  144. package/dist/lib/long-task-workspace-scope.js +121 -0
  145. package/dist/lib/long-task-workspace.d.ts +1 -0
  146. package/dist/lib/long-task-workspace.js +73 -9
  147. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +84 -2
  148. package/migrations/README.md +7 -7
  149. package/package.json +3 -3
  150. package/source-mappings.yaml +25 -25
@@ -0,0 +1,93 @@
1
+ import { invalidDesignResourceHandoff, requireKnownDesignResourceRef, requireNonemptyDesignResourceValues, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
2
+ export function validateDesignResourceScope(handoff) {
3
+ const surfaceStableKeys = new Set(handoff.subjects
4
+ .filter((subject) => subject.kind === "surface")
5
+ .flatMap((subject) => subject.stable_keys));
6
+ for (const surfaceKey of handoff.scope.surface_keys)
7
+ if (!surfaceStableKeys.has(surfaceKey))
8
+ invalidDesignResourceHandoff("scope_surface_subject_missing", surfaceKey);
9
+ }
10
+ export function validateDesignResourceConditions(handoff) {
11
+ for (const condition of handoff.conditions) {
12
+ for (const [name, values] of [
13
+ ["modes", condition.modes],
14
+ ["states", condition.states],
15
+ ["content_cases", condition.content_cases],
16
+ ["input_methods", condition.input_methods],
17
+ ]) {
18
+ requireNonemptyDesignResourceValues(values, `condition_${name}_required:${condition.key}`);
19
+ requireUniqueDesignResourceValues(values, `condition_${name}_duplicate:${condition.key}`);
20
+ }
21
+ }
22
+ }
23
+ export function validateDesignResourceSubjects(handoff, targets) {
24
+ const stableKeys = new Set();
25
+ for (const subject of handoff.subjects) {
26
+ requireNonemptyDesignResourceValues(subject.stable_keys, `subject_stable_keys_required:${subject.key}`);
27
+ requireUniqueDesignResourceValues(subject.stable_keys, `subject_stable_key_duplicate:${subject.key}`);
28
+ requireNonemptyDesignResourceValues(subject.target_refs, `subject_target_refs_required:${subject.key}`);
29
+ requireUniqueDesignResourceValues(subject.target_refs, `subject_target_ref_duplicate:${subject.key}`);
30
+ for (const ref of subject.target_refs)
31
+ requireKnownDesignResourceRef(targets, ref, "target");
32
+ for (const stableKey of subject.stable_keys) {
33
+ if (stableKeys.has(stableKey))
34
+ invalidDesignResourceHandoff("subject_stable_key_ambiguous", stableKey);
35
+ stableKeys.add(stableKey);
36
+ }
37
+ }
38
+ }
39
+ export function validateDesignResourceTargets(handoff, resources, conditions) {
40
+ for (const target of handoff.targets) {
41
+ requireNonemptyDesignResourceValues(target.resource_refs, `target_resource_refs_required:${target.key}`);
42
+ requireNonemptyDesignResourceValues(target.condition_refs, `target_condition_refs_required:${target.key}`);
43
+ requireUniqueDesignResourceValues(target.resource_refs, `target_resource_ref_duplicate:${target.key}`);
44
+ requireUniqueDesignResourceValues(target.condition_refs, `target_condition_ref_duplicate:${target.key}`);
45
+ for (const ref of target.resource_refs)
46
+ requireKnownDesignResourceRef(resources, ref, "resource");
47
+ for (const ref of target.condition_refs)
48
+ requireKnownDesignResourceRef(conditions, ref, "condition");
49
+ validateTargetSourceProfile(target, resources);
50
+ const expectedRole = target.interpretation === "exact_target" ? "exact_target" : "constraint";
51
+ if (!target.resource_refs.some((ref) => resources.get(ref)?.role === expectedRole))
52
+ invalidDesignResourceHandoff("target_interpretation_resource_role_missing", `${target.key}:${expectedRole}`);
53
+ }
54
+ }
55
+ function validateTargetSourceProfile(target, resources) {
56
+ const profile = target.source_profile;
57
+ requireKnownDesignResourceRef(resources, profile.entry_resource_ref, "source_profile_entry_resource");
58
+ requireUniqueDesignResourceValues(profile.dependency_resource_refs, `source_profile_dependency_resource_ref_duplicate:${target.key}`);
59
+ for (const ref of profile.dependency_resource_refs)
60
+ requireKnownDesignResourceRef(resources, ref, "source_profile_dependency_resource");
61
+ if (profile.dependency_resource_refs.includes(profile.entry_resource_ref))
62
+ invalidDesignResourceHandoff("source_profile_entry_repeated_as_dependency", target.key);
63
+ const declared = [
64
+ profile.entry_resource_ref,
65
+ ...profile.dependency_resource_refs,
66
+ ].sort();
67
+ const targetResources = [...target.resource_refs].sort();
68
+ if (declared.length !== targetResources.length ||
69
+ declared.some((ref, index) => ref !== targetResources[index]))
70
+ invalidDesignResourceHandoff("source_profile_resource_closure_mismatch", target.key);
71
+ const entry = resources.get(profile.entry_resource_ref);
72
+ if (profile.kind === "implementation_web" &&
73
+ !["text/html", "application/xhtml+xml"].includes(entry.media_type))
74
+ invalidDesignResourceHandoff("implementation_web_entry_media_type_invalid", `${target.key}:${entry.media_type}`);
75
+ if (profile.kind === "implementation_app" &&
76
+ !(entry.media_type.startsWith("text/") ||
77
+ [
78
+ "application/json",
79
+ "application/javascript",
80
+ "application/yaml",
81
+ "application/x-yaml",
82
+ ].includes(entry.media_type)))
83
+ invalidDesignResourceHandoff("implementation_app_entry_media_type_invalid", `${target.key}:${entry.media_type}`);
84
+ }
85
+ export function validateDesignResourceEvidence(handoff, resources, conditions) {
86
+ for (const item of handoff.evidence) {
87
+ requireKnownDesignResourceRef(resources, item.resource_ref, "resource");
88
+ requireNonemptyDesignResourceValues(item.condition_refs, `evidence_condition_refs_required:${item.key}`);
89
+ requireUniqueDesignResourceValues(item.condition_refs, `evidence_condition_ref_duplicate:${item.key}`);
90
+ for (const ref of item.condition_refs)
91
+ requireKnownDesignResourceRef(conditions, ref, "condition");
92
+ }
93
+ }
@@ -0,0 +1,3 @@
1
+ import type { DesignResourceHandoffPreflightV1, ParsedDesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
2
+ export declare function preflightDesignResourceHandoff(repository: string, handoffPath: string): Promise<DesignResourceHandoffPreflightV1>;
3
+ export declare function validateDesignResourceHandoffSemantics(parsed: ParsedDesignResourceHandoffV1): void;
@@ -0,0 +1,78 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { parseDesignResourceHandoffMarkdown } from "./design-resource-handoff-parser.js";
4
+ import { validateDesignResourceFiles } from "./design-resource-handoff-file-validation.js";
5
+ import { validateDesignResourceBlockers, validateDesignResourceCoverage, validateDesignResourceReachability, } from "./design-resource-handoff-validation-coverage.js";
6
+ import { indexDesignResourceItems, invalidDesignResourceHandoff, requireNonemptyDesignResourceValues, requireUniqueDesignResourceObjects, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
7
+ import { validateDesignResourceConditions, validateDesignResourceEvidence, validateDesignResourceScope, validateDesignResourceSubjects, validateDesignResourceTargets, } from "./design-resource-handoff-validation-structure.js";
8
+ import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
9
+ import { sha256Hex } from "./strict-codec.js";
10
+ export async function preflightDesignResourceHandoff(repository, handoffPath) {
11
+ const handoffFile = await assertProtectedRepositoryFile(repository, path.resolve(repository, ...handoffPath.split("/")), "design_resource_handoff");
12
+ const parsed = parseDesignResourceHandoffMarkdown(handoffPath, await readFile(handoffFile, "utf8"));
13
+ validateDesignResourceHandoffSemantics(parsed);
14
+ const resourceHashes = await validateResourceIntegrity(repository, parsed);
15
+ await validateDesignResourceFiles(repository, parsed);
16
+ const handoff = parsed.handoff;
17
+ return {
18
+ schema_version: "design-resource-handoff-preflight-v1",
19
+ status: "ready",
20
+ ...parsed,
21
+ resource_hashes: resourceHashes,
22
+ counts: {
23
+ resources: handoff.resources.length,
24
+ conditions: handoff.conditions.length,
25
+ subjects: handoff.subjects.length,
26
+ targets: handoff.targets.length,
27
+ evidence: handoff.evidence.length,
28
+ coverage: handoff.coverage.length,
29
+ acceptance_blockers: handoff.acceptance_blockers.length,
30
+ },
31
+ };
32
+ }
33
+ export function validateDesignResourceHandoffSemantics(parsed) {
34
+ const { handoff } = parsed;
35
+ requireNonemptyDesignResourceValues(handoff.scope.surface_keys, "scope_surface_keys_required");
36
+ requireNonemptyDesignResourceValues(handoff.resources, "resources_required");
37
+ requireNonemptyDesignResourceValues(handoff.conditions, "conditions_required");
38
+ requireNonemptyDesignResourceValues(handoff.subjects, "subjects_required");
39
+ requireNonemptyDesignResourceValues(handoff.targets, "targets_required");
40
+ requireNonemptyDesignResourceValues(handoff.evidence, "evidence_required");
41
+ requireNonemptyDesignResourceValues(handoff.coverage, "coverage_required");
42
+ requireUniqueDesignResourceValues(handoff.scope.surface_keys, "scope_surface_key_duplicate");
43
+ requireUniqueDesignResourceObjects(handoff.resources, "resource_key_duplicate");
44
+ requireUniqueDesignResourceValues(handoff.resources.map((item) => item.path), "resource_path_duplicate");
45
+ requireUniqueDesignResourceObjects(handoff.conditions, "condition_key_duplicate");
46
+ requireUniqueDesignResourceObjects(handoff.subjects, "subject_key_duplicate");
47
+ requireUniqueDesignResourceObjects(handoff.targets, "target_key_duplicate");
48
+ requireUniqueDesignResourceObjects(handoff.evidence, "evidence_key_duplicate");
49
+ requireUniqueDesignResourceObjects(handoff.coverage, "coverage_key_duplicate");
50
+ requireUniqueDesignResourceObjects(handoff.acceptance_blockers, "acceptance_blocker_key_duplicate");
51
+ const resources = indexDesignResourceItems(handoff.resources);
52
+ const conditions = indexDesignResourceItems(handoff.conditions);
53
+ const subjects = indexDesignResourceItems(handoff.subjects);
54
+ const targets = indexDesignResourceItems(handoff.targets);
55
+ const evidence = indexDesignResourceItems(handoff.evidence);
56
+ const sourceItems = new Map(Object.entries(parsed.source_item_kinds));
57
+ validateDesignResourceScope(handoff);
58
+ validateDesignResourceConditions(handoff);
59
+ validateDesignResourceSubjects(handoff, targets);
60
+ validateDesignResourceTargets(handoff, resources, conditions);
61
+ validateDesignResourceEvidence(handoff, resources, conditions);
62
+ validateDesignResourceCoverage(handoff, subjects, targets, conditions, evidence, sourceItems);
63
+ validateDesignResourceBlockers(handoff, subjects, targets, sourceItems);
64
+ validateDesignResourceReachability(handoff);
65
+ }
66
+ async function validateResourceIntegrity(repository, parsed) {
67
+ const hashes = {};
68
+ for (const resource of parsed.handoff.resources) {
69
+ if (resource.path === parsed.handoff_path)
70
+ invalidDesignResourceHandoff("resource_must_not_be_handoff", resource.key);
71
+ const file = await assertProtectedRepositoryFile(repository, path.resolve(repository, ...resource.path.split("/")), `design_resource:${resource.key}`);
72
+ const digest = sha256Hex(await readFile(file));
73
+ if (digest !== resource.sha256)
74
+ invalidDesignResourceHandoff("resource_digest_mismatch", `${resource.key}:${resource.sha256}:${digest}`);
75
+ hashes[resource.key] = digest;
76
+ }
77
+ return hashes;
78
+ }
@@ -0,0 +1,3 @@
1
+ import type { ParsedDesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
2
+ import { type DesignResource } from "./design-resource-handoff-file-primitives.js";
3
+ export declare function validateDesignResourceWebDependencyClosure(target: ParsedDesignResourceHandoffV1["handoff"]["targets"][number], resources: Map<string, DesignResource>, contents: Map<string, Buffer>): void;
@@ -0,0 +1,70 @@
1
+ import path from "node:path";
2
+ import { htmlAttributes, isTextResource, } from "./design-resource-handoff-file-primitives.js";
3
+ import { invalidDesignResourceHandoff } from "./design-resource-handoff-validation-primitives.js";
4
+ export function validateDesignResourceWebDependencyClosure(target, resources, contents) {
5
+ const declaredPaths = new Set(target.resource_refs.map((ref) => resources.get(ref).path));
6
+ for (const resourceRef of target.resource_refs) {
7
+ const resource = resources.get(resourceRef);
8
+ if (!isTextResource(resource))
9
+ continue;
10
+ const content = contents.get(resourceRef).toString("utf8");
11
+ for (const reference of localDependencyReferences(content, resource.media_type)) {
12
+ const resolved = resolveResourceReference(resource.path, reference);
13
+ if (!declaredPaths.has(resolved))
14
+ invalidDesignResourceHandoff("implementation_dependency_undeclared", `${target.key}:${resource.path}:${reference}:${resolved}`);
15
+ }
16
+ }
17
+ }
18
+ function localDependencyReferences(content, mediaType) {
19
+ const values = new Set();
20
+ if (["text/html", "application/xhtml+xml"].includes(mediaType)) {
21
+ for (const tag of content.matchAll(/<(script|img|source|video|audio|track|iframe|embed|input|link|object|use|image)\b([^<>]*)>/giu)) {
22
+ const attributes = htmlAttributes(tag[2]);
23
+ for (const name of ["src", "href", "poster"])
24
+ addLocalReference(values, attributes.get(name));
25
+ if (tag[1].toLowerCase() === "object")
26
+ addLocalReference(values, attributes.get("data"));
27
+ for (const candidate of (attributes.get("srcset") ?? "").split(","))
28
+ addLocalReference(values, candidate.trim().split(/\s+/u)[0]);
29
+ }
30
+ }
31
+ if (mediaType === "text/css" ||
32
+ ["text/html", "application/xhtml+xml"].includes(mediaType))
33
+ for (const match of content.matchAll(/(?:url\(\s*["']?([^"')\s]+)|@import\s+(?:url\(\s*)?["']([^"']+))/giu))
34
+ addLocalReference(values, match[1] ?? match[2]);
35
+ if ([
36
+ "text/javascript",
37
+ "application/javascript",
38
+ "text/typescript",
39
+ "application/typescript",
40
+ "text/ecmascript",
41
+ "application/ecmascript",
42
+ "text/html",
43
+ ].includes(mediaType)) {
44
+ for (const match of content.matchAll(/(?:\b(?:from|import)\s*|\bimport\s*\(|\brequire\s*\()\s*["']([^"']+)["']/gu))
45
+ addLocalReference(values, match[1]);
46
+ for (const match of content.matchAll(/(?:\bfetch\s*\(|\bnew\s+(?:Shared)?Worker\s*\(|\bnew\s+URL\s*\()\s*["']([^"']+)["']/gu))
47
+ addLocalReference(values, match[1]);
48
+ }
49
+ return values;
50
+ }
51
+ function addLocalReference(values, raw) {
52
+ if (!raw)
53
+ return;
54
+ const value = raw.trim();
55
+ if (!value ||
56
+ value.startsWith("#") ||
57
+ /^(?:[a-z][a-z0-9+.-]*:|\/\/)/iu.test(value))
58
+ return;
59
+ values.add(value.replace(/[?#].*$/u, ""));
60
+ }
61
+ function resolveResourceReference(from, reference) {
62
+ if (reference.startsWith("/"))
63
+ invalidDesignResourceHandoff("implementation_dependency_path_unsafe", `${from}:${reference}`);
64
+ const resolved = path.posix.normalize(path.posix.join(path.posix.dirname(from), reference));
65
+ if (resolved === ".." ||
66
+ resolved.startsWith("../") ||
67
+ path.posix.isAbsolute(resolved))
68
+ invalidDesignResourceHandoff("implementation_dependency_path_unsafe", `${from}:${reference}`);
69
+ return resolved;
70
+ }
@@ -6,6 +6,7 @@ import { validateClaimEvidenceSensitivity } from "./long-task-evidence-sensitivi
6
6
  import { validateSemanticConformance } from "./long-task-conformance-policy.js";
7
7
  import { deliveryContractStructureDiagnostics, validateDeliveryContractStructure, } from "./long-task-delivery-validation.js";
8
8
  import { validateRawExecutionObservationOwnership } from "./long-task-observation-ownership.js";
9
+ import { validateLongTaskDesignResourceHandoffs } from "./long-task-design-resource-handoff.js";
9
10
  import { freezeDeliveryCheck } from "./long-task-runner-freeze.js";
10
11
  import { classifyLongTaskRisk, validateRiskProof, } from "./long-task-risk.js";
11
12
  import { validateSourceContinuity } from "./long-task-source-continuity.js";
@@ -41,6 +42,7 @@ export async function validateContractForActivation(options) {
41
42
  : undefined);
42
43
  return items;
43
44
  });
45
+ await attempt(mode, diagnostics, () => validateLongTaskDesignResourceHandoffs(contract, repository));
44
46
  const risk = await attempt(mode, diagnostics, () => {
45
47
  const decision = classifyLongTaskRisk(contract);
46
48
  validateRiskProof(contract, decision);
@@ -60,7 +62,7 @@ export async function validateContractForActivation(options) {
60
62
  const executionTarget = contract.task.execution_targets.find((target) => target.key === check.execution_target.target_ref);
61
63
  if (!executionTarget)
62
64
  continue;
63
- const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, null, repository, workspace, executionTarget, contract.task.execution_targets), null, check.key);
65
+ const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, null, repository, workspace, executionTarget, contract.task.execution_targets, []), null, check.key);
64
66
  if (frozen)
65
67
  globalChecks.push(frozen);
66
68
  }
@@ -71,7 +73,7 @@ export async function validateContractForActivation(options) {
71
73
  const executionTarget = contract.task.execution_targets.find((target) => target.key === check.execution_target.target_ref);
72
74
  if (!executionTarget)
73
75
  continue;
74
- const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets), outcome.key, check.key);
76
+ const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets, designTargetsForCheck(outcome, check.key)), outcome.key, check.key);
75
77
  if (frozen)
76
78
  checks.push(frozen);
77
79
  }
@@ -114,6 +116,16 @@ export async function validateContractForActivation(options) {
114
116
  outcomes,
115
117
  };
116
118
  }
119
+ function designTargetsForCheck(outcome, checkKey) {
120
+ return (outcome.product.surface_bindings ?? []).flatMap((binding) => binding.design_targets
121
+ .filter((target) => target.conformance_check_ref === checkKey)
122
+ .map((target) => ({
123
+ ...target,
124
+ surface_binding_ref: binding.key,
125
+ surface_ref: binding.surface_ref,
126
+ target_ref: binding.target_ref,
127
+ })));
128
+ }
117
129
  async function attempt(mode, diagnostics, action, outcomeKey, checkKey) {
118
130
  try {
119
131
  return await action();
@@ -140,6 +140,9 @@ function diagnosticRefs(code, message) {
140
140
  return payload.slice(0, 2);
141
141
  case "owner_path_globs_empty":
142
142
  return payload.slice(0, 1);
143
+ case "workspace_path_forbidden":
144
+ case "workspace_path_unclassified":
145
+ return payload.slice(0, 1);
143
146
  case "product_claim_uncovered":
144
147
  case "global_claim_uncovered":
145
148
  case "source_claim_decision_required":
@@ -171,6 +174,10 @@ function diagnosticRepairHint(code) {
171
174
  return "Correct source_ref or add the matching non-rendering Source marker/anchor without rewriting the Source statement.";
172
175
  case "source_claim_decision_required":
173
176
  return "Resolve the stated product decision from the user or authoritative Source before Compile.";
177
+ case "workspace_path_forbidden":
178
+ return "Revert or relocate the forbidden workspace change, or revise the owning Source/Contract boundary through the appropriate authority path.";
179
+ case "workspace_path_unclassified":
180
+ return "Declare the file under the owning Outcome's expected_change_paths or allowed_support_paths, or remove the unrelated workspace change before Compile.";
174
181
  default:
175
182
  if (code.endsWith("_path_not_found"))
176
183
  return "Create or correct the declared repository path, runner target or Binding carrier, then rerun Preflight.";
@@ -4,7 +4,8 @@ import { addAuthoringDiagnostics, addDiagnosticError, normalizeAuthoringDiagnost
4
4
  import { emptyClaimCoverage, emptyPreflightResult, } from "./long-task-authoring-preflight-types.js";
5
5
  import { validateContractForActivation } from "./long-task-activation-validation.js";
6
6
  import { parseDeliveryContractBundle } from "./long-task-delivery-parser.js";
7
- import { repositoryRoot } from "./long-task-workspace.js";
7
+ import { changedWorkspacePaths, changedWorkspacePathsFromHead, repoRelative, repositoryRoot, } from "./long-task-workspace.js";
8
+ import { classifyWorkspaceScope, firstLockManagedWorkspacePaths, protectedWorkspacePaths, workspaceScopeErrors, } from "./long-task-workspace-scope.js";
8
9
  export async function preflightDeliveryContract(workdirInput, projectRootInput = process.cwd()) {
9
10
  const diagnostics = [];
10
11
  const repository = await repositoryRoot(projectRootInput);
@@ -29,6 +30,43 @@ export async function preflightDeliveryContract(workdirInput, projectRootInput =
29
30
  diagnostics,
30
31
  });
31
32
  const active = await loadAuthoringActiveAuthority(repository, workdir, diagnostics);
33
+ if (validation.workspace)
34
+ try {
35
+ const changedPaths = active?.workdir === workdir
36
+ ? changedWorkspacePaths(active.initial_task_base.workspace_manifest, validation.workspace)
37
+ : await changedWorkspacePathsFromHead(repository, workdir);
38
+ const contractFiles = Object.fromEntries(Object.entries(parsed.contract_files).map(([relative, hash]) => [
39
+ repoRelative(repository, path.join(workdir, ...relative.split("/"))),
40
+ hash,
41
+ ]));
42
+ const checks = [
43
+ ...validation.global_checks,
44
+ ...validation.outcomes.flatMap((outcome) => outcome.acceptance.checks),
45
+ ];
46
+ const declaredVerificationInputs = [
47
+ ...contract.global.acceptance.checks,
48
+ ...contract.outcomes.flatMap((outcome) => outcome.acceptance.checks),
49
+ ].flatMap((check) => check.verification_inputs);
50
+ const firstLockManagedPaths = active?.workdir === workdir
51
+ ? []
52
+ : await firstLockManagedWorkspacePaths(repository, changedPaths);
53
+ const classification = classifyWorkspaceScope(contract, changedPaths, protectedWorkspacePaths({
54
+ contract_files: contractFiles,
55
+ source_hashes: validation.source_hashes,
56
+ context_hashes: validation.context_snapshot?.sha256,
57
+ checks,
58
+ additional_files: [
59
+ ...contract.task.source_paths,
60
+ ...declaredVerificationInputs,
61
+ ...firstLockManagedPaths,
62
+ ],
63
+ }));
64
+ for (const error of workspaceScopeErrors(classification))
65
+ addDiagnosticError(diagnostics, new Error(error));
66
+ }
67
+ catch (error) {
68
+ addDiagnosticError(diagnostics, error);
69
+ }
32
70
  const normalizedDiagnostics = normalizeAuthoringDiagnostics(diagnostics);
33
71
  const ready = !normalizedDiagnostics.some((item) => item.level === "error" || item.level === "decision_required");
34
72
  return {
@@ -168,6 +168,20 @@ function flattenProductSemantics(projection) {
168
168
  "accessibility",
169
169
  ])
170
170
  fields.set(`${prefix}.controls.${control.key}.${field}`, control[field]);
171
+ for (const binding of outcome.surface_bindings ?? []) {
172
+ const bindingPrefix = `${prefix}.surface_bindings.${binding.key}`;
173
+ fields.set(`${bindingPrefix}.surface_ref`, binding.surface_ref);
174
+ fields.set(`${bindingPrefix}.target_ref`, binding.target_ref);
175
+ fields.set(`${bindingPrefix}.control_refs`, binding.control_refs);
176
+ fields.set(`${bindingPrefix}.route_binding_ref`, binding.route_binding_ref);
177
+ fields.set(`${bindingPrefix}.component_binding_refs`, binding.component_binding_refs);
178
+ fields.set(`${bindingPrefix}.root_journey_check_ref`, binding.root_journey_check_ref);
179
+ fields.set(`${bindingPrefix}.entry_action_ref`, binding.entry_action_ref);
180
+ for (const target of binding.design_targets)
181
+ fields.set(`${bindingPrefix}.design_targets.${target.key}`, target);
182
+ for (const blocker of binding.acceptance_blockers)
183
+ fields.set(`${bindingPrefix}.acceptance_blockers.${blocker.key}`, blocker);
184
+ }
171
185
  for (const item of outcome.non_completing_outcomes)
172
186
  fields.set(`${prefix}.non_completing.${item.key}`, item.statement);
173
187
  }
@@ -77,6 +77,27 @@ export function projectProductSemantics(contract) {
77
77
  feedback: control.feedback,
78
78
  accessibility: control.accessibility,
79
79
  })),
80
+ surface_bindings: [...(outcome.product.surface_bindings ?? [])]
81
+ .sort(keyOrder)
82
+ .map((binding) => ({
83
+ ...binding,
84
+ control_refs: [...binding.control_refs].sort(),
85
+ component_binding_refs: [...binding.component_binding_refs].sort(),
86
+ design_targets: [...binding.design_targets]
87
+ .sort(keyOrder)
88
+ .map((target) => ({
89
+ ...target,
90
+ source_paths: [...target.source_paths].sort(),
91
+ condition_keys: [...target.condition_keys].sort(),
92
+ claim_refs: [...target.claim_refs].sort(),
93
+ })),
94
+ acceptance_blockers: [...binding.acceptance_blockers]
95
+ .sort(keyOrder)
96
+ .map((blocker) => ({
97
+ ...blocker,
98
+ refs: [...blocker.refs].sort(),
99
+ })),
100
+ })),
80
101
  non_completing_outcomes: keyedStatements(outcome.product.non_completing_outcomes),
81
102
  })),
82
103
  };
@@ -65,6 +65,7 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
65
65
  requirements: "semantic_user_review";
66
66
  owner_surfaces: "semantic_user_review";
67
67
  controls: "semantic_user_review";
68
+ surface_bindings: "semantic_user_review";
68
69
  non_completing_outcomes: "semantic_user_review";
69
70
  };
70
71
  readonly requirement: {
@@ -102,6 +103,38 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
102
103
  feedback: "semantic_user_review";
103
104
  accessibility: "semantic_user_review";
104
105
  };
106
+ readonly surface_binding: {
107
+ key: "identity";
108
+ surface_ref: "semantic_user_review";
109
+ target_ref: "semantic_user_review";
110
+ control_refs: "semantic_user_review";
111
+ route_binding_ref: "semantic_user_review";
112
+ component_binding_refs: "semantic_user_review";
113
+ root_journey_check_ref: "proof_additive";
114
+ entry_action_ref: "proof_additive";
115
+ design_targets: "semantic_user_review";
116
+ acceptance_blockers: "semantic_user_review";
117
+ };
118
+ readonly design_target: {
119
+ key: "identity";
120
+ interpretation: "semantic_user_review";
121
+ source_paths: "scope";
122
+ condition_keys: "semantic_user_review";
123
+ claim_refs: "proof_additive";
124
+ conformance_check_ref: "proof_additive";
125
+ conformance_assertion_ref: "proof_additive";
126
+ verification_method_bindings: "proof_additive";
127
+ actual_artifact_path: "output_requirement";
128
+ comparison_artifact_path: "output_requirement";
129
+ };
130
+ readonly design_blocker: {
131
+ key: "identity";
132
+ status: "semantic_user_review";
133
+ refs: "semantic_user_review";
134
+ source_item_refs: "semantic_user_review";
135
+ verification_methods: "proof_additive";
136
+ rationale: "semantic_user_review";
137
+ };
105
138
  readonly outcome_technical: {
106
139
  obligations: "semantic_user_review";
107
140
  expected_change_paths: "scope";
@@ -48,6 +48,7 @@ const OUTCOME_PRODUCT_AUTHORITY_POLICY = {
48
48
  requirements: "semantic_user_review",
49
49
  owner_surfaces: "semantic_user_review",
50
50
  controls: "semantic_user_review",
51
+ surface_bindings: "semantic_user_review",
51
52
  non_completing_outcomes: "semantic_user_review",
52
53
  };
53
54
  const REQUIREMENT_AUTHORITY_POLICY = {
@@ -85,6 +86,38 @@ const CONTROL_AUTHORITY_POLICY = {
85
86
  feedback: "semantic_user_review",
86
87
  accessibility: "semantic_user_review",
87
88
  };
89
+ const SURFACE_BINDING_AUTHORITY_POLICY = {
90
+ key: "identity",
91
+ surface_ref: "semantic_user_review",
92
+ target_ref: "semantic_user_review",
93
+ control_refs: "semantic_user_review",
94
+ route_binding_ref: "semantic_user_review",
95
+ component_binding_refs: "semantic_user_review",
96
+ root_journey_check_ref: "proof_additive",
97
+ entry_action_ref: "proof_additive",
98
+ design_targets: "semantic_user_review",
99
+ acceptance_blockers: "semantic_user_review",
100
+ };
101
+ const DESIGN_TARGET_AUTHORITY_POLICY = {
102
+ key: "identity",
103
+ interpretation: "semantic_user_review",
104
+ source_paths: "scope",
105
+ condition_keys: "semantic_user_review",
106
+ claim_refs: "proof_additive",
107
+ conformance_check_ref: "proof_additive",
108
+ conformance_assertion_ref: "proof_additive",
109
+ verification_method_bindings: "proof_additive",
110
+ actual_artifact_path: "output_requirement",
111
+ comparison_artifact_path: "output_requirement",
112
+ };
113
+ const DESIGN_BLOCKER_AUTHORITY_POLICY = {
114
+ key: "identity",
115
+ status: "semantic_user_review",
116
+ refs: "semantic_user_review",
117
+ source_item_refs: "semantic_user_review",
118
+ verification_methods: "proof_additive",
119
+ rationale: "semantic_user_review",
120
+ };
88
121
  const OUTCOME_TECHNICAL_AUTHORITY_POLICY = {
89
122
  obligations: "semantic_user_review",
90
123
  expected_change_paths: "scope",
@@ -185,6 +218,9 @@ export const AUTHORITY_FIELD_POLICY_REGISTRIES = {
185
218
  requirement: REQUIREMENT_AUTHORITY_POLICY,
186
219
  owner: OWNER_AUTHORITY_POLICY,
187
220
  control: CONTROL_AUTHORITY_POLICY,
221
+ surface_binding: SURFACE_BINDING_AUTHORITY_POLICY,
222
+ design_target: DESIGN_TARGET_AUTHORITY_POLICY,
223
+ design_blocker: DESIGN_BLOCKER_AUTHORITY_POLICY,
188
224
  outcome_technical: OUTCOME_TECHNICAL_AUTHORITY_POLICY,
189
225
  obligation: OBLIGATION_AUTHORITY_POLICY,
190
226
  binding: BINDING_AUTHORITY_POLICY,
@@ -1,6 +1,7 @@
1
1
  import type { CompiledCheckV2, CompiledDeliveryContractV2, DeliveryContractV2 } from "./long-task-delivery-types.js";
2
2
  export interface CheckRevisionAnalysis {
3
3
  negative_assertions_removed: string[];
4
+ acceptance_semantics_reduced: string[];
4
5
  proof_surfaces_changed: string[];
5
6
  runner_definitions_changed: string[];
6
7
  verification_inputs_added: string[];
@@ -2,6 +2,7 @@ import { addedInputPaths, addedVerificationInputs, bindingReductions, changedRun
2
2
  export function analyzeCheckRevisions(beforeChecks, afterChecks) {
3
3
  const result = {
4
4
  negative_assertions_removed: [],
5
+ acceptance_semantics_reduced: [],
5
6
  proof_surfaces_changed: [],
6
7
  runner_definitions_changed: [],
7
8
  verification_inputs_added: [],
@@ -19,6 +20,12 @@ export function analyzeCheckRevisions(beforeChecks, afterChecks) {
19
20
  for (const assertion of before.negative_assertions)
20
21
  if (!after.negative_assertions.some((item) => same(item, assertion)))
21
22
  result.negative_assertions_removed.push(`${identity}:${assertion.key}`);
23
+ if (!same(before.execution_target, after.execution_target))
24
+ result.acceptance_semantics_reduced.push(`${identity}:execution_target`);
25
+ collectRemovedValues(result.acceptance_semantics_reduced, `${identity}:journey_role`, before.journey_roles, after.journey_roles);
26
+ collectRemovedValues(result.acceptance_semantics_reduced, `${identity}:scenario.given`, before.scenario.given, after.scenario.given);
27
+ collectRemovedValues(result.acceptance_semantics_reduced, `${identity}:scenario.when`, before.scenario.when, after.scenario.when);
28
+ collectAssertionReductions(result.acceptance_semantics_reduced, identity, before.positive_assertions, after.positive_assertions);
22
29
  if (before.proof_surface !== after.proof_surface)
23
30
  result.proof_surfaces_changed.push(`${identity}:${before.proof_surface}->${after.proof_surface}`);
24
31
  result.runner_definitions_changed.push(...changedRunnerFields(identity, before, after));
@@ -32,6 +39,29 @@ export function analyzeCheckRevisions(beforeChecks, afterChecks) {
32
39
  }
33
40
  return result;
34
41
  }
42
+ function collectRemovedValues(result, prefix, before, after) {
43
+ for (const value of before)
44
+ if (!after.some((candidate) => same(candidate, value)))
45
+ result.push(`${prefix}:${String(value)}`);
46
+ }
47
+ function collectAssertionReductions(result, identity, before, after) {
48
+ const next = new Map(after.map((assertion) => [assertion.key, assertion]));
49
+ for (const assertion of before) {
50
+ const candidate = next.get(assertion.key);
51
+ if (!candidate) {
52
+ result.push(`${identity}:positive_assertion.${assertion.key}:removed`);
53
+ continue;
54
+ }
55
+ const semanticChanged = assertion.criterion !== candidate.criterion ||
56
+ !same(assertion.claims, candidate.claims) ||
57
+ assertion.observation !== candidate.observation ||
58
+ assertion.operator !== candidate.operator ||
59
+ !same(assertion.expected, candidate.expected);
60
+ const capabilityRemoved = assertion.evidence_capabilities.some((capability) => !candidate.evidence_capabilities.includes(capability));
61
+ if (semanticChanged || capabilityRemoved)
62
+ result.push(`${identity}:positive_assertion.${assertion.key}:changed`);
63
+ }
64
+ }
35
65
  export function analyzeOutcomeRevisions(previous, next) {
36
66
  const result = {
37
67
  owner_paths_expanded: [],
@@ -0,0 +1,3 @@
1
+ import type { AuthorityRevisionApprovalSummaryV2, AuthorityRevisionChangeClassV2, AuthorityRevisionDecisionBriefV2, AuthorityRevisionDecisionV2 } from "./long-task-authority-revision-types.js";
2
+ export declare function authorityRevisionDecisionNextAction(decision: AuthorityRevisionDecisionV2): string;
3
+ export declare function buildAuthorityRevisionDecisionBrief(summary: AuthorityRevisionApprovalSummaryV2, changeClass: AuthorityRevisionChangeClassV2, approvalRequired: boolean): AuthorityRevisionDecisionBriefV2;