@tiinex/core 0.29.0 → 0.31.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiinex/core",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "description": "Shared host-neutral Tiinex implementation core for artifacts, schemas, validation, lineage, grounding, Handoffs, provenance and deterministic workflows.",
5
5
  "type": "module",
6
6
  "sideEffects": true,
@@ -173,12 +173,12 @@
173
173
  "type": "git",
174
174
  "url": "git+https://github.com/Tiinex/core.git"
175
175
  },
176
- "gitHead": "d2ab9eeaaf1a0c0d13e2d7a5f9de4d010cf5e5bb",
176
+ "gitHead": "54c359f5d721194579aec2089cae096643912f07",
177
177
  "tiinexRelease": {
178
178
  "policy": "tiinex.master-npm-release.v1",
179
- "sourceCommit": "d2ab9eeaaf1a0c0d13e2d7a5f9de4d010cf5e5bb",
180
- "sourceTree": "50ae220f210ec6551825735fb7d9ba8f7956edc5",
179
+ "sourceCommit": "54c359f5d721194579aec2089cae096643912f07",
180
+ "sourceTree": "fbf8219dabf97f9939544b63387372c2c705726e",
181
181
  "repository": "Tiinex/core",
182
- "previousVersion": "0.28.0"
182
+ "previousVersion": "0.30.0"
183
183
  }
184
184
  }
@@ -0,0 +1,120 @@
1
+ export const SCHEMA_LINEAGE_SOURCE_AUTHORITY_QUALIFICATION_SCHEMA_ID = 'tiinex.core.schema-lineage-source-authority-qualification.v1';
2
+
3
+ export function qualifyCompiledSchemaLineageSourceAuthority(validationContract = {}) {
4
+ const lineage = Array.isArray(validationContract?.lineage) ? validationContract.lineage.map((item) => String(item || '').trim()) : [];
5
+ const projected = Array.isArray(validationContract?.lineageAuthority) ? validationContract.lineageAuthority : [];
6
+ const findings = [];
7
+ const edges = [];
8
+
9
+ if (!lineage.length || validationContract?.lineageQualification?.state !== 'valid') {
10
+ findings.push('Compiled validation lineage is unavailable or not valid.');
11
+ }
12
+ if (projected.length !== lineage.length) {
13
+ findings.push(`Compiled validation lineage source authority cardinality is ${projected.length}; expected ${lineage.length}.`);
14
+ }
15
+
16
+ const count = Math.min(projected.length, lineage.length);
17
+ for (let index = 0; index < count; index += 1) {
18
+ const entry = projected[index] || {};
19
+ const expectedSchemaId = lineage[index] || '';
20
+ const actualSchemaId = String(entry?.schemaId || '').trim();
21
+ if (!actualSchemaId || actualSchemaId !== expectedSchemaId) {
22
+ findings.push(`Compiled lineage source authority identity mismatch at index ${index}: expected ${expectedSchemaId || '(missing schema id)'} but observed ${actualSchemaId || '(missing schema id)'}.`);
23
+ }
24
+ }
25
+
26
+ for (let index = 1; index < count; index += 1) {
27
+ const parent = projected[index - 1] || {};
28
+ const child = projected[index] || {};
29
+ const parentSchemaId = String(parent?.schemaId || '').trim();
30
+ const childSchemaId = String(child?.schemaId || '').trim();
31
+ const declaredParentSchemaId = String(child?.parentSchemaId || '').trim();
32
+ const parentSource = normalizeSourceTuple(parent?.source || {});
33
+ const candidates = Object.freeze((Array.isArray(child?.parentSourceCandidates) ? child.parentSourceCandidates : []).map(normalizeSourceTuple));
34
+
35
+ if (!declaredParentSchemaId || declaredParentSchemaId !== parentSchemaId) {
36
+ findings.push(`Compiled lineage identity is incoherent across ${parentSchemaId || '(unknown parent)'} -> ${childSchemaId || '(unknown child)'}.`);
37
+ edges.push(freezeEdge({ state: 'contradictory', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'parent-schema-identity-mismatch' }));
38
+ continue;
39
+ }
40
+
41
+ if (isQualifiedLocalUnpublishedSchemaSource(parent?.source || {})) {
42
+ edges.push(freezeEdge({ state: 'qualified-local-supersession', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'qualified-local-unpublished-parent-authority' }));
43
+ continue;
44
+ }
45
+
46
+ const exactCandidates = candidates.filter(completeSourceTuple);
47
+ if (candidates.length !== 1 || exactCandidates.length !== 1) {
48
+ const reason = candidates.length > 1 ? 'ambiguous-parent-source-authority' : 'parent-source-authority-unavailable';
49
+ findings.push(candidates.length > 1
50
+ ? `Declared parent source authority is ambiguous for ${childSchemaId}: ${candidates.length} exact pinned candidates.`
51
+ : `Declared parent source authority is unavailable for ${childSchemaId} -> ${parentSchemaId}.`);
52
+ edges.push(freezeEdge({ state: 'unresolved', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason }));
53
+ continue;
54
+ }
55
+
56
+ const expected = exactCandidates[0];
57
+ if (!sameSourceTuple(parentSource, expected)) {
58
+ findings.push(`Compiled lineage substitutes source authority for ${childSchemaId} -> ${parentSchemaId}: declared ${formatSource(expected)} but compiled ${formatSource(parentSource)}.`);
59
+ edges.push(freezeEdge({ state: 'contradictory', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'compiled-parent-source-substitution' }));
60
+ continue;
61
+ }
62
+
63
+ edges.push(freezeEdge({ state: 'qualified', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'exact-parent-source-match' }));
64
+ }
65
+
66
+ const contradictory = edges.some((edge) => edge.state === 'contradictory') || findings.some((finding) => finding.includes('identity mismatch') || finding.includes('identity is incoherent') || finding.includes('substitutes source authority'));
67
+ const unresolved = !contradictory && (findings.length > 0 || edges.some((edge) => edge.state === 'unresolved'));
68
+ const state = contradictory ? 'contradictory' : unresolved ? 'unresolved' : 'qualified';
69
+ return deepFreeze({
70
+ schema: SCHEMA_LINEAGE_SOURCE_AUTHORITY_QUALIFICATION_SCHEMA_ID,
71
+ state,
72
+ complete: state === 'qualified',
73
+ lineage: Object.freeze([...lineage]),
74
+ edges: Object.freeze(edges),
75
+ findings: Object.freeze(findings),
76
+ boundary: 'Exact runtime validation authority requires source-coherent compiled inheritance. Qualified local unpublished Parent authority may intentionally supersede published Parent locators; all other inheritance edges require one exact declared Parent source tuple matching the compiled Parent material.'
77
+ });
78
+ }
79
+
80
+ export function isQualifiedLocalUnpublishedSchemaSource(source = {}) {
81
+ return String(source?.publicationState || '').trim().toLowerCase() === 'accepted-local-unpublished'
82
+ && String(source?.snapshotCompleteness || '').trim() === 'exact-axiom-canonical-unpublished-bounded-workspace-contract';
83
+ }
84
+
85
+ function normalizeSourceTuple(value = {}) {
86
+ return Object.freeze({
87
+ repository: String(value?.repository || '').trim(),
88
+ commit: String(value?.commit || '').trim().toLowerCase(),
89
+ path: String(value?.path || '').trim()
90
+ });
91
+ }
92
+
93
+ function completeSourceTuple(value = {}) {
94
+ return Boolean(value.repository && /^[0-9a-f]{40}$/.test(value.commit) && value.path);
95
+ }
96
+
97
+ function sameSourceTuple(left = {}, right = {}) {
98
+ return left.repository === right.repository && left.commit === right.commit && left.path === right.path;
99
+ }
100
+
101
+ function formatSource(value = {}) {
102
+ return `${value.repository || '(unknown repo)'}@${value.commit || '(unknown commit)'}/${value.path || '(unknown path)'}`;
103
+ }
104
+
105
+ function freezeEdge(value = {}) {
106
+ return Object.freeze({
107
+ state: String(value.state || 'unresolved'),
108
+ parentSchemaId: String(value.parentSchemaId || ''),
109
+ childSchemaId: String(value.childSchemaId || ''),
110
+ actual: value.actual || Object.freeze({ repository: '', commit: '', path: '' }),
111
+ candidates: value.candidates || Object.freeze([]),
112
+ reason: String(value.reason || '')
113
+ });
114
+ }
115
+
116
+ function deepFreeze(value) {
117
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
118
+ for (const child of Object.values(value)) deepFreeze(child);
119
+ return Object.freeze(value);
120
+ }
@@ -1,5 +1,6 @@
1
1
  import { sha256Hex, utf8Bytes } from '../export/package.bytes.js';
2
2
  import { qualifyGithubSchemaSourceProvider } from './schema.githubSourceTarget.js';
3
+ import { qualifyCompiledSchemaLineageSourceAuthority } from './schema.lineageAuthority.js';
3
4
 
4
5
  export const BUNDLED_SCHEMA_SOURCE_SCHEMA_ID = 'tiinex.site.bundled-schema-source.v1';
5
6
  export const SCHEMA_RUNTIME_PROJECTION_SCHEMA_ID = 'tiinex.site.schema-runtime-projection.v1';
@@ -48,6 +49,7 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
48
49
  ...(!loadedBlobSha ? ['Loaded schema Git-blob identity is unavailable from the runtime projection.'] : [])
49
50
  ])
50
51
  });
52
+ const validationLineageAuthority = qualifyCompiledSchemaLineageSourceAuthority(runtimeProjection.validationContract || {});
51
53
  const validationContract = projectionExact && runtimeProjection.validationContract?.schemaId === schemaId && runtimeProjection.validationContract?.lineageQualification?.state === 'valid'
52
54
  ? runtimeProjection.validationContract
53
55
  : null;
@@ -85,6 +87,7 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
85
87
  authority,
86
88
  bindingMaterialCoherence,
87
89
  materialIdentity,
90
+ validationLineageAuthority,
88
91
  compiledContract,
89
92
  projection: runtimeProjection,
90
93
  findings: Object.freeze([
@@ -93,7 +96,8 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
93
96
  ...(runtimeProjection.sourceChecksum !== expectedChecksum ? ['Schema runtime projection source checksum does not match binding.'] : []),
94
97
  ...(runtimeProjection.bindingChecksum !== expectedChecksum ? ['Schema runtime projection binding checksum does not match binding.'] : []),
95
98
  ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.schemaId !== schemaId ? ['Schema runtime validation projection identity does not match binding.'] : []),
96
- ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.lineageQualification?.state !== 'valid' ? ['Schema runtime validation projection lineage is not exact/valid.'] : [])
99
+ ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.lineageQualification?.state !== 'valid' ? ['Schema runtime validation projection lineage is not exact/valid.'] : []),
100
+ ...(validationLineageAuthority.state !== 'qualified' ? validationLineageAuthority.findings : [])
97
101
  ])
98
102
  });
99
103
  return cached;
@@ -20,6 +20,7 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
20
20
  if (!['handoff', 'workspace', 'bootstrap'].includes(carrierMode)) throw new Error(`portable.cli.handoff-carrier.carrier-mode.invalid:${carrierMode}`);
21
21
  if (carrierMode === 'workspace') return prepareWorkspaceCarrierCliCommand(flags, workspaceRoot, runtime);
22
22
  if (carrierMode === 'bootstrap') return prepareBootstrapCarrierCliCommand(flags, runtime);
23
+ if (flags['package-major'] && flags['package-consolidation']) throw new Error('portable.cli.handoff-carrier.package-major-consolidation-conflict');
23
24
  const continuationState = parsed.surfaceCommand === 'handoff'
24
25
  ? await readGroundContinuationState(workspaceRoot)
25
26
  : {};
@@ -103,6 +104,7 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
103
104
  selectedRoutePointer: continuationState.selectedRoutePointer || flags['package-parent-route-pointer'] || '',
104
105
  selectedRouteId: continuationState.selectedRouteId || flags['package-parent-route-id'] || '',
105
106
  explicitSiblingIndex: flags['package-sibling-index'],
107
+ consolidation: Boolean(flags['package-consolidation']),
106
108
  enabled: Boolean(flags.output || flags['output-dir'])
107
109
  });
108
110
  carrierAllocation = siblingAllocation;
@@ -118,6 +120,8 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
118
120
  packageParentSha256 = String(carrierLineage.parentPackageSha256 || '');
119
121
  } else if (flags['package-major']) {
120
122
  throw new Error('portable.cli.handoff-carrier.package-major.parent-required');
123
+ } else if (flags['package-consolidation']) {
124
+ throw new Error('portable.cli.handoff-carrier.package-consolidation.parent-required');
121
125
  }
122
126
  const carrierProfile = selectCarrierProfile({
123
127
  operator: operatorCarrierProfile,
@@ -97,10 +97,62 @@ export function deriveHandoffSiblingAllocation({ parentInspection = null, select
97
97
  }
98
98
  }
99
99
 
100
+ export function deriveHandoffConsolidationAllocation({ parentInspection = null, explicitSiblingIndex = null, parentPackagePath = '', parentPackageSha256 = '', parentDimension = '' } = {}) {
101
+ const explicit = normalizeSiblingIndex(explicitSiblingIndex);
102
+ const inspection = parentInspection && typeof parentInspection === 'object' ? parentInspection : null;
103
+ if (!inspection || inspection.detected === false) return freeze({
104
+ state: 'unavailable', siblingIndex: null, allocationMode: 'unavailable',
105
+ reasonCode: 'qualified-parent-route-topology-unavailable-for-consolidation',
106
+ provenance: provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
107
+ boundary: consolidationBoundary()
108
+ });
109
+ if (String(inspection.status || '') !== 'valid') return consolidationBlocked('qualified-parent-route-topology-invalid-for-consolidation');
110
+ const routes = [...(inspection.routes || [])];
111
+ if (!routes.length) return consolidationBlocked('qualified-parent-route-topology-empty-for-consolidation');
112
+
113
+ const topology = deriveHandoffSiblingAllocation({
114
+ parentInspection: inspection,
115
+ selectedRoutePointer: String(routes[0]?.pointerPath || ''),
116
+ parentPackagePath, parentPackageSha256, parentDimension
117
+ });
118
+ if (topology.state !== 'qualified') return consolidationBlocked(topology.reasonCode || 'qualified-parent-route-pointer-order-unresolved');
119
+ const routeCount = Number(topology.provenance?.qualifiedRouteCount || 0);
120
+ const siblingIndex = routeCount + 1;
121
+ if (!Number.isInteger(siblingIndex) || siblingIndex < 2 || siblingIndex > MAX_SIBLING_INDEX) return consolidationBlocked('derived-consolidation-sibling-index-out-of-range');
122
+ if (explicit && explicit !== siblingIndex) return consolidationBlocked('explicit-sibling-index-conflicts-with-qualified-consolidation-topology', { expectedSiblingIndex: siblingIndex });
123
+
124
+ return freeze({
125
+ state: 'qualified', siblingIndex,
126
+ childDimension: parentDimension ? `${String(parentDimension).trim()}-${siblingIndex}` : '',
127
+ allocationMode: 'qualified-parent-route-consolidation-ordinal',
128
+ explicitOverride: explicit ? 'matched-derived-value' : 'not-supplied',
129
+ reasonCode: '',
130
+ provenance: {
131
+ ...provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
132
+ basis: 'qualified-parent-route-consolidation-ordinal',
133
+ qualifiedRouteCount: routeCount,
134
+ consolidationOrdinal: siblingIndex,
135
+ commonFrontierDimension: String(parentDimension || '').trim(),
136
+ pointerOrder: topology.provenance.pointerOrder
137
+ },
138
+ boundary: consolidationBoundary()
139
+ });
140
+
141
+ function consolidationBlocked(reasonCode, extra = {}) {
142
+ return freeze({
143
+ state: 'blocked', siblingIndex: null, allocationMode: 'blocked', reasonCode, ...extra,
144
+ provenance: provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
145
+ boundary: consolidationBoundary()
146
+ });
147
+ }
148
+ }
149
+
100
150
  export async function resolveHandoffSiblingAllocation(input = {}) {
101
- const derived = deriveHandoffSiblingAllocation(input);
151
+ const consolidation = input.consolidation === true;
152
+ const derived = consolidation ? deriveHandoffConsolidationAllocation(input) : deriveHandoffSiblingAllocation(input);
102
153
  if (derived.state === 'qualified') return derived;
103
154
  if (derived.state === 'blocked') throw new Error(`portable.cli.handoff-carrier.sibling-allocation.${derived.reasonCode}`);
155
+ if (consolidation) throw new Error('portable.cli.handoff-carrier.sibling-allocation.qualified-parent-route-topology-required-for-consolidation');
104
156
  const explicit = normalizeSiblingIndex(input.explicitSiblingIndex ?? input.siblingIndex);
105
157
  if (!explicit) throw new Error('portable.cli.handoff-carrier.sibling-allocation.explicit-index-required-when-topology-unavailable');
106
158
  const legacy = await reserveHandoffSiblingIndex({
@@ -172,6 +224,7 @@ function provenanceBase({ parentPackagePath = '', parentPackageSha256 = '', pare
172
224
  explicitSiblingIndex: explicitSiblingIndex ? normalizeSiblingIndex(explicitSiblingIndex) : null
173
225
  };
174
226
  }
227
+ function consolidationBoundary() { return 'Transport-only carrier consolidation allocation. The consolidation sibling is exactly N+1 for N qualified Handoff routes on the common pre-batch carrier frontier. It is never derived from one specialist return, arrival order, retries, output collisions, local allocation files or artifact Parent lineage; explicit Major stabilization remains separate.'; }
175
228
  function allocationBoundary() { return 'Transport-only carrier allocation. A non-Major sibling ordinal may come only from exact qualified package-local Handoff Pointer order for the selected parent route, or from an explicit advanced override when such topology is unavailable. Allocation never creates semantic Parent, Workspace, Role, acceptance, completion, participant, process, or source authority; different carrier prefixes are not coordinated.'; }
176
229
  function normalizeSiblingIndex(value) {
177
230
  if (value === null || value === undefined || value === '') return 0;
@@ -63,9 +63,9 @@ function commonCommandHelp(command, surfaceCommand) {
63
63
  `${command} ground <handoff-package.zip> --route <Continue-from> [--holder-role <recipient-role>]`,
64
64
  `${command} ground <handoff-package.zip> --route <Continue-from> --holder-role <recipient-role> --continue <workspace-dir>`,
65
65
  '',
66
- 'Reads and qualifies the exact selected Handoff route. The default projection keeps readiness, recipient authority boundary, explicit consuming-session holder binding, Required Context closure, continuity/blockers, current Task identity, and exact next action compact; add `--full` for the full qualified receipt.',
66
+ 'Reads and qualifies the exact selected Handoff route. The default projection keeps readiness, recipient authority boundary, consuming-session holder binding, Required Context closure, continuity/blockers, current Task identity, and exact next action compact; add `--full` for the full qualified receipt.',
67
67
  'Add `--include-required-context <requirement-id,name|all>` and/or `--include-current-work` only when exact body text is needed. `ground --continue` includes the bounded current Task body needed to proceed, retains Required Context counts and continuity/recovery state, and does not repeat qualified Required Context item paths or root-detail receipts unless explicitly requested (or `--full` is used).',
68
- 'For a Role recipient, `--holder-role <recipient-role>` is an explicit consuming-session Role-capacity binding; it is never inferred from route selection, provider identity, or assistant/user position. Without it, the holder remains unresolved and grounding stays discussion-only. After `grounded-to-act`, `--continue` materializes the selected carried Workspace into an empty local directory and writes runtime-only `.tiinex/continuation.json`. The grounding operation itself is non-mutating; downstream work authority comes from qualified Handoff/Task/Role artifacts, not from that operation-safety fact.',
68
+ 'For a Role recipient, exact qualified consumption of the selected Handoff may establish the bounded consuming-session Role-capacity binding when the exact qualified recipient Role authorizes canonical Assignment Mode `handoff`. `--holder-role <recipient-role>` remains an explicit consuming-session assertion and must match the selected recipient; mismatches block and never fall back to Handoff assignment. No binding is inferred from package delivery, route orientation alone, provider identity, or assistant/user position. After `grounded-to-act`, `--continue` materializes the selected carried Workspace into an empty local directory and writes runtime-only `.tiinex/continuation.json`. The grounding operation itself is non-mutating; downstream work authority comes from qualified Handoff/Task/Role artifacts, not from that operation-safety fact.',
69
69
  '',
70
70
  `Advanced/internal catalog: ${command} operations`
71
71
  ];
@@ -83,7 +83,7 @@ function commonCommandHelp(command, surfaceCommand) {
83
83
  '',
84
84
  `${command} handoff <workspace-dir>`,
85
85
  '',
86
- 'Infers the latest qualified authored Handoff, selected Workspace identity/target, received package parent as carrier-lineage evidence, canonical projected filename, and return output directory. Ordinary non-Major continuation derives its sibling ordinal from the exact qualified selected Handoff Pointer order in the received parent carrier, so common-path `handoff` does not require `--package-sibling-index` or `--return-package-sibling-index`. A single selected Pointer derives `-1`; parallel qualified Pointers derive dense local ordinals in Pointer order, and each returned branch continues from its own carrier. `--package-sibling-index` remains an advanced compatibility override only when qualified route topology is unavailable, and must match when topology already proves the value; conflicting or ambiguous topology fails closed. `--return-package-major` remains the explicit Major-return declaration. Different carrier prefixes are never globally coordinated. Byte-identical duplicate transport at one exact output path is idempotent and divergent bytes fail closed. It does not implicitly carry sibling Workspaces from the received package; advanced manufacture must select exact reusable parent snapshots with `--package-parent-workspaces <id,...|all>`. Recovery/integration manufacture can bind the reconciled byte proof with `--require-reconciliation-proof --reconciliation-proof <full-reconcile-receipt.json>`; missing, non-ready, edited, or source-stale proof blocks package output. The default receipt keeps output identity, routing text, closure/workspace qualification, verification, and actionable findings compact; add `--full` for the complete manufacture receipt. Normal operator completion is exactly one Handoff package plus the adjacent exact routing text. In markdown-capable hosts render that routing in a fenced code block; do not emit canonical Workspace Evidence/Handoff markdown as additional loose transport files. Runtime-only `.tiinex` state is excluded from canonical manufacture.',
86
+ 'Infers the latest qualified authored Handoff, selected Workspace identity/target, received package parent as carrier-lineage evidence, canonical projected filename, and return output directory. Ordinary non-Major continuation derives its sibling ordinal from the exact qualified selected Handoff Pointer order in the received parent carrier, so common-path `handoff` does not require `--package-sibling-index` or `--return-package-sibling-index`. A single selected Pointer derives `-1`; parallel qualified Pointers derive dense local ordinals in Pointer order, and each returned branch continues from its own carrier. Advanced manufacture may declare `--package-consolidation` against the common pre-batch parent carrier; with N qualified route Pointers it derives consolidation ordinal N+1 and rejects conflicting overrides or missing qualified common-frontier topology. `--package-sibling-index` remains an advanced compatibility override only when qualified route topology is unavailable for ordinary route returns, and must match when topology already proves the value; conflicting or ambiguous topology fails closed. `--return-package-major` remains the explicit Major-return declaration. Different carrier prefixes are never globally coordinated. Byte-identical duplicate transport at one exact output path is idempotent and divergent bytes fail closed. It does not implicitly carry sibling Workspaces from the received package; advanced manufacture must select exact reusable parent snapshots with `--package-parent-workspaces <id,...|all>`. Recovery/integration manufacture can bind the reconciled byte proof with `--require-reconciliation-proof --reconciliation-proof <full-reconcile-receipt.json>`; missing, non-ready, edited, or source-stale proof blocks package output. The default receipt keeps output identity, routing text, closure/workspace qualification, verification, and actionable findings compact; add `--full` for the complete manufacture receipt. Normal operator completion is exactly one Handoff package plus the adjacent exact routing text. In markdown-capable hosts render that routing in a fenced code block; do not emit canonical Workspace Evidence/Handoff markdown as additional loose transport files. Runtime-only `.tiinex` state is excluded from canonical manufacture.',
87
87
  '',
88
88
  `Advanced/internal catalog: ${command} operations`
89
89
  ];
@@ -181,7 +181,7 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
181
181
  const dependencyClosure = await expandPointerDependencyClosure({ requirements, materials, workspaceRuntimeById, bindings: input.materialBindings || {} });
182
182
  requirements = dependencyClosure.requirements;
183
183
  materials = appendMissingRequirementMaterials(dependencyClosure.materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
184
- const routeParentBoundaryClosure = expandRouteParentBoundaryClosure({ requirements, materials, workspaceMaterializations, workspaceRuntimeById, routeSpecs });
184
+ const routeParentBoundaryClosure = expandRouteParentBoundaryClosure({ requirements, materials, workspaceMaterializations, workspaceRuntimeById, routeSpecs, exactMaterialProvider: packageParentExactMaterialProvider });
185
185
  requirements = routeParentBoundaryClosure.requirements;
186
186
  materials = appendMissingRequirementMaterials(routeParentBoundaryClosure.materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
187
187
  const parentBoundaryClosure = expandBoundedParentBoundaryClosure({ requirements, materials, workspaceMaterializations, workspaceRuntimeById });
@@ -166,10 +166,9 @@ export function expandRouteParentBoundaryClosure(input = {}) {
166
166
  const visitKey = `${currentWorkspaceId}\0${currentPath}`;
167
167
  if (visited.has(visitKey)) break;
168
168
  visited.add(visitKey);
169
- const runtime = input.workspaceRuntimeById?.get(currentWorkspaceId);
170
- const currentEntry = runtime ? entryFromEnumeration(runtime.enumeration, currentPath) : null;
171
- if (!currentEntry) break;
172
- const markdown = decodeUtf8(currentEntry.data);
169
+ const currentSource = exactArtifactSource(input, materials, currentWorkspaceId, currentPath);
170
+ if (!currentSource) break;
171
+ const markdown = decodeUtf8(currentSource.data);
173
172
  if (!markdown) break;
174
173
  let parent;
175
174
  try { parent = parseArtifactMarkdown(markdown).envelope?.parent || {}; } catch { break; }
@@ -188,8 +187,7 @@ export function expandRouteParentBoundaryClosure(input = {}) {
188
187
  }
189
188
  if (!targetWorkspaceId || !targetPath) break;
190
189
 
191
- const targetRuntime = input.workspaceRuntimeById?.get(targetWorkspaceId);
192
- const targetEntry = targetRuntime ? entryFromEnumeration(targetRuntime.enumeration, targetPath) : null;
190
+ const targetSource = exactArtifactSource(input, materials, targetWorkspaceId, targetPath);
193
191
  const targetMaterialization = materializationByWorkspaceId.get(targetWorkspaceId);
194
192
  const targetAlreadyCarried = workspaceMaterializationIncludesPath(targetMaterialization, targetPath);
195
193
  const routeTargetKey = `${routeWorkspaceId}\0${routePath}\0${targetWorkspaceId}\0${targetPath}`;
@@ -217,10 +215,10 @@ export function expandRouteParentBoundaryClosure(input = {}) {
217
215
  fields: Object.freeze({ RouteWorkspace: routeWorkspaceId, RoutePath: routePath, SourceWorkspace: currentWorkspaceId, SourcePath: currentPath, TargetWorkspace: targetWorkspaceId, TargetPath: targetPath, Reference: reference })
218
216
  });
219
217
  dependencies.push(requirement);
220
- if (targetEntry) materials.push(materialCandidateFromWorkspaceEntry(requirement, targetWorkspaceId, targetPath, targetEntry, targetRuntime.enumeration, targetRuntime));
218
+ if (targetSource) materials.push(materialCandidateFromExactArtifactSource(requirement, targetSource));
221
219
  }
222
220
  }
223
- if (!targetEntry) break;
221
+ if (!targetSource) break;
224
222
  currentWorkspaceId = targetWorkspaceId;
225
223
  currentPath = targetPath;
226
224
  }
@@ -232,6 +230,81 @@ export function expandRouteParentBoundaryClosure(input = {}) {
232
230
  });
233
231
  }
234
232
 
233
+ function exactArtifactSource(input = {}, materials = [], workspaceIdValue = '', targetPathValue = '') {
234
+ const workspaceId = String(workspaceIdValue || '').trim();
235
+ const targetPath = normalizeRelativePath(targetPathValue);
236
+ if (!workspaceId || !targetPath) return null;
237
+
238
+ // Explicit current/inherited Workspace providers retain precedence over detached cache
239
+ // material. This preserves the existing package-parent precedence boundary while allowing
240
+ // the exact same route traversal to continue when the next ancestor is cache-only.
241
+ const runtime = input.workspaceRuntimeById?.get(workspaceId);
242
+ const entry = runtime ? entryFromEnumeration(runtime.enumeration, targetPath) : null;
243
+ if (entry) return Object.freeze({
244
+ kind: 'workspace-entry', workspaceId, path: targetPath, data: entry.data, bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''),
245
+ mediaType: String(entry.mediaType || 'text/markdown'), entry, runtime
246
+ });
247
+
248
+ const candidates = [];
249
+ for (const material of materials || []) {
250
+ const provenance = material?.provenance || {};
251
+ const candidateWorkspaceId = String(provenance.workspaceId || material.workspaceId || material.targetWorkspaceId || '').trim();
252
+ const candidatePath = normalizeRelativePath(provenance.path || material.path || material.targetPath || '');
253
+ if (candidateWorkspaceId !== workspaceId || candidatePath !== targetPath || !material?.data) continue;
254
+ candidates.push(Object.freeze({
255
+ kind: 'qualified-material', workspaceId, path: targetPath, data: material.data, bytes: Number(material.bytes || 0), sha256: String(material.sha256 || ''),
256
+ mediaType: String(material.mediaType || 'text/markdown'), providerId: String(material.providerId || ''), providerKind: String(material.providerKind || ''),
257
+ provenance: Object.freeze({ ...provenance }), authority: Object.freeze({ ...(material.authority || {}) })
258
+ }));
259
+ }
260
+ for (const material of input.exactMaterialProvider?.entries || []) {
261
+ const provenance = material?.provenance || {};
262
+ const candidateWorkspaceId = String(provenance.workspaceId || '').trim();
263
+ const candidatePath = normalizeRelativePath(provenance.path || '');
264
+ if (candidateWorkspaceId !== workspaceId || candidatePath !== targetPath || !material?.data) continue;
265
+ candidates.push(Object.freeze({
266
+ kind: 'qualified-material', workspaceId, path: targetPath, data: material.data, bytes: Number(material.bytes || 0), sha256: String(material.sha256 || ''),
267
+ mediaType: String(material.mediaType || 'text/markdown'), providerId: String(material.providerId || 'qualified-package-parent-exact-material'),
268
+ providerKind: String(material.providerKind || 'qualified-package-parent-cache-material'), provenance: Object.freeze({ ...provenance }),
269
+ authority: Object.freeze({ packageParentMaterialQualified: true, semanticAuthority: 'none', sourceSelectionAuthority: false })
270
+ }));
271
+ }
272
+ if (!candidates.length) return null;
273
+ const digests = [...new Set(candidates.map((candidate) => String(candidate.sha256 || '')).filter(Boolean))];
274
+ if (digests.length !== 1) return null;
275
+ return candidates.find((candidate) => candidate.sha256 === digests[0]) || null;
276
+ }
277
+
278
+ function materialCandidateFromExactArtifactSource(requirement = {}, source = {}) {
279
+ if (source.kind === 'workspace-entry') {
280
+ return materialCandidateFromWorkspaceEntry(requirement, source.workspaceId, source.path, source.entry, source.runtime.enumeration, source.runtime);
281
+ }
282
+ return Object.freeze({
283
+ requirementId: String(requirement.id || ''),
284
+ referenceTarget: String(requirement.reference?.target || requirement.referenceTarget || ''),
285
+ path: String(source.path || ''),
286
+ data: source.data,
287
+ bytes: Number(source.bytes || 0),
288
+ sha256: String(source.sha256 || ''),
289
+ mediaType: String(source.mediaType || 'text/markdown'),
290
+ providerId: String(source.providerId || 'qualified-exact-material'),
291
+ providerKind: String(source.providerKind || 'qualified-exact-material'),
292
+ provenance: Object.freeze({
293
+ ...(source.provenance || {}),
294
+ workspaceId: String(source.workspaceId || source.provenance?.workspaceId || ''),
295
+ path: String(source.path || source.provenance?.path || ''),
296
+ reboundRequirementId: String(requirement.id || ''),
297
+ reboundClassification: String(requirement.classification || '')
298
+ }),
299
+ authority: Object.freeze({
300
+ ...(source.authority || {}),
301
+ localIdentityQualified: true,
302
+ semanticAuthority: 'none',
303
+ sourceSelectionAuthority: false
304
+ })
305
+ });
306
+ }
307
+
235
308
  function workspaceMaterializationIncludesPath(materialization = null, targetPath = '') {
236
309
  if (!materialization) return false;
237
310
  const state = String(materialization.state || materialization.materialization || '');
@@ -14,7 +14,7 @@ export function projectParticipantAuthority(authority = null) {
14
14
  participantIdentityCreatesAuthority: false,
15
15
  conversationPositionCreatesAuthority: false,
16
16
  universalHumanFeedbackRule: false,
17
- boundary: 'Qualified Role material plus explicit holder binding is the basis. Identity/chat position alone create no authority; no universal human-input-as-feedback rule is imposed.'
17
+ boundary: 'Qualified Role material plus a qualified holder binding is the basis; that binding may be explicit or may come from exact qualified selected-Handoff consumption when the Role authorizes `handoff`. Identity/chat position alone create no authority; no universal human-input-as-feedback rule is imposed.'
18
18
  });
19
19
  }
20
20
  function compact(value = '', limit = 180) { const text = String(value || '').replace(/\s+/g, ' ').trim(); return text.length > limit ? `${text.slice(0, limit - 1).trimEnd()}…` : text; }
@@ -55,12 +55,18 @@ export function projectGroundingAuthority(authority, mode) {
55
55
  explicit: Boolean(authority.holderBinding.explicit),
56
56
  inferredFromTransport: Boolean(authority.holderBinding.inferredFromTransport),
57
57
  provenance: Object.freeze({
58
- basis: authority.holderBinding.explicit ? 'explicit-consuming-session-holder-binding' : 'unresolved-or-non-explicit-holder-binding',
58
+ basis: authority.holderBinding.explicit ? 'explicit-consuming-session-holder-binding' : (authority.holderBinding.source === 'qualified-selected-handoff-consumption' && String(authority.holderBinding.state || '') === 'qualified' ? 'qualified-selected-handoff-consumption-binding' : 'unresolved-or-non-explicit-holder-binding'),
59
59
  source: authority.holderBinding.source || '',
60
60
  sourceKind: authority.holderBinding.sourceDetail?.kind || '',
61
61
  sourceLocator: authority.holderBinding.sourceDetail?.locator || '',
62
62
  semanticAuthorityState: authority.holderBinding.sourceDetail?.semanticAuthorityState || 'not-established',
63
63
  qualifiedMaterialSource: Boolean(authority.holderBinding.sourceDetail?.qualifiedMaterialSource),
64
+ assignmentMode: authority.holderBinding.assertionMode || authority.holderBinding.authorization?.assignmentMode || '',
65
+ routePointerPath: authority.holderBinding.sourceDetail?.routePointerPath || '',
66
+ handoffArtifactPath: authority.holderBinding.sourceDetail?.handoffArtifactPath || '',
67
+ handoffArtifactSha256: authority.holderBinding.sourceDetail?.handoffArtifactSha256 || '',
68
+ roleArtifactPath: authority.holderBinding.sourceDetail?.roleArtifactPath || authority.holderBinding.authorization?.provenance?.roleArtifactPath || '',
69
+ roleArtifactSha256: authority.holderBinding.sourceDetail?.roleArtifactSha256 || authority.holderBinding.authorization?.provenance?.roleArtifactSha256 || '',
64
70
  authorizationState: authority.holderBinding.authorization?.state || 'unresolved',
65
71
  authorizationBasis: authority.holderBinding.authorization?.provenance?.basis || '',
66
72
  boundary: authority.holderBinding.boundary || 'Consuming-session holder identity is never inferred from route transport or recipient position.'
@@ -129,7 +129,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
129
129
  } else {
130
130
  holderBindingActReady = false;
131
131
  unresolved.push(evidence('session-holder-role-binding', 'unresolved', `recipient Role ${authority?.role?.endpoint?.label || authority?.handoff?.to || 'recipient'} is qualified separately from the consuming session`));
132
- reasons.push(reason('session-holder-role-binding-unresolved', 'The selected recipient Role does not assign itself to this consuming session. Supply an explicit matching session holder Role binding before act-ready continuation.'));
132
+ reasons.push(reason('session-holder-role-binding-unresolved', 'The selected recipient Role is not yet bound to this consuming session. Exact qualified selected-Handoff consumption may bind it only when the exact recipient Role authorizes Assignment Mode `handoff`; otherwise supply an explicit matching session holder Role binding authorized by that Role.'));
133
133
  }
134
134
 
135
135
  if (holderState === 'not-applicable') {
@@ -142,7 +142,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
142
142
  } else {
143
143
  holderBindingActReady = false;
144
144
  unresolved.push(evidence('session-holder-role-binding-authorization', holderAuthorizationState || 'unresolved', authority?.holderBinding?.authorization?.reasonCode || 'exact qualified canonical assignment-mode authority does not authorize the asserted binding mechanism'));
145
- reasons.push(reason('session-holder-role-binding-authorization-unresolved', 'The explicit consuming-session Role assertion matches the selected recipient Role, but exact qualified canonical assignment-mode authority does not authorize the asserted mechanism. Matching session input alone cannot make the route act-ready.'));
145
+ reasons.push(reason('session-holder-role-binding-authorization-unresolved', 'The consuming-session Role binding matches the selected recipient Role, but exact qualified canonical assignment-mode authority does not authorize the asserted mechanism. Matching session input or Handoff selection alone cannot make the route act-ready.'));
146
146
  }
147
147
  }
148
148
 
@@ -368,12 +368,12 @@ function projectCurrentWork(topology = {}, records = [], includeCurrentWork = fa
368
368
  }
369
369
 
370
370
  function nextActionFor(state, topology, continuity = {}, authority = null) {
371
- if (state === 'grounded-to-act') return Object.freeze({ kind: 'continue-bounded-handoff-work', target: topology.currentFrontier[0]?.path || '', basis: 'qualified authority + explicit session holder Role binding + exact qualified holder-assignment authorization when Role-recipient + required context + cold-start root continuity + selected-route Parent leaf + declared current-work frontier' });
372
- if (state === 'grounded-to-discuss' && String(authority?.holderBinding?.state || 'unresolved') === 'unresolved') return Object.freeze({ kind: 'declare-explicit-session-holder-role-binding', target: authority?.role?.endpoint?.label || authority?.handoff?.to || '', basis: 'recipient Role qualification is separate from consuming-session holder binding; no transport/provider/assistant-user identity inference is permitted' });
371
+ if (state === 'grounded-to-act') return Object.freeze({ kind: 'continue-bounded-handoff-work', target: topology.currentFrontier[0]?.path || '', basis: 'qualified authority + qualified session holder Role binding (explicit or exact selected-Handoff consumption) + exact qualified holder-assignment authorization when Role-recipient + required context + cold-start root continuity + selected-route Parent leaf + declared current-work frontier' });
372
+ if (state === 'grounded-to-discuss' && String(authority?.holderBinding?.state || 'unresolved') === 'unresolved') return Object.freeze({ kind: 'establish-session-holder-role-binding', target: authority?.role?.endpoint?.label || authority?.handoff?.to || '', basis: 'recipient Role qualification is separate from consuming-session holder binding; exact qualified selected-Handoff consumption may establish `handoff` assignment when authorized, otherwise an explicit authorized binding is required; no transport/provider/assistant-user identity inference is permitted' });
373
373
  if (state === 'grounded-to-discuss' && String(authority?.holderBinding?.state || '') === 'qualified' && String(authority?.holderBinding?.authorization?.state || 'unresolved') !== 'qualified') return Object.freeze({
374
374
  kind: 'resolve-session-holder-binding-authorization',
375
375
  target: authority?.holderBinding?.authorization?.provenance?.roleArtifactPath || authority?.role?.endpoint?.label || authority?.handoff?.to || '',
376
- basis: 'a matching explicit session Role assertion is not semantic authorization; exact qualified recipient Role Holder Relationship authority must establish the assignment mode'
376
+ basis: 'a matching session Role binding is not semantic authorization by itself; exact qualified recipient Role Holder Relationship authority must establish the selected assignment mode'
377
377
  });
378
378
  if (state === 'grounded-to-discuss') return Object.freeze({ kind: topology.currentFrontier.length ? 'obtain-bounded-action-authority-or-human-gate' : 'resolve-current-work-frontier', target: topology.currentTasks[0]?.path || '', basis: 'discussion-ready but act-readiness condition is unresolved' });
379
379
  if (continuity?.state === 'unproven') return Object.freeze({
@@ -129,10 +129,22 @@ function resolveDescriptorMaterial(bundle, descriptor, byteProvider, target = ''
129
129
  const expectedRouteWorkspaceId = String(routeWorkspaceId || '');
130
130
  const expectedRoutePath = normalizeWorkspacePath(routePath || '');
131
131
  const matches = (descriptor.materialized || []).filter((entry) => {
132
- if (expectedRequirementId && String(entry.requirementId || '') !== expectedRequirementId) return false;
132
+ const entryRequirementId = String(entry.requirementId || '');
133
+ const entrySourceRequirementId = String(entry.sourceRequirementId || '');
134
+ const entryRouteWorkspaceId = String(entry.routeWorkspaceId || '');
135
+ const entryRoutePath = normalizeWorkspacePath(entry.routePath || '');
136
+ const exactRequirementMatch = !expectedRequirementId || entryRequirementId === expectedRequirementId;
137
+ const routeScopedSourceMatch = Boolean(
138
+ expectedRequirementId &&
139
+ entrySourceRequirementId === expectedRequirementId &&
140
+ expectedRouteWorkspaceId && expectedRoutePath &&
141
+ entryRouteWorkspaceId === expectedRouteWorkspaceId &&
142
+ entryRoutePath === expectedRoutePath
143
+ );
144
+ if (expectedRequirementId && !exactRequirementMatch && !routeScopedSourceMatch) return false;
133
145
  if (expectedTarget && String(entry.referenceTarget || '') !== expectedTarget) return false;
134
- if (expectedRouteWorkspaceId && entry.routeWorkspaceId && String(entry.routeWorkspaceId || '') !== expectedRouteWorkspaceId) return false;
135
- if (expectedRoutePath && entry.routePath && normalizeWorkspacePath(entry.routePath || '') !== expectedRoutePath) return false;
146
+ if (expectedRouteWorkspaceId && entryRouteWorkspaceId && entryRouteWorkspaceId !== expectedRouteWorkspaceId) return false;
147
+ if (expectedRoutePath && entryRoutePath && entryRoutePath !== expectedRoutePath) return false;
136
148
  return Boolean(expectedTarget || expectedRequirementId);
137
149
  });
138
150
  const byRepresentation = new Map();
@@ -247,82 +247,110 @@ function groundHolderBinding(input, handoff, role, findings) {
247
247
  const recipientRoleKind = normalizeToken(handoff.toKind || (recipientRoleLabel ? 'role' : ''));
248
248
  const roleRecipient = recipientRoleKind === 'role';
249
249
  const explicitlySupplied = Boolean(roleLabel || holderId);
250
- const sourceDetail = holderBindingSourceDetail(input, explicit, explicitlySupplied);
251
- const assertionMode = String(explicit.assignmentMode || explicit.bindingMode || explicit.mechanism || input.holderAssignmentMode || input.sessionAssignmentMode || 'explicit-session').trim();
252
- const authorization = projectHolderBindingAuthorization(role, { assertionMode });
253
250
  const durableIdentity = holderDurableIdentityProjection(holderId);
254
251
 
255
- if (!roleRecipient) return deepFreeze({
256
- state: 'not-applicable',
257
- holderId,
258
- assertionMode,
259
- roleLabel,
260
- recipientRoleLabel,
261
- recipientCompatibility: 'not-applicable',
262
- source: explicitlySupplied ? 'explicit-input' : 'none',
263
- sourceDetail,
264
- authorization,
265
- durableIdentity,
266
- explicit: explicitlySupplied,
267
- inferredFromTransport: false,
268
- boundary: 'The selected Handoff recipient is not a Role endpoint, so no consuming-session Role holder binding is required or inferred.'
269
- });
252
+ if (!roleRecipient) {
253
+ const assertionMode = String(explicit.assignmentMode || explicit.bindingMode || explicit.mechanism || input.holderAssignmentMode || input.sessionAssignmentMode || 'explicit-session').trim();
254
+ const sourceDetail = holderBindingSourceDetail(input, explicit, explicitlySupplied);
255
+ const authorization = projectHolderBindingAuthorization(role, { assertionMode });
256
+ return deepFreeze({
257
+ state: 'not-applicable', holderId, assertionMode, roleLabel, recipientRoleLabel,
258
+ recipientCompatibility: 'not-applicable', source: explicitlySupplied ? 'explicit-input' : 'none', sourceDetail,
259
+ authorization, durableIdentity, explicit: explicitlySupplied, inferredFromTransport: false,
260
+ boundary: 'The selected Handoff recipient is not a Role endpoint, so no consuming-session Role holder binding is required or inferred.'
261
+ });
262
+ }
263
+
264
+ if (!explicitlySupplied) {
265
+ const assertionMode = 'handoff';
266
+ const authorization = projectHolderBindingAuthorization(role, { assertionMode });
267
+ const exactHandoff = exactSelectedHandoffAssignmentEvidence(handoff, role);
268
+ const sourceDetail = handoffHolderBindingSourceDetail(handoff, role, exactHandoff, authorization);
269
+ if (exactHandoff && authorization.state === 'qualified') return deepFreeze({
270
+ state: 'qualified', holderId: '', assertionMode, roleLabel: recipientRoleLabel, recipientRoleLabel,
271
+ recipientCompatibility: 'matched', source: 'qualified-selected-handoff-consumption', sourceDetail,
272
+ authorization, durableIdentity, explicit: false, inferredFromTransport: false,
273
+ boundary: 'Qualified consumption of the exact selected Handoff binds this bounded Tooling session to its exact recipient Role only because that exact qualified Role authorizes the canonical `handoff` assignment mode. Package delivery, route position, provider/chat identity and Role inventory alone do not bind a holder; durable identity and broader semantic authority remain unestablished.'
274
+ });
275
+ return deepFreeze({
276
+ state: 'unresolved', holderId: '', assertionMode, roleLabel: '', recipientRoleLabel,
277
+ recipientCompatibility: 'unresolved', source: exactHandoff ? 'qualified-selected-handoff-consumption' : 'none', sourceDetail,
278
+ authorization, durableIdentity, explicit: false, inferredFromTransport: false,
279
+ boundary: 'No explicit holder declaration was supplied, and bounded Handoff assignment can qualify only from the exact selected qualified Handoff plus exact recipient Role material that directly authorizes the canonical `handoff` mode. Transport delivery, endpoint naming, cached Role inventory and assistant/user position are insufficient.'
280
+ });
281
+ }
282
+
283
+ const sourceDetail = holderBindingSourceDetail(input, explicit, true);
284
+ const assertionMode = String(explicit.assignmentMode || explicit.bindingMode || explicit.mechanism || input.holderAssignmentMode || input.sessionAssignmentMode || 'explicit-session').trim();
285
+ const authorization = projectHolderBindingAuthorization(role, { assertionMode });
270
286
 
271
287
  if (!roleLabel) {
272
288
  if (holderId) findings.push(portableFinding('warning', 'portable.cold-start.holder-binding.role-missing', 'A consuming-session holder identifier was supplied without an explicit Role capacity; the holder binding remains unresolved.', { holderId, recipientRole: recipientRoleLabel }));
273
289
  return deepFreeze({
274
- state: 'unresolved',
275
- holderId,
276
- assertionMode,
277
- roleLabel: '',
278
- recipientRoleLabel,
279
- recipientCompatibility: 'unresolved',
280
- source: explicitlySupplied ? 'explicit-input' : 'none',
281
- sourceDetail,
282
- authorization,
283
- durableIdentity,
284
- explicit: explicitlySupplied,
285
- inferredFromTransport: false,
286
- boundary: 'Recipient Role and consuming-session holder are separate. No holder Role is inferred from route selection, transport identity, provider identity, assistant/user position, or participant declarations.'
290
+ state: 'unresolved', holderId, assertionMode, roleLabel: '', recipientRoleLabel,
291
+ recipientCompatibility: 'unresolved', source: 'explicit-input', sourceDetail, authorization, durableIdentity,
292
+ explicit: true, inferredFromTransport: false,
293
+ boundary: 'A partial explicit holder declaration is not completed from the Handoff path. Explicit-session and Handoff assignment remain mode-isolated.'
287
294
  });
288
295
  }
289
296
 
290
297
  if (recipientRoleLabel && normalizeComparable(roleLabel) !== normalizeComparable(recipientRoleLabel)) {
291
298
  findings.push(portableFinding('error', 'portable.cold-start.holder-binding.role-mismatch', 'Explicit consuming-session holder Role does not match the selected Handoff recipient Role.', { holderRole: roleLabel, recipientRole: recipientRoleLabel }));
292
299
  return deepFreeze({
293
- state: 'blocked',
294
- holderId,
295
- assertionMode,
296
- roleLabel,
297
- recipientRoleLabel,
298
- recipientCompatibility: 'mismatch',
299
- source: 'explicit-input',
300
- sourceDetail,
301
- authorization,
302
- durableIdentity,
303
- explicit: true,
304
- inferredFromTransport: false,
305
- boundary: 'An explicit holder Role mismatch is contradictory and blocks act-ready grounding. Tooling does not relabel the session to make the route fit.'
300
+ state: 'blocked', holderId, assertionMode, roleLabel, recipientRoleLabel,
301
+ recipientCompatibility: 'mismatch', source: 'explicit-input', sourceDetail, authorization, durableIdentity,
302
+ explicit: true, inferredFromTransport: false,
303
+ boundary: 'An explicit holder Role mismatch is contradictory and blocks act-ready grounding. Tooling does not relabel the session or fall back to Handoff assignment to make the route fit.'
306
304
  });
307
305
  }
308
306
 
309
307
  return deepFreeze({
310
- state: 'qualified',
311
- holderId,
312
- assertionMode,
313
- roleLabel,
314
- recipientRoleLabel,
315
- recipientCompatibility: 'matched',
316
- source: 'explicit-input',
317
- sourceDetail,
318
- authorization,
319
- durableIdentity,
320
- explicit: true,
321
- inferredFromTransport: false,
308
+ state: 'qualified', holderId, assertionMode, roleLabel, recipientRoleLabel,
309
+ recipientCompatibility: 'matched', source: 'explicit-input', sourceDetail, authorization, durableIdentity,
310
+ explicit: true, inferredFromTransport: false,
322
311
  boundary: 'Explicit consuming-session Role-capacity binding only. This binds the current Tooling invocation/session to the selected recipient Role capacity; it does not prove a human identity, consent, or authority beyond the qualified Handoff/Role/Task boundaries.'
323
312
  });
324
313
  }
325
314
 
315
+ function exactSelectedHandoffAssignmentEvidence(handoff = {}, role = {}) {
316
+ const artifact = role?.material?.artifact || {};
317
+ return String(handoff.schemaId || '') === 'tiinex.handoff.v1'
318
+ && Boolean(String(handoff.routeId || '').trim())
319
+ && Boolean(String(handoff.routePointerPath || '').trim())
320
+ && Boolean(String(handoff.workspaceRelativePath || '').trim())
321
+ && /^[0-9a-f]{64}$/i.test(String(handoff.sha256 || ''))
322
+ && String(role?.state || '') === 'qualified'
323
+ && String(role?.material?.state || '') === 'qualified'
324
+ && Boolean(String(artifact.path || '').trim())
325
+ && /^[0-9a-f]{64}$/i.test(String(artifact.sha256 || ''));
326
+ }
327
+
328
+ function handoffHolderBindingSourceDetail(handoff = {}, role = {}, exactHandoff = false, authorization = {}) {
329
+ const artifact = role?.material?.artifact || {};
330
+ const qualified = exactHandoff && String(authorization?.state || '') === 'qualified';
331
+ return deepFreeze({
332
+ kind: exactHandoff ? 'qualified-selected-handoff-consumption' : 'none',
333
+ locator: exactHandoff ? String(handoff.routePointerPath || handoff.workspaceRelativePath || '') : '',
334
+ authorityClass: exactHandoff ? 'selected-handoff-assignment-evidence' : 'none',
335
+ semanticAuthorityState: qualified ? 'qualified-bounded-handoff-assignment' : 'not-established',
336
+ qualifiedMaterialSource: Boolean(exactHandoff),
337
+ assignmentMode: 'handoff',
338
+ routeId: String(handoff.routeId || ''),
339
+ routePointerPath: String(handoff.routePointerPath || ''),
340
+ handoffArtifactPath: String(handoff.workspaceRelativePath || ''),
341
+ handoffArtifactSha256: String(handoff.sha256 || ''),
342
+ roleArtifactPath: String(artifact.path || ''),
343
+ roleArtifactSha256: String(artifact.sha256 || ''),
344
+ roleSchemaId: String(artifact.schemaId || ''),
345
+ roleLabel: String(artifact.roleLabel || role?.endpoint?.label || ''),
346
+ authorizationState: String(authorization?.state || 'unresolved'),
347
+ authorizationBasis: String(authorization?.provenance?.basis || ''),
348
+ boundary: exactHandoff
349
+ ? 'Exact selected qualified Handoff consumption plus exact qualified recipient Role material are the bounded assignment evidence. This is semantic Handoff/Role evidence, not package-delivery, provider, model, chat-position, filename or neighboring-route inference.'
350
+ : 'Exact selected Handoff/Role assignment evidence is not established; no Handoff-mode holder binding is projected.'
351
+ });
352
+ }
353
+
326
354
  function holderDurableIdentityProjection(holderId = '') {
327
355
  return deepFreeze({
328
356
  state: 'not-established',
@@ -390,6 +390,7 @@ export function parseHandoffGrounding(markdown, route) {
390
390
  returnTo: sectionField(completion, 'Return To')
391
391
  }),
392
392
  routeId: String(route?.id || ''),
393
+ routePointerPath: String(route?.pointerPath || ''),
393
394
  workspaceId: String(route?.workspaceId || ''),
394
395
  workspaceRelativePath: String(route?.workspaceRelativeHandoffPath || route?.workspaceRelativePath || ''),
395
396
  packagePath: String(route?.packagePath || ''),
@@ -405,7 +406,7 @@ function markdownReferenceTarget(value = '') {
405
406
  }
406
407
 
407
408
  export function emptyHandoffGrounding() {
408
- return deepFreeze({ schemaId: '', purpose: '', from: '', fromKind: '', fromReference: '', to: '', toKind: '', toReference: '', transfers: Object.freeze([]), retainedResponsibilities: Object.freeze([]), completionExpectation: Object.freeze({ signalKind: '', signalMeaning: '', returnTo: '' }), routeId: '', workspaceId: '', workspaceRelativePath: '', packagePath: '', sha256: '', boundary: 'No Handoff material supplied.' });
409
+ return deepFreeze({ schemaId: '', purpose: '', from: '', fromKind: '', fromReference: '', to: '', toKind: '', toReference: '', transfers: Object.freeze([]), retainedResponsibilities: Object.freeze([]), completionExpectation: Object.freeze({ signalKind: '', signalMeaning: '', returnTo: '' }), routeId: '', routePointerPath: '', workspaceId: '', workspaceRelativePath: '', packagePath: '', sha256: '', boundary: 'No Handoff material supplied.' });
409
410
  }
410
411
 
411
412
  export function resolveGroundingRouteMarkdown(bundle = {}, selectedRoute = {}, findings = [], context = null) {
@@ -8,7 +8,7 @@ export function buildEndpointRolePointerChain(input = {}) {
8
8
  const findings = [];
9
9
  let lineageParent = input.lineageParent || null;
10
10
  let nextDimension = String(input.nextDimension || '');
11
- for (const requirement of input.requirements || []) {
11
+ for (const requirement of orderedEndpointRequirements(input.requirements || [])) {
12
12
  const target = input.resolveRoleMaterialTarget(requirement, input.descriptor, input.workspaceById, input.cache, input.route);
13
13
  if (target.state !== 'qualified') {
14
14
  findings.push(finding('error', `portable.handoff-v2-surface.endpoint-role.${target.reason || 'unresolved'}`, 'Endpoint Role requirement did not resolve to one exact carried Workspace/cache representation.', { routeId: String(input.route?.id || ''), requirementId: String(requirement.id || '') }));
@@ -175,5 +175,18 @@ export function buildParticipantRolePointerChain(input = {}) {
175
175
  });
176
176
  }
177
177
 
178
+ function orderedEndpointRequirements(requirements = []) {
179
+ return [...requirements].map((item, index) => ({ item, index })).sort((a, b) => {
180
+ const rank = (entry) => {
181
+ const party = String(entry?.party || entry?.fields?.Side || '').trim().toLowerCase();
182
+ if (party === 'from') return 0;
183
+ if (party === 'to') return 1;
184
+ return 2;
185
+ };
186
+ const delta = rank(a.item) - rank(b.item);
187
+ return delta || a.index - b.index;
188
+ }).map(({ item }) => item);
189
+ }
190
+
178
191
  function safeToken(value = '') { return String(value || '').trim().toLowerCase().normalize('NFKD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'workspace'; }
179
192
  function finding(severity, code, message, extra = {}) { return Object.freeze({ severity, code, message, ...extra }); }
@@ -5,7 +5,7 @@ export function projectRecipientV2Routes(routePointers = [], endpointPointers =
5
5
  const qualified = (qualifiedRoutes || []).find((route) => String(route.workspaceId || '') === String(item.facts?.workspaceId || '') && String(route.workspaceRelativePath || '') === String(item.facts?.workspaceRelativeHandoffPath || '')) || null;
6
6
  return Object.freeze({
7
7
  pointerPath: item.path,
8
- routeId: String(item.facts?.routeId || qualified?.id || ''),
8
+ routeId: String(item.facts?.routeId || ''),
9
9
  workspaceId: String(item.facts?.workspaceId || ''),
10
10
  workspaceRelativeHandoffPath: String(item.facts?.workspaceRelativeHandoffPath || ''),
11
11
  returnCarrierReservation: item.facts?.returnCarrierReservation || qualified?.returnCarrierReservation || null,
@@ -163,10 +163,10 @@ function buildRecipientFacingV2PackageV1Prepared(input = {}, sealedByWorkspaceId
163
163
  const binding = bindingForWorkspace(descriptor, owningWorkspace.workspaceId);
164
164
  let lineageParent = cache?.parent || owningWorkspace.parent;
165
165
  let nextDimension = cache ? `${plan.prefix}-1-1` : `${plan.prefix}-1`;
166
- const endpointChain = buildEndpointRolePointerChain({ requirements: route.materialRequirements?.endpointRoles || [], descriptor, workspaceById, cache, workspace: owningWorkspace, route, createdAt, lineageParent, nextDimension, resolveRoleMaterialTarget: roleMaterialTarget, parentAuthority: recipientV2ParentAuthority });
167
- files.push(...endpointChain.files); topology.endpointRoles.push(...endpointChain.roles); findings.push(...endpointChain.findings); lineageParent = endpointChain.lineageParent; nextDimension = endpointChain.nextDimension;
168
166
  const participantChain = buildParticipantRolePointerChain({ requirements: route.materialRequirements?.participantRoles || [], descriptor, workspaceById, cache, workspace: owningWorkspace, route, createdAt, lineageParent, nextDimension, resolveRoleMaterialTarget: roleMaterialTarget, parentAuthority: recipientV2ParentAuthority });
169
167
  files.push(...participantChain.files); topology.participantRoles.push(...participantChain.roles); findings.push(...participantChain.findings); lineageParent = participantChain.lineageParent; nextDimension = participantChain.nextDimension;
168
+ const endpointChain = buildEndpointRolePointerChain({ requirements: route.materialRequirements?.endpointRoles || [], descriptor, workspaceById, cache, workspace: owningWorkspace, route, createdAt, lineageParent, nextDimension, resolveRoleMaterialTarget: roleMaterialTarget, parentAuthority: recipientV2ParentAuthority });
169
+ files.push(...endpointChain.files); topology.endpointRoles.push(...endpointChain.roles); findings.push(...endpointChain.findings); lineageParent = endpointChain.lineageParent; nextDimension = endpointChain.nextDimension;
170
170
  const pointerPath = `${nextDimension}-handoff-pointer.trace.md`;
171
171
  const routeEntry = (binding?.entryMap?.entries || []).find((entry) => String(entry.path || '') === String(route.workspaceRelativePath || ''));
172
172
  const pointerFacts = {
@@ -183,8 +183,8 @@ function buildRecipientFacingV2TopologyLegacy(input = {}) {
183
183
  const routeDimension = cache ? `001-${plan.workspace.ordinal}-1-${plan.ordinal}` : `001-${plan.workspace.ordinal}-${plan.ordinal}`;
184
184
  let lineageParent = cache?.parent || workspace.parent;
185
185
  let nextDimension = routeDimension;
186
- const endpointChain = buildEndpointRolePointerChain({
187
- requirements: route.materialRequirements?.endpointRoles || [],
186
+ const participantChain = buildParticipantRolePointerChain({
187
+ requirements: route.materialRequirements?.participantRoles || [],
188
188
  descriptor,
189
189
  workspaceById,
190
190
  cache,
@@ -196,13 +196,13 @@ function buildRecipientFacingV2TopologyLegacy(input = {}) {
196
196
  resolveRoleMaterialTarget: roleMaterialTarget,
197
197
  parentAuthority: recipientV2ParentAuthority
198
198
  });
199
- files.push(...endpointChain.files);
200
- topology.endpointRoles.push(...endpointChain.roles);
201
- findings.push(...endpointChain.findings);
202
- lineageParent = endpointChain.lineageParent;
203
- nextDimension = endpointChain.nextDimension;
204
- const participantChain = buildParticipantRolePointerChain({
205
- requirements: route.materialRequirements?.participantRoles || [],
199
+ files.push(...participantChain.files);
200
+ topology.participantRoles.push(...participantChain.roles);
201
+ findings.push(...participantChain.findings);
202
+ lineageParent = participantChain.lineageParent;
203
+ nextDimension = participantChain.nextDimension;
204
+ const endpointChain = buildEndpointRolePointerChain({
205
+ requirements: route.materialRequirements?.endpointRoles || [],
206
206
  descriptor,
207
207
  workspaceById,
208
208
  cache,
@@ -214,11 +214,11 @@ function buildRecipientFacingV2TopologyLegacy(input = {}) {
214
214
  resolveRoleMaterialTarget: roleMaterialTarget,
215
215
  parentAuthority: recipientV2ParentAuthority
216
216
  });
217
- files.push(...participantChain.files);
218
- topology.participantRoles.push(...participantChain.roles);
219
- findings.push(...participantChain.findings);
220
- lineageParent = participantChain.lineageParent;
221
- nextDimension = participantChain.nextDimension;
217
+ files.push(...endpointChain.files);
218
+ topology.endpointRoles.push(...endpointChain.roles);
219
+ findings.push(...endpointChain.findings);
220
+ lineageParent = endpointChain.lineageParent;
221
+ nextDimension = endpointChain.nextDimension;
222
222
  const pointerPath = `${nextDimension}-handoff-pointer.trace.md`;
223
223
  const pointerFacts = {
224
224
  workspaceId: workspace.workspaceId,
@@ -13,10 +13,19 @@ export function portableRuntimeValidationContractForSchema(schemaId = '', resolu
13
13
  const resolution = resolutionInput || resolveSchemaModule({ schemaId });
14
14
  if (resolution?.fallbackUsed || !resolution?.module) return unavailable('registered-schema-resolution-unavailable', { resolution });
15
15
  const qualification = typeof resolution.module.schemaSource?.qualify === 'function' ? resolution.module.schemaSource.qualify() : null;
16
+ const lineageAuthority = qualification?.validationLineageAuthority || null;
17
+ if (qualification?.state === 'qualified' && lineageAuthority && lineageAuthority.state !== 'qualified') {
18
+ return unavailable('compiled-validation-lineage-source-authority-unqualified', {
19
+ resolution,
20
+ findings: Object.freeze([...(lineageAuthority.findings || [])]),
21
+ lineageAuthority,
22
+ baseQualificationState: String(qualification?.state || 'unavailable')
23
+ });
24
+ }
16
25
  const baseContract = qualification?.state === 'qualified' ? qualification?.compiledContract?.validationContract || null : null;
17
- if (!baseContract) return unavailable(qualification?.state === 'qualified' ? 'compiled-validation-contract-unavailable' : 'schema-source-unqualified', { resolution });
26
+ if (!baseContract) return unavailable(qualification?.state === 'qualified' ? 'compiled-validation-contract-unavailable' : 'schema-source-unqualified', { resolution, findings: Object.freeze([...(qualification?.findings || [])]), baseQualificationState: String(qualification?.state || 'unavailable') });
18
27
  const projected = projectPortableValidationContractWithQualifiedLocalRoot(baseContract);
19
- return deepFreeze({ ...projected, resolution, baseQualificationState: String(qualification?.state || 'unavailable') });
28
+ return deepFreeze({ ...projected, resolution, lineageAuthority, baseQualificationState: String(qualification?.state || 'unavailable') });
20
29
  }
21
30
 
22
31
  export function portableRuntimeValidationAuthorityForRecord(record = {}) {
@@ -26,7 +35,10 @@ export function portableRuntimeValidationAuthorityForRecord(record = {}) {
26
35
  const schemaId = String(declaredSchema.id || record?.schemaId || record?.currentSchemaId || '').trim();
27
36
  const runtime = portableRuntimeValidationContractForSchema(schemaId);
28
37
  if (runtime.state !== 'qualified' || !runtime.compiledContract) {
29
- return unavailableAuthority(schemaId, runtime, ['Registered compiled validation authority is unavailable for the declared Current Schema.']);
38
+ const runtimeFindings = Array.isArray(runtime?.findings) && runtime.findings.length
39
+ ? runtime.findings
40
+ : ['Registered compiled validation authority is unavailable for the declared Current Schema.'];
41
+ return unavailableAuthority(schemaId, runtime, runtimeFindings);
30
42
  }
31
43
 
32
44
  const findings = [];