project-tiny-context-harness 0.8.7 → 0.8.10

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 (57) hide show
  1. package/README.md +146 -118
  2. package/assets/README.md +276 -246
  3. package/assets/README.zh-CN.md +169 -137
  4. package/assets/agents/AGENTS_CORE.md +8 -6
  5. package/assets/context_templates/architecture.md +10 -7
  6. package/assets/context_templates/verification.md +7 -5
  7. package/assets/skills/context_development_engineer/SKILL.md +37 -24
  8. package/assets/skills/design-resource-authoring/SKILL.md +12 -12
  9. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +57 -48
  10. package/assets/skills/long-task-workflow/SKILL.md +8 -6
  11. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +1 -1
  12. package/assets/skills/long-task-workflow/references/contract-authoring.md +13 -11
  13. package/dist/commands/check-modularity.js +16 -3
  14. package/dist/commands/design-resource.js +62 -2
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +1 -0
  17. package/dist/lib/design-resource-fact-manifest-validation.d.ts +3 -2
  18. package/dist/lib/design-resource-fact-manifest-validation.js +23 -18
  19. package/dist/lib/design-resource-fact-universe-catalog.js +18 -8
  20. package/dist/lib/design-resource-fact-universe-helpers.js +9 -5
  21. package/dist/lib/design-resource-handoff-bundle.d.ts +31 -0
  22. package/dist/lib/design-resource-handoff-bundle.js +171 -0
  23. package/dist/lib/design-resource-handoff-file-validation.d.ts +1 -1
  24. package/dist/lib/design-resource-handoff-file-validation.js +1 -9
  25. package/dist/lib/design-resource-handoff-manifest-projection.d.ts +3 -0
  26. package/dist/lib/design-resource-handoff-manifest-projection.js +37 -0
  27. package/dist/lib/design-resource-handoff-parser.d.ts +7 -2
  28. package/dist/lib/design-resource-handoff-parser.js +32 -12
  29. package/dist/lib/design-resource-handoff-set-integrity.d.ts +8 -0
  30. package/dist/lib/design-resource-handoff-set-integrity.js +93 -0
  31. package/dist/lib/design-resource-handoff-shape.d.ts +2 -1
  32. package/dist/lib/design-resource-handoff-shape.js +62 -0
  33. package/dist/lib/design-resource-handoff-snapshot.d.ts +6 -0
  34. package/dist/lib/design-resource-handoff-snapshot.js +21 -0
  35. package/dist/lib/design-resource-handoff-types.d.ts +23 -1
  36. package/dist/lib/design-resource-handoff-validation.d.ts +2 -1
  37. package/dist/lib/design-resource-handoff-validation.js +45 -22
  38. package/dist/lib/long-task-design-resource-handoff.d.ts +15 -0
  39. package/dist/lib/long-task-design-resource-handoff.js +63 -173
  40. package/dist/lib/long-task-design-resource-method-binding.d.ts +8 -0
  41. package/dist/lib/long-task-design-resource-method-binding.js +135 -0
  42. package/dist/lib/long-task-source-item-parser.d.ts +8 -0
  43. package/dist/lib/long-task-source-item-parser.js +29 -107
  44. package/dist/lib/long-task-source-owned-sections.d.ts +29 -0
  45. package/dist/lib/long-task-source-owned-sections.js +90 -0
  46. package/dist/lib/migrations.js +2 -0
  47. package/dist/lib/modularity-capability-migration.d.ts +2 -0
  48. package/dist/lib/modularity-capability-migration.js +165 -0
  49. package/dist/lib/modularity-python.d.ts +7 -0
  50. package/dist/lib/modularity-python.js +191 -0
  51. package/dist/lib/modularity.d.ts +12 -5
  52. package/dist/lib/modularity.js +110 -44
  53. package/dist/lib/source-files.d.ts +2 -0
  54. package/dist/lib/source-files.js +21 -0
  55. package/dist/lib/source-line-scanner.d.ts +3 -0
  56. package/dist/lib/source-line-scanner.js +42 -0
  57. package/package.json +84 -84
@@ -25,6 +25,8 @@ For non-UI meaning, complete and accurate Source defaults to the finest independ
25
25
 
26
26
  One Source-embedded `semantic-fact-manifest-v1` is the task-local canonical index; durable meaning remains in its existing owning Context and exact values remain Source, never copied into Contract. It freezes a complete Inspector Census, explicit N/A/exclusion basis, non-sampling/non-truncation counts/digests, Fact Cells/Facts, dynamic populations, every Fact × required-method obligation, comparator/parameters/tolerance/mask, Oracle/environment and blockers. Require exact conservation: `Expected Semantic Facts = Source Indexed Facts = Contract Indexed Facts`, and `Fact × required-method obligations = Contract proof bindings = current Final-Gate semantic_fact results`. Every current result carries attributable actual observation/environment, frozen comparison authority, Oracle and pass/fail verdict; proof reaches the furthest independently failing boundary. Aggregate strings, representative/pairwise samples, default paths, implementation-generated expectations, ungrounded N/A, proxy-only/self-reported results and one broad pass Boolean cannot close atomic rows. Any material Source hidden as supporting-only, or any missing, extra, duplicate, unresolved, unreadable, unmapped, unimplemented, unexecuted, stale, failed, authority-drifted, reused or indistinguishable identity blocks Authority Lock or Final Gate. Genuine external authority stays a typed External Confirmation. This adds no second plan, value authority, Gate, state or implementation-order rule.
27
27
 
28
+ Shared Engineering Quality stays thin around those semantic authorities. Before implementation, the universal Architecture Deliberation also routes triggered quality attributes or records a concrete preservation basis; during implementation, owner/boundary/failure/resource guardrails constrain correctness without prescribing order or feedback cadence; Final Gate is the sole Long-Task Engineering Quality Conformance carrier. Every material independently falsifiable invariant uses existing Source-backed technical obligations/global constraints/forbidden shortcuts, owner/path/Bindings, project-owned Checks and an independent Assertion when functional behavior could pass separately. A performance claim requires a workload, metric, baseline or budget, environment, comparator/tolerance and real benchmark/probe. Final Gate proves exactly that declared project-check-bound set—not overall code quality. Exact expected semantics remain in Semantic Facts or selected design, and no quality Boolean, matrix, Source aspect, Claim/risk kind, Contract field, second Gate, state or Receipt is added.
29
+
28
30
  Only fresh evidence from the complete current final snapshot may create machine acceptance. Exactly fresh `machine_accepted` with no pending External Confirmation is `AcceptedDeliveryTerminal` and may support the full declared-observable no-drift conclusion. Otherwise report the task as unfinished or qualified. `machine_accepted_external_pending` means machine-verifiable authority passed while named external confirmation remains; it proves only the declared machine scope and is not full delivery completion. Machine acceptance has no direct native-Goal effect. Never substitute prose, progress, historical tests, Receipts, one exit code or Agent judgment for the Final Gate.
29
31
 
30
32
  Anti-Degradation Assurance requires current-implementation Context to match the indexed code/runtime and protects the controlling purpose, enabling key logic, two jointly necessary implementation responsibilities, theorem boundary and adjacent `F = Implementation Freedom Boundary` from implicit weakening. `F` is an efficiency/anti-process-bloat invariant, not a third responsibility or no-drift theorem premise: within declared Source/Contract, architecture, security, forbidden-shortcut, irreversible-effect and external-action boundaries, the current Goal owns implementation order, methods, local feedback cadence and optional one-agent or multi-agent/subagent execution. Harness must not add a development phase/method permission Gate, per-edit verification mandate, agent allocator/scheduler, delegation proof or persistent delegation state. Replacing any protected invariant requires an explicit project-owner design-purpose decision and replacement proof; a new development-stage constraint must additionally identify a distinct path that final proof or a lighter project-owned check cannot cover and have positive net ROI. Agent inference, coordinated edits or cost alone do not authorize it. Mechanism changes use a two-stage hard gate. First prove `Coverage_new ⊇ Coverage_old`, `FalseNegative_new ⊆ FalseNegative_old`, and that Authority, fail-closed behavior and complete-current-final-snapshot proof cannot be bypassed. If non-degradation cannot be proved, preserve the current formal acceptance path. Only after that gate passes may positive net ROI compare incremental anti-degradation or purpose benefit with every incremental Authoring, Runtime, State, Recovery, maintenance, test, process, introduction and migration cost. No cost reduction compensates for weaker drift interception; positive net ROI permits consideration but never overrides the first gate. This creates no second Authority, Gate or state.
@@ -52,7 +54,7 @@ A Draft Outcome is an Outcome in that pre-Authority-Lock Draft, not a new schema
52
54
 
53
55
  ## Entry And Authoring Loop
54
56
 
55
- 1. Read the user request or external initial proposal, selected design resources and minimum controlling Context. Collect the architecture owners, extension points and boundaries needed for the shared deliberation before deciding `Context Delta`.
57
+ 1. Read the user request or external initial proposal, selected design resources and minimum controlling Context. Collect the architecture owners, extension points, boundaries and risk-triggered engineering-quality attributes needed for the shared deliberation before deciding `Context Delta`.
56
58
  - For material production UI, read the Contract-authoring visual guidance before Compile. When selected resources arrive as an implementation handoff, require one marked `design-resource-handoff-v1` in `task.source_paths` and run `ty-context design-resource preflight <handoff.md>`. Require its canonical Fact manifest, frozen Inspector Census, complete standard/custom axes and property catalog, exact `subject × target × condition × variation × property` Fact Cells, all property-required proofs and exact manifest↔handoff equality; incomplete resource/dependency/Census closure, aggregate state labels, sampling/truncation, ambiguous condition profiles, unsupported evidence, unresolvable located digests, unresolved lineage/conflicts/blockers, missing exact-target layout/pixel Facts or stale identities are blocking. Traverse affected surface/control/target keys from owning Context through `DESIGN.md`, then open every affected selected `exact-target` or `constraint` as Context-reachable ordinary Source. Confirm selection basis, readable immutable identity/digest, declared surface/condition/variation/property coverage and editable upstream owner/locator/update route. A registry or handoff index mention is not consumption. Missing, stale, unreadable, truncated or conflicting resources remain `decision_required`; if only the editable upstream is unavailable, the immutable target may guide implementation but requested resource edits remain a manual/external boundary. An unconfigured starter, candidate, style-only rule or inspiration-only reference is incomplete design authority unless Source explicitly scopes the result as prototype/non-fidelity or supplies a selected target before implementation. When Controls exist, bind them through Product `surface_bindings` to the required production target, existing route/component Bindings and a root-entry journey; each selected target's identity/conditions/files, complete Fact/proof set, canonical per-Fact expectations, covered Source Claims/root Assertion, per-method independent Assertions and blocker lineage must match the handoff before typed evidence can prove it.
57
59
  - If the user is asking to generate or iterate standalone design resources before Contract authoring rather than execute this delivery, use `design-resource-authoring` instead. Its result may later return as ordinary Source; it creates no Contract Draft or Authority.
58
60
  2. If a valid active binding exists, run `ty-context long-task resume <workdir>`, directly load the installed package-managed `long-task-workflow` Skill and read the lifecycle reference. This recovery path does not depend on implicit invocation.
@@ -62,11 +64,11 @@ A Draft Outcome is an Outcome in that pre-Authority-Lock Draft, not a new schema
62
64
  6. Continue reading repository, Source and Context and revise the same Draft. A request to synthesize, refine, complete, implement or use judgment delegates plan-level authoring, but it does not invent the user's tradeoff priorities. Before comparative research or a material product, technical, architecture or provider selection, identify the criteria that could change the research scope, candidate set or recommendation. Infer them only from the user's words, Source, Context or controlling constraints. If quality versus cost, speed, reliability, privacy, lock-in, operational burden or another material priority is unknown or ambiguous, stop before that research or selection and ask one concise targeted clarification. Do not impose a questionnaire, re-ask known preferences or interrupt minor reversible choices whose recommendation would not change.
63
65
  7. Once the material preference envelope is clear, decide what research is needed. Use current authoritative or primary evidence for external capability, pricing, quota, license, compatibility, region, security posture or support claims. When one recommendation is then defensible, record it in real Source with the authoring instruction, preference/evidence basis and exact added meaning instead of pausing for approval. Append the delegated item without rewriting the user's original text when ordinary prose is the Source. Return only when authoritative requirements conflict, the user explicitly reserves the choice, a material preference remains unknown, critical semantics have no defensible recommendation or no falsifiable acceptance standard can be formed.
64
66
  8. Contract expansion remains limited to meaning-preserving structural decomposition, evidence-backed repository binding and choices first recorded as delegated real Source. Never place a new product rule, default, threshold, recovery behavior, permission or platform/data scope only in Contract YAML. Default plan delegation authorizes meaning, not action: payment, contracting, production deployment or publication, destructive production mutation, real permission grants, sensitive-data transmission and required legal/security/human approval remain named external confirmations. Any conflicting, user-reserved, missing-preference or unsupported semantic remains `decision_required`.
65
- 9. Before formal Compile and the first implementation edit, complete the shared `Architecture Deliberation` once and surface concise repository-bound conclusions rather than private reasoning. Cover the current owner/extension point/source of truth, dependencies and lifecycle, selected and rejected alternatives, a plausible future-change challenge, touched debt and its disposition, forbidden shortcuts and project-owned Checks. Even a preservation result names concrete owners and why no new or worsened debt is introduced. Put durable conclusions in owning Context and material falsifiable delivery conclusions in real marked Source plus existing Contract fields, then decide `Context Delta: none|required`. A material scope, owner, Context or design change before implementation stales and refreshes the deliberation.
67
+ 9. Before formal Compile and the first implementation edit, complete the shared `Architecture Deliberation` once and surface concise repository-bound conclusions rather than private reasoning. Cover the current owner/extension point/source of truth, dependencies and lifecycle, selected and rejected alternatives, a plausible future-change challenge, touched debt and its disposition, forbidden shortcuts, project-owned Checks and each triggered quality attribute or concrete preservation basis. Correctness/invariants and maintainability/changeability always receive at least preservation; reliability/resource lifecycle, concurrency/consistency, performance/capacity/cost, security/privacy/safety, compatibility/migration/rollout and operability/observability/testability activate only when material. Even a preservation result names concrete owners and why no new or worsened debt is introduced. Put durable conclusions in owning Context and material falsifiable delivery conclusions in real marked Source plus existing Contract fields, then decide `Context Delta: none|required`. A material scope, owner, Context, design, quality-applicability or debt-disposition change before implementation stales and refreshes the deliberation.
66
68
  10. Close every real Control's 22 canonical fields through `field_coverage` and its Outcome's cross-Control meaning through `control_relation_closure`; use `specified`, explicit `not_applicable` or blocking `unresolved`, and give the closure exact applicability refs even when no Controls apply. Independently close the semantic manifest: exact Source/context input inventory and digests; all standard/custom family, unit, relation, population, axis/value/combination, property, Fact Cell, Fact, proof, Oracle, environment and blocker Census identities; complete generation counts/digests; and exact Source→Fact→Claim/applicability→proof binding equality. Each machine proof maps to one single-Fact Assertion and typed `semantic_fact` capability; each external proof maps to an impact-complete External Confirmation. Declare only actual applicability profiles, each with an atomic, duplicate-free dimension assignment plus exact target, journey, Given condition/input/state refs and ordered When refs. Every Claim lists all applicable profiles; every Claim-bearing Assertion proves one Claim in one matching profile and all required proof surfaces. Declare each execution target's runtime capabilities and require the production family, cold-start and production-root capabilities where applicable. Give every Assertion the minimum all-of Evidence Capabilities that can actually prove its Claim. Every behavioral Claim-bearing Assertion also needs a same-Check claim-local `replace_json_value` or `replace_text` wrong-semantic witness and a claimless target-runtime liveness Assertion that remains passing; whole-file replacement is compatibility-only and cannot prove semantic binding. Population declares a universe Binding whose carriers are Check inputs and proves exact universe = eligible = observed plus valid exclusions. Separate required success and degradation Checks. Type every external confirmation with impacted Claim refs and target-blocking effect. For selected design targets, keep resource-integrity Checks distinct from root-bound implementation conformance, freeze the validated handoff and target resources, preserve exact condition equality, map every covered handoff Source Item into separate attributable Assertions, bind each verification method to its own `design_method` evidence with exact per-condition `fact_refs`, distinct record and primary-observation paths plus a unique current primary digest for every condition, require the cell union to equal the complete target fact set, and declare current actual/comparison artifacts. Preserve every blocker's required target capabilities; use a machine Claim only on the exact capability-qualified target, otherwise keep a target-blocking External Confirmation. Playwright must attach both declared cell artifacts in every project instance. Use `context_snapshot_mode: full`. Run read-only `ty-context long-task preflight <workdir>`, repair every semantic manifest, handoff, Contract and `decision_required` error in the same Draft, then formally Compile only when ready.
67
69
  11. When the first Compile returns `execution_model_checkpoint.required: true`, obey its terminal-turn boundary. Unless an earlier user message explicitly states this task's current-model or switch-and-resume strategy, do no product implementation, file edit, build or test after that result; end the current turn and ask the user to choose `continue_current_model` or switch models and then resume the active Long-Task. Generic “continue”, “resume”, “finish” or “continue the Goal” language does not satisfy the checkpoint. Later revisions return `required: false` and do not repeat it.
68
70
 
69
- Architecture quality uses the existing authority model, not a new gate or field. The visible deliberation proves that architecture work occurred, not that subjective quality is machine-proven. Encode every material falsifiable invariant as a Source-backed technical obligation/global constraint/forbidden shortcut plus owner/path/Binding boundaries and a project-owned executable Check. Functional acceptance cannot substitute when the architecture claim can fail independently. An unverifiable design preference remains task-local, durable Context or `decision_required`; it must not be promoted into false proof.
71
+ Engineering quality uses the existing authority model, not a new stage, Gate or field. The visible deliberation makes the checkpoint reviewable but does not machine-prove subjective quality. Encode every material falsifiable architecture or quality invariant as a Source-backed technical obligation/global constraint/forbidden shortcut plus owner/path/Binding boundaries, a project-owned executable Check and a separate Assertion when functional acceptance could pass independently. Never substitute a broad quality Boolean, functional pass or prose review. An unverifiable preference remains task-local, durable Context or `decision_required`; it must not be promoted into false proof.
70
72
 
71
73
  ## Rolling Execution
72
74
 
@@ -74,7 +76,7 @@ After Authority Lock and the one-time execution-model checkpoint are satisfied,
74
76
 
75
77
  Re-evaluate `Context Delta` whenever implementation or repair discovers a durable fact. Controlling Context changes always use Authority Revision; they require a user decision only when mapped Claims, targets, proof obligations or another decision boundary changes. Graph-derived, non-explicit `implementation-index` and `archive` are Supporting Context in referenced mode and may auto-revise when only navigation/background changed. Full snapshot mode treats every selected Context file as controlling.
76
78
 
77
- If rolling implementation materially changes scope, ownership, dependency direction, the selected design or a debt disposition, refresh the Architecture Deliberation and express any authority change through marked Source/Context plus protected revision before continuing. This is refinement of the same checkpoint, not a second workflow stage.
79
+ If rolling implementation materially changes scope, ownership, dependency direction, the selected design, quality-attribute applicability or a debt disposition, refresh the Architecture Deliberation and express any authority change through marked Source/Context plus protected revision before continuing. This is refinement of the same checkpoint, not a second workflow stage.
78
80
 
79
81
  Use `verify --explain [--outcome/--check]` when execution cost is unclear; it previews declared main and Counterfactual runner invocations without executing or writing Progress. Use targeted `verify --outcome/--check` for optional feedback and repair when its expected localization value exceeds its cost. Progress is repair evidence only and never acceptance authority. Keep precise findings attached to the owning Source item, Claim, Assertion, Check, Binding and owner path. Do not add another model-switch pause or turn delegation into a Harness scheduler, state or proof source.
80
82
 
@@ -95,7 +97,7 @@ Complete Context, implementation and project tests, create a clean candidate com
95
97
 
96
98
  Final Gate recompiles Source authority, captures semantic and raw Contract protected-input identity, validates active task/revision/compiled/worktree identity, creates one Git-tree snapshot and reruns every required Global and Outcome Check. It requires exactly one current typed semantic result for every and only every compiled Fact × machine-method obligation, preserving actual observation/environment, frozen expected/comparison/tolerance/mask/Oracle authority and passing verdict; external obligations remain named confirmations. It then recompiles again and requires unchanged Contract/fragments, Source semantic manifest, Controlling Context, verifier, runner and verification/workdir inputs, plus unchanged workspace/tree and Active Authority, before acceptance. It derives Stage results and target qualification from that run; it does not trust targeted Progress as a Stage pass. A target-runtime Check must exercise its exact target in that current Gate execution; rerunning a reader for a historical or tracked status report is not live target proof. Design-resource integrity, an isolated route or `visual_render` cannot replace required root-bound `design_conformance`, and unresolved semantic or design blockers remain blocking. Final Gate, Stop and close never trust historical Progress, Receipt or compiled cache.
97
99
 
98
- Final Gate is the Long-Task path's sole `Architecture Conformance` carrier. It reruns the declared architecture obligations/constraints/forbidden shortcuts, owner/path/Binding boundaries and project-owned Checks on that same snapshot and blocks scope escape, bypass, duplicate authority, a second source of truth, wrong dependency direction, undeclared boundary change or new/worsened debt represented by those invariants. Do not also run the default Workflow's standalone Contract Conformance closure. Any later candidate or authority change invalidates the Gate and uses the existing freshness path again.
100
+ Final Gate is the Long-Task path's sole `Engineering Quality Conformance` and `Architecture Conformance` carrier. It reruns the declared architecture/quality obligations, constraints and forbidden shortcuts, owner/path/Binding boundaries, independent Assertions and project-owned Checks on that same snapshot. It blocks the represented scope escape, bypass, duplicate authority, second source of truth, wrong dependency direction, undeclared boundary/lifecycle change, silent failure, unsupported performance claim or new/worsened debt. It proves only those declared falsifiable invariants, never overall code quality. Do not also run the default Workflow's Contract Conformance closure. Any later candidate or authority change invalidates the Gate and uses the existing freshness path again.
99
101
 
100
102
  Machine acceptance covers only declared machine authority. Preserve every pending external confirmation through `final-gate`, `status`, `resume`, `stop-check`, the package-owned Stop Hook and `close`; accepted output identifies `acceptance_scope: declared_machine_authority` and `native_goal_effect: none`, while `closed_scope: machine_authority` means only Authority cleanup. Do not invent external-confirmation or native-Goal tracking state.
101
103
 
@@ -103,4 +105,4 @@ Before invoking platform-native Goal completion, perform one veto-only conforman
103
105
 
104
106
  ## Handoff
105
107
 
106
- Report implementation, effective risk, Architecture Deliberation/Conformance status, Claim Coverage, Stage frontier/results, declared target profile, exact `target_state`, Live Gate result, acceptance scope, every pending external confirmation, Context status and blockers. Use verifier terms exactly: `progress_passing` means targeted repair evidence, `progress_stale` is a freshness fact rather than a current pass or immediate rerun command, `final_workflow_status: null` means unfinished, `authority_revision_adopted` means return to rolling execution, and `machine_accepted_external_pending` must retain its named confirmations and never be summarized as `AcceptedDeliveryTerminal` or full no-drift delivery. Contract target states are only `implementation_complete`, `target_profile_usable` and `production_release_ready`; terminal failure uses `not_accepted` or `blocked_external`. Never shorten targeted progress to “Outcome complete” or invent per-platform progress/status. State the theorem boundary honestly: undeclared or inaccurate Source cannot be discovered mechanically; the named project oracle must be semantically sound; the supported direct-literal verifier dependency graph is frozen while other declared verification inputs, indirect runtime access, installed package/runtime behavior, Harness verifier and Git metadata form the trusted computing boundary; the visible checkpoint cannot prove private reasoning or universal future-proofing; native-Goal/model selection belongs to the host/user; and internal platform delegation is not observed.
108
+ Report implementation, effective risk, Architecture Deliberation and Engineering Quality/Architecture Conformance status, Claim Coverage, Stage frontier/results, declared target profile, exact `target_state`, Live Gate result, acceptance scope, every pending external confirmation, Context status and blockers. Use verifier terms exactly: `progress_passing` means targeted repair evidence, `progress_stale` is a freshness fact rather than a current pass or immediate rerun command, `final_workflow_status: null` means unfinished, `authority_revision_adopted` means return to rolling execution, and `machine_accepted_external_pending` must retain its named confirmations and never be summarized as `AcceptedDeliveryTerminal` or full no-drift delivery. Contract target states are only `implementation_complete`, `target_profile_usable` and `production_release_ready`; terminal failure uses `not_accepted` or `blocked_external`. Never shorten targeted progress to “Outcome complete” or invent per-platform progress/status. State the theorem boundary honestly: undeclared or inaccurate Source cannot be discovered mechanically; the named project oracle must be semantically sound; the supported direct-literal verifier dependency graph is frozen while other declared verification inputs, indirect runtime access, installed package/runtime behavior, Harness verifier and Git metadata form the trusted computing boundary; Final Gate proves only its declared project-check-bound quality set; the visible checkpoint cannot prove private reasoning or universal future-proofing; native-Goal/model selection belongs to the host/user; and internal platform delegation is not observed.
@@ -67,7 +67,7 @@ Report their exact meaning: `progress_passing` is current targeted repair eviden
67
67
 
68
68
  ## Final Gate And Terminal Paths
69
69
 
70
- Before Final Gate, complete Context/code/tests and create a clean candidate commit. Final Gate first verifies the accepted compiled authority is still fresh, then recompiles Source authority and records semantic plus raw protected-input identity for the Contract and fragments, the Source-embedded semantic manifest, every Source file, full Controlling Context, verifier/runner, recursively frozen local verifier dependencies, `verification_inputs` and workdir inputs. It validates the common-dir record/marker, creates one Git-tree snapshot and reruns every Check and sensitivity control. Non-UI semantic evidence must reproduce exactly every compiled machine Fact × method expectation with one attributable actual observation/environment/comparison/verdict under frozen expected/tolerance/mask/Oracle authority; selected-design method evidence must reproduce its exact compiled `fact_results` universe; every verdict passes, while named external obligations remain pending rather than fabricated. After execution it recompiles and re-hashes the same full protected set; any change returns `protected_inputs_changed_during_final_gate`, while an Active Authority race returns `active_authority_changed_during_final_gate`. Only unchanged protected inputs, workspace/tree and Authority may be accepted. It is the sole Long-Task `Architecture Conformance` carrier and the sole non-UI semantic and selected-design closure carrier: material deliberation conclusions must already be declared through existing obligations/constraints/forbidden shortcuts, owners/paths/Bindings and project-owned Checks, and no separate default Contract Conformance closure runs. A target-runtime Check must exercise its exact target again in that Final Gate execution; rereading historical status does not become live proof merely because the reader reran. The Receipt reports the target profile/state and every Stage as `passed`, `failed`, `blocked_external` or `blocked_dependency`.
70
+ Before Final Gate, complete Context/code/tests and create a clean candidate commit. Final Gate first verifies the accepted compiled authority is still fresh, then recompiles Source authority and records semantic plus raw protected-input identity for the Contract and fragments, the Source-embedded semantic manifest, every Source file, full Controlling Context, verifier/runner, recursively frozen local verifier dependencies, `verification_inputs` and workdir inputs. It validates the common-dir record/marker, creates one Git-tree snapshot and reruns every Check and sensitivity control. Non-UI semantic evidence must reproduce exactly every compiled machine Fact × method expectation with one attributable actual observation/environment/comparison/verdict under frozen expected/tolerance/mask/Oracle authority; selected-design method evidence must reproduce its exact compiled `fact_results` universe; every verdict passes, while named external obligations remain pending rather than fabricated. After execution it recompiles and re-hashes the same full protected set; any change returns `protected_inputs_changed_during_final_gate`, while an Active Authority race returns `active_authority_changed_during_final_gate`. Only unchanged protected inputs, workspace/tree and Authority may be accepted. It is the sole Long-Task `Engineering Quality Conformance`/`Architecture Conformance` carrier and the sole non-UI semantic and selected-design closure carrier: material independently falsifiable deliberation conclusions must already be declared through existing Source-backed obligations/constraints/forbidden shortcuts, owners/paths/Bindings, project-owned Checks and separate Assertions when functional behavior can pass independently. It proves exactly that declared project-check-bound engineering-quality set, not overall code quality, and no separate default Contract Conformance closure runs. A target-runtime Check must exercise its exact target again in that Final Gate execution; rereading historical status does not become live proof merely because the reader reran. The Receipt reports the target profile/state and every Stage as `passed`, `failed`, `blocked_external` or `blocked_dependency`.
71
71
 
72
72
  Commit, verifier migration, clear and abandon share one active-state lock. Stop/close clear only the identity actually accepted through CAS and preserve `machine_accepted_external_pending` plus every named external confirmation in output. Final Gate/Stop/close identify `acceptance_scope: declared_machine_authority` and `native_goal_effect: none`; close additionally identifies `closed_scope: machine_authority`. The Stop Hook emits the same scope as one non-blocking message for either accepted machine status. A stale Receipt exposes no accepted workflow status.
73
73
 
@@ -72,21 +72,23 @@ Declare cheap machine-checkable prerequisites through existing environment requi
72
72
  - `task.target_profile` declares `required_state` plus a non-empty, duplicate-free `required_target_refs`. Each ref resolves to a `product` execution target with one bounded runtime family, root entrypoint and explicit capabilities. A required product target declares its family capability plus `cold-start` and `production-root`; every Stage Gate and every `critical_user_path` Outcome provides root `target_runtime` proof for every required ref. Optional support/observer targets never substitute.
73
73
  - Use `implementation_complete` only when code-level implementation is the selected target, `target_profile_usable` when the declared required targets must be usable, and `production_release_ready` only when release gates are part of the selected target. These are terminal target qualifications, not Outcome progress states.
74
74
 
75
- ## Architecture Deliberation And Closure
76
-
77
- Architecture Deliberation occurs once for every implementation delivery before formal Compile and the first implementation edit; risk changes depth, not occurrence. Surface concise conclusions and repository evidence rather than private chain-of-thought. A preservation result still names the concrete owner/extension point and explains why durable boundaries and debt do not worsen. Material work covers module ownership, unique source of truth, dependency direction, API/schema/data boundary, state lifecycle, persistence/recovery, security boundary, compatibility/migration, selected and rejected alternatives, one plausible future-change challenge, touched technical debt and forbidden bypasses.
78
-
79
- Represent every material falsifiable invariant with existing Contract fields:
75
+ ## Engineering Quality Deliberation And Closure
76
+
77
+ Architecture Deliberation occurs once for every implementation delivery before formal Compile and the first implementation edit; risk changes depth, not occurrence. Surface concise conclusions and repository evidence rather than private chain-of-thought. A preservation result still names the concrete owner/extension point, applicable engineering-quality attributes or their concrete preservation basis, and why durable boundaries and debt do not worsen. Material work covers module ownership, unique source of truth, dependency direction, API/schema/data boundary, state/resource lifecycle, persistence/recovery, security boundary, compatibility/migration, selected and rejected alternatives, one plausible future-change challenge, touched technical debt, forbidden bypasses and triggered failure/load/threat scenarios.
78
+
79
+ Correctness/invariants and maintainability/changeability always receive at least preservation. Reliability/resource lifecycle, concurrency/consistency, performance/capacity/cost, security/privacy/safety, compatibility/migration/rollout and operability/observability/testability activate only when the Source or implementation risk makes them material. Exact expected predicates remain in Semantic Facts or selected-design authority. A performance claim additionally binds workload, metric, baseline or budget, environment, comparator/tolerance and a project-owned benchmark/probe; static shape cannot prove runtime performance.
80
+
81
+ Represent every material independently falsifiable architecture or engineering-quality invariant with existing Contract fields:
80
82
 
81
83
  1. a Source-backed technical obligation, global constraint or forbidden shortcut;
82
84
  2. owner Context and expected/support/forbidden paths;
83
85
  3. a Binding to the implementation carrier when Counterfactual sensitivity is required;
84
- 4. a project-owned executable architecture check, such as the repository's lint, AST, dependency or contract test;
85
- 5. a separate Assertion when functional behavior could pass while the architecture invariant fails.
86
-
87
- New or worsened debt is unacceptable unless a project-owned bounded exception identifies owner, rationale, tracking and removal/expiry condition. Unrelated legacy debt does not automatically expand delivery scope, but debt touched, relied on or worsened by the implementation cannot remain hidden. Material changes to scope, owner, Context, dependency direction, selected design or debt disposition refresh the deliberation and, after Authority Lock, use protected revision.
88
-
89
- Do not encode subjective “clean architecture or generic quality prose as machine authority. If no reliable observation can falsify it, keep it as durable Context/review judgment or return `decision_required`. Harness routes the repository's architecture check; it does not become a language-generic dependency analyzer. Final Gate is the only Long-Task Architecture Conformance carrier and reruns these declared Checks on its current snapshot; do not add a default-workflow closure, architecture field, second Gate or state.
86
+ 4. a project-owned executable type, compiler, lint, AST, dependency, contract, behavior, benchmark or probe Check; and
87
+ 5. a separate Assertion when functional behavior could pass while the quality invariant fails.
88
+
89
+ New or worsened debt is unacceptable unless a project-owned bounded exception identifies owner, rationale, tracking and removal/expiry condition. Unrelated legacy debt does not automatically expand delivery scope, but debt touched, relied on or worsened by the implementation cannot remain hidden. Material changes to scope, owner, Context, dependency direction, selected design or debt disposition refresh the deliberation and, after Authority Lock, use protected revision.
90
+
91
+ Do not encode subjective “clean architecture”, `quality == true`, a functional pass or generic quality prose as machine authority. If no reliable observation can falsify it, keep it as durable Context/review judgment or return `decision_required`. Harness routes repository-native checks; it does not become a language-generic dependency, quality or performance analyzer. Final Gate is the only Long-Task Engineering Quality/Architecture Conformance carrier and reruns these declared Checks on its current snapshot. It proves only the declared project-check-bound invariant set, not overall code quality. Do not add a default-workflow closure, quality matrix, Source aspect, Claim/risk kind, Contract field, second Gate, state or Receipt.
90
92
 
91
93
  ## Proxy And Target Runtime Independence
92
94
 
@@ -39,7 +39,7 @@ export async function checkModularity(args) {
39
39
  : file.overLimit
40
40
  ? "observed-risk"
41
41
  : "ok";
42
- console.log(`${prefix}: ${file.relativePath} ${file.lines} lines statements=${file.metrics.maxFunctionStatements} branches=${file.metrics.maxBranchComplexity} exports=${file.metrics.exports} transitions=${file.metrics.stateTransitions} responsibilities=${file.metrics.responsibilities.join(",") || "none"} statement_at=${formatLocation(file.metrics.maxFunctionStatementsLocation)} branch_at=${formatLocation(file.metrics.maxBranchComplexityLocation)}`);
42
+ console.log(`${prefix}: ${file.relativePath} ${file.lines} lines analysis=${file.metrics.analysis} statements=${formatMetric(file.metrics.maxFunctionStatements)} branches=${formatMetric(file.metrics.maxBranchComplexity)} exports=${formatMetric(file.metrics.exports)} transitions=${formatMetric(file.metrics.stateTransitions)} responsibilities=${formatResponsibilities(file.metrics.responsibilities)} statement_at=${formatLocation(file.metrics.maxFunctionStatementsLocation, file.metrics.maxFunctionStatements !== null)} branch_at=${formatLocation(file.metrics.maxBranchComplexityLocation, file.metrics.maxBranchComplexity !== null)}`);
43
43
  }
44
44
  for (const error of report.errors) {
45
45
  console.error(`error: ${error}`);
@@ -63,9 +63,21 @@ export async function checkModularity(args) {
63
63
  process.exitCode = 1;
64
64
  }
65
65
  }
66
- function formatLocation(location) {
66
+ function formatLocation(location, supported) {
67
+ if (!supported) {
68
+ return "n/a";
69
+ }
67
70
  return location ? `${location.symbol}:${location.line}` : "none";
68
71
  }
72
+ function formatMetric(value) {
73
+ return value === null ? "n/a" : String(value);
74
+ }
75
+ function formatResponsibilities(value) {
76
+ if (value === null) {
77
+ return "n/a";
78
+ }
79
+ return value.join(",") || "none";
80
+ }
69
81
  function parseArgs(args) {
70
82
  const parsed = {
71
83
  touched: false,
@@ -160,7 +172,8 @@ function helpText() {
160
172
  check-modularity --base <ref> [--limit 300] [--fail-on-warning]
161
173
  check-modularity --config-only
162
174
 
163
- Audits physical lines, per-function statements and branch complexity, exports, state transitions and module responsibilities.
175
+ Portable heuristic risk signal: all selected files get physical-line analysis; JS/TS gets lexical function/branch/export/state-transition/responsibility metrics; Python gets lexical per-function statement/branch metrics; other included formats are line-only.
176
+ The report names analysis=js-ts-heuristic|python-heuristic|line-only and prints n/a for unsupported metrics. It is not complete cross-language static analysis, architecture proof or runtime-performance evidence; prefer project-native tools for those claims.
164
177
  For --touched and --base, existing findings are reported but only new or worsened non-line complexity is a warning; physical lines remain a risk signal and new files are audited in full.
165
178
  The default is warning-only; --fail-on-warning lets projects opt into CI enforcement.
166
179
  Generated configs default to modularity.policy: strict_except_generated; omitted policy is treated as scoped_waivers for compatibility.
@@ -1,5 +1,6 @@
1
+ import { publishDesignResourceHandoffBundle } from "../lib/design-resource-handoff-bundle.js";
1
2
  import { preflightDesignResourceHandoff } from "../lib/design-resource-handoff-validation.js";
2
- import { normalizeRepositoryFile } from "../lib/long-task-paths.js";
3
+ import { normalizeRepositoryCwd, normalizeRepositoryFile, } from "../lib/long-task-paths.js";
3
4
  import { canonicalJson } from "../lib/strict-codec.js";
4
5
  export async function designResource(args) {
5
6
  const [subcommand = "help", ...rest] = args;
@@ -7,6 +8,10 @@ export async function designResource(args) {
7
8
  help();
8
9
  return;
9
10
  }
11
+ if (subcommand === "bundle") {
12
+ await bundle(rest);
13
+ return;
14
+ }
10
15
  if (subcommand !== "preflight")
11
16
  throw new Error(`Unknown design-resource subcommand: ${subcommand}`);
12
17
  const json = rest.includes("--json");
@@ -25,8 +30,63 @@ export async function designResource(args) {
25
30
  console.log(`Coverage: ${result.counts.subjects} subjects x 8 dimensions (${result.counts.coverage} grouped rows)`);
26
31
  console.log(`Acceptance blockers: ${result.counts.acceptance_blockers}`);
27
32
  }
33
+ async function bundle(args) {
34
+ const positional = [];
35
+ const manifests = [];
36
+ let maxHandoffBytes = null;
37
+ let json = false;
38
+ for (let index = 0; index < args.length; index += 1) {
39
+ const item = args[index];
40
+ if (item === "--json") {
41
+ json = true;
42
+ continue;
43
+ }
44
+ if (item === "--manifest") {
45
+ const value = args[index + 1];
46
+ if (!value)
47
+ throw new Error("--manifest requires a path");
48
+ manifests.push(normalizeRepositoryFile(value, "design_resource_bundle_manifest"));
49
+ index += 1;
50
+ continue;
51
+ }
52
+ if (item === "--max-handoff-bytes") {
53
+ const value = args[index + 1];
54
+ if (!value)
55
+ throw new Error("--max-handoff-bytes requires an integer");
56
+ maxHandoffBytes = Number(value);
57
+ index += 1;
58
+ continue;
59
+ }
60
+ if (item.startsWith("--"))
61
+ throw new Error(`Unknown design-resource bundle option: ${item}`);
62
+ positional.push(item);
63
+ }
64
+ if (positional.length !== 2 ||
65
+ manifests.length === 0 ||
66
+ maxHandoffBytes === null)
67
+ throw new Error("usage: ty-context design-resource bundle <draft-dir> <new-output-dir> --manifest <facts.json> [--manifest <facts.json> ...] --max-handoff-bytes <bytes> [--json]");
68
+ const result = await publishDesignResourceHandoffBundle({
69
+ repository: process.cwd(),
70
+ draft_directory: normalizeRepositoryCwd(positional[0], "design_resource_bundle_draft_directory"),
71
+ output_directory: normalizeRepositoryCwd(positional[1], "design_resource_bundle_output_directory"),
72
+ manifest_paths: manifests,
73
+ max_handoff_bytes: maxHandoffBytes,
74
+ });
75
+ if (json) {
76
+ process.stdout.write(canonicalJson(result));
77
+ return;
78
+ }
79
+ console.log(`Design resource handoff bundle published: ${result.output_directory}`);
80
+ console.log(`Handoffs: ${result.handoffs.length}`);
81
+ console.log(`Targets: ${result.handoffs.map((item) => item.target_key).join(", ")}`);
82
+ }
28
83
  function help() {
29
84
  console.log(`ty-context design-resource commands:
30
85
  preflight <handoff.md> [--json]
31
- Validate one selected implementation handoff`);
86
+ Validate one selected implementation handoff
87
+ bundle <draft-dir> <new-output-dir> --manifest <facts.json> [...]
88
+ --max-handoff-bytes <bytes> [--json]
89
+ Validate manifest-backed one-target handoffs and
90
+ atomically publish the complete target set; the
91
+ output parent directory must already exist`);
32
92
  }
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { commands } from "./commands/index.js";
2
2
  export { compileDeliveryContract, type CompileDeliveryOptionsV2, } from "./lib/long-task-delivery-compiler.js";
3
3
  export { DELIVERY_CONTRACT_FILE, parseDeliveryContract, parseDeliveryContractBundle, } from "./lib/long-task-delivery-parser.js";
4
4
  export { evaluateContractBoundary } from "./lib/long-task-boundary-check.js";
5
+ export { publishDesignResourceHandoffBundle, type DesignResourceHandoffBundleOptions, type DesignResourceHandoffBundleResult, } from "./lib/design-resource-handoff-bundle.js";
5
6
  export { preflightDesignResourceHandoff } from "./lib/design-resource-handoff-validation.js";
6
7
  export { classifyLongTaskRisk, validateRiskProof, } from "./lib/long-task-risk.js";
7
8
  export { verifyDeliveryContract } from "./lib/long-task-verifier-v2.js";
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export { commands } from "./commands/index.js";
2
2
  export { compileDeliveryContract, } from "./lib/long-task-delivery-compiler.js";
3
3
  export { DELIVERY_CONTRACT_FILE, parseDeliveryContract, parseDeliveryContractBundle, } from "./lib/long-task-delivery-parser.js";
4
4
  export { evaluateContractBoundary } from "./lib/long-task-boundary-check.js";
5
+ export { publishDesignResourceHandoffBundle, } from "./lib/design-resource-handoff-bundle.js";
5
6
  export { preflightDesignResourceHandoff } from "./lib/design-resource-handoff-validation.js";
6
7
  export { classifyLongTaskRisk, validateRiskProof, } from "./lib/long-task-risk.js";
7
8
  export { verifyDeliveryContract } from "./lib/long-task-verifier-v2.js";
@@ -1,3 +1,4 @@
1
1
  import type { DesignResourceObservableFactManifestV1 } from "./design-resource-fact-manifest-types.js";
2
- import type { ParsedDesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
3
- export declare function loadAndValidateDesignResourceFactManifests(repository: string, parsed: ParsedDesignResourceHandoffV1): Promise<Map<string, DesignResourceObservableFactManifestV1>>;
2
+ import type { ParsedDesignResourceHandoffInputV1, ParsedDesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
3
+ export declare function parseDesignResourceFactManifests(parsed: ParsedDesignResourceHandoffInputV1, contents: Map<string, Buffer>): Map<string, DesignResourceObservableFactManifestV1>;
4
+ export declare function validateDesignResourceFactManifests(parsed: ParsedDesignResourceHandoffV1, contents: Map<string, Buffer>, manifests: Map<string, DesignResourceObservableFactManifestV1>, validateProjection: boolean): void;
@@ -1,18 +1,9 @@
1
- import { readFile } from "node:fs/promises";
2
- import path from "node:path";
3
1
  import { parseDesignResourceFactManifestJson } from "./design-resource-fact-manifest-shape.js";
4
2
  import { validateDesignResourceFactManifestUniverse } from "./design-resource-fact-manifest-universe.js";
5
3
  import { invalidDesignResourceHandoff } from "./design-resource-handoff-validation-primitives.js";
6
- import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
7
- export async function loadAndValidateDesignResourceFactManifests(repository, parsed) {
4
+ export function parseDesignResourceFactManifests(parsed, contents) {
8
5
  const resources = new Map(parsed.handoff.resources.map((resource) => [resource.key, resource]));
9
- const contents = new Map();
10
- for (const resource of parsed.handoff.resources) {
11
- const file = await assertProtectedRepositoryFile(repository, path.resolve(repository, ...resource.path.split("/")), `design_resource:${resource.key}`);
12
- contents.set(resource.key, await readFile(file));
13
- }
14
6
  const manifests = new Map();
15
- const sourceItems = new Map(Object.entries(parsed.source_item_kinds));
16
7
  for (const target of parsed.handoff.targets) {
17
8
  const manifestRef = target.source_profile.fact_manifest_resource_ref;
18
9
  const manifestResource = resources.get(manifestRef);
@@ -32,13 +23,23 @@ export async function loadAndValidateDesignResourceFactManifests(repository, par
32
23
  if (manifest.target_key !== target.key ||
33
24
  manifest.scope_key !== parsed.handoff.scope.key)
34
25
  invalid("fact_manifest_identity_mismatch", `${target.key}:${manifest.scope_key}:${manifest.target_key}`);
35
- validateDesignResourceFactManifestUniverse(manifest, parsed.handoff, target, resources, contents, sourceItems);
36
- validateManifestProjection(parsed.handoff, target.key, manifest);
37
26
  manifests.set(target.key, manifest);
38
27
  }
39
28
  sameSet([...manifests.keys()], parsed.handoff.targets.map((target) => target.key), "fact_manifest_target_set_mismatch", "handoff");
40
29
  return manifests;
41
30
  }
31
+ export function validateDesignResourceFactManifests(parsed, contents, manifests, validateProjection) {
32
+ const resources = new Map(parsed.handoff.resources.map((resource) => [resource.key, resource]));
33
+ const sourceItems = new Map(Object.entries(parsed.source_item_kinds));
34
+ for (const target of parsed.handoff.targets) {
35
+ const manifest = manifests.get(target.key);
36
+ if (!manifest)
37
+ invalid("fact_manifest_target_missing", target.key);
38
+ validateDesignResourceFactManifestUniverse(manifest, parsed.handoff, target, resources, contents, sourceItems);
39
+ if (validateProjection)
40
+ validateManifestProjection(parsed.handoff, target.key, manifest);
41
+ }
42
+ }
42
43
  function validateManifestProjection(handoff, targetKey, manifest) {
43
44
  const target = handoff.targets.find((item) => item.key === targetKey);
44
45
  const targetConditions = new Set(target.condition_refs);
@@ -77,12 +78,16 @@ function validateManifestProjection(handoff, targetKey, manifest) {
77
78
  exactRows(handoff.acceptance_blockers.filter((row) => row.target_refs.includes(targetKey)), manifest.acceptance_blockers, "acceptance_blockers", targetKey);
78
79
  }
79
80
  function exactRows(handoffRows, manifestRows, collection, targetKey) {
80
- const handoff = new Map(handoffRows.map((row) => [row.key, canonicalJson(row)]));
81
- const manifest = new Map(manifestRows.map((row) => [row.key, canonicalJson(row)]));
82
- sameSet([...handoff.keys()], [...manifest.keys()], `manifest_handoff_${collection}_set_mismatch`, targetKey);
83
- for (const [key, value] of manifest)
84
- if (handoff.get(key) !== value)
85
- invalid(`manifest_handoff_${collection}_row_mismatch`, `${targetKey}:${key}`);
81
+ const handoff = new Map(handoffRows.map((row) => [row.key, row]));
82
+ if (handoff.size !== manifestRows.length)
83
+ invalid(`manifest_handoff_${collection}_set_mismatch`, `${targetKey}:count:${handoff.size}:${manifestRows.length}`);
84
+ for (const manifestRow of manifestRows) {
85
+ const handoffRow = handoff.get(manifestRow.key);
86
+ if (!handoffRow)
87
+ invalid(`manifest_handoff_${collection}_set_mismatch`, `${targetKey}:missing:${manifestRow.key}`);
88
+ if (canonicalJson(handoffRow) !== canonicalJson(manifestRow))
89
+ invalid(`manifest_handoff_${collection}_row_mismatch`, `${targetKey}:${manifestRow.key}`);
90
+ }
86
91
  }
87
92
  function canonicalJson(value) {
88
93
  if (Array.isArray(value))
@@ -101,7 +101,7 @@ export function validateManifestFactCells(manifest, sourceItems, census) {
101
101
  actual.set(fingerprint, cell.key);
102
102
  validateFactCellDisposition(cell, coveredFacts);
103
103
  }
104
- sameSet([...actual.keys()], expectedFactCellFingerprints(manifest), "manifest_expected_fact_cell_universe_mismatch", manifest.target_key);
104
+ assertExpectedFactCellFingerprints(manifest, actual);
105
105
  unique(coveredFacts, "manifest_fact_ref_reused_by_cells");
106
106
  sameSet(coveredFacts, manifest.facts.map((fact) => fact.key), "manifest_expected_canonical_fact_set_mismatch", manifest.target_key);
107
107
  }
@@ -134,18 +134,28 @@ function validateFactCellDisposition(cell, coveredFacts) {
134
134
  cell.disposition === "unavailable")
135
135
  invalid("manifest_fact_cell_unresolved", cell.key);
136
136
  }
137
- function expectedFactCellFingerprints(manifest) {
138
- const expected = [];
137
+ function assertExpectedFactCellFingerprints(manifest, actual) {
138
+ const variationsBySubject = new Map();
139
+ for (const variation of manifest.variations) {
140
+ const rows = variationsBySubject.get(variation.subject_ref) ?? [];
141
+ rows.push(variation.key);
142
+ variationsBySubject.set(variation.subject_ref, rows);
143
+ }
144
+ let expectedCount = 0;
139
145
  for (const subject of manifest.subjects)
140
146
  for (const condition of manifest.conditions)
141
- for (const variation of manifest.variations.filter((item) => item.subject_ref === subject.key))
147
+ for (const variationRef of variationsBySubject.get(subject.key) ?? [])
142
148
  for (const property of manifest.properties)
143
- expected.push(factCellFingerprint({
149
+ if (!actual.has(factCellFingerprint({
144
150
  subject_ref: subject.key,
145
151
  target_ref: manifest.target_key,
146
152
  condition_ref: condition.key,
147
- variation_ref: variation.key,
153
+ variation_ref: variationRef,
148
154
  property_ref: property.key,
149
- }));
150
- return expected;
155
+ })))
156
+ invalid("manifest_expected_fact_cell_universe_mismatch", `${manifest.target_key}:missing:${subject.key}:${condition.key}:${variationRef}:${property.key}`);
157
+ else
158
+ expectedCount += 1;
159
+ if (actual.size !== expectedCount)
160
+ invalid("manifest_expected_fact_cell_universe_mismatch", `${manifest.target_key}:count:${actual.size}:${expectedCount}`);
151
161
  }
@@ -1,11 +1,15 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { DESIGN_RESOURCE_STANDARD_CONDITION_AXES, } from "./design-resource-fact-manifest-types.js";
2
3
  import { invalidDesignResourceHandoff } from "./design-resource-handoff-validation-primitives.js";
3
- import { sha256Hex } from "./strict-codec.js";
4
4
  export function manifestIdentityDigest(rows) {
5
- return sha256Hex(rows
6
- .map((row) => stableJson(row))
7
- .sort()
8
- .join("\n"));
5
+ const hash = createHash("sha256");
6
+ const identities = rows.map((row) => stableJson(row)).sort();
7
+ for (let index = 0; index < identities.length; index += 1) {
8
+ if (index > 0)
9
+ hash.update("\n");
10
+ hash.update(identities[index]);
11
+ }
12
+ return hash.digest("hex");
9
13
  }
10
14
  export function manifestCollectionRows(manifest) {
11
15
  return new Map([
@@ -0,0 +1,31 @@
1
+ import type { DesignResourceManifestCollectionName } from "./design-resource-fact-manifest-types.js";
2
+ export interface DesignResourceHandoffBundleOptions {
3
+ repository: string;
4
+ draft_directory: string;
5
+ output_directory: string;
6
+ manifest_paths: string[];
7
+ max_handoff_bytes: number;
8
+ }
9
+ export interface DesignResourceHandoffBundleResult {
10
+ status: "published";
11
+ output_directory: string;
12
+ handoffs: Array<{
13
+ path: string;
14
+ sha256: string;
15
+ bytes: number;
16
+ scope_key: string;
17
+ target_key: string;
18
+ }>;
19
+ manifests: Array<{
20
+ path: string;
21
+ sha256: string;
22
+ scope_key: string;
23
+ target_key: string;
24
+ collections: Array<{
25
+ name: DesignResourceManifestCollectionName;
26
+ expected_count: number;
27
+ identity_sha256: string;
28
+ }>;
29
+ }>;
30
+ }
31
+ export declare function publishDesignResourceHandoffBundle(options: DesignResourceHandoffBundleOptions): Promise<DesignResourceHandoffBundleResult>;