@tiinex/core 0.17.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/package.json +7 -5
  2. package/src/tooling/portable/adapters/cli/cli.command-input.js +8 -1
  3. package/src/tooling/portable/adapters/cli/cli.common-author.js +29 -5
  4. package/src/tooling/portable/adapters/cli/cli.common-output.js +38 -3
  5. package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +33 -17
  6. package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +139 -2
  7. package/src/tooling/portable/adapters/cli/cli.help.js +1 -1
  8. package/src/tooling/portable/adapters/cli/cli.run.js +4 -0
  9. package/src/tooling/portable/adapters/node/handoff.manufacture.js +25 -12
  10. package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +43 -0
  11. package/src/tooling/portable/grounding/grounding.capsule.js +22 -3
  12. package/src/tooling/portable/grounding/grounding.holderBindingAuthorization.js +81 -0
  13. package/src/tooling/portable/grounding/grounding.implementationSourceAuthority.js +109 -0
  14. package/src/tooling/portable/grounding/grounding.orchestrationReadiness.js +33 -0
  15. package/src/tooling/portable/grounding/grounding.participantAuthority.js +1 -1
  16. package/src/tooling/portable/grounding/grounding.participantContext.js +58 -0
  17. package/src/tooling/portable/grounding/grounding.processApplicability.js +38 -0
  18. package/src/tooling/portable/grounding/grounding.readiness.authority.js +63 -3
  19. package/src/tooling/portable/grounding/grounding.readiness.js +72 -12
  20. package/src/tooling/portable/grounding/grounding.readiness.support.js +5 -1
  21. package/src/tooling/portable/grounding/grounding.sourceEvidence.js +151 -9
  22. package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +12 -1
  23. package/src/tooling/portable/handoff/coldStartQualification.grounding.js +62 -3
  24. package/src/tooling/portable/handoff/coldStartQualification.materials.js +19 -1
  25. package/src/tooling/portable/handoff/contextAudit.js +1 -1
  26. package/src/tooling/portable/handoff/delegationReturnReservation.js +4 -2
  27. package/src/tooling/portable/handoff/manufacture.js +1 -0
  28. package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +3 -0
  29. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +1 -1
  30. package/src/tooling/portable/handoff/recoveryAcceptanceAudit.js +5 -3
  31. package/src/tooling/portable/schema/contract.field-domain.js +43 -2
@@ -9,6 +9,7 @@ import { auditHandoffPackageContextCarriage } from '../handoff/contextAudit.js';
9
9
  import { acceptedRecoveryMaterial, projectColdStartContinuity } from './grounding.continuity.js';
10
10
  import { projectGroundingAuthority } from './grounding.readiness.authority.js';
11
11
  import { projectGroundingCapsule } from './grounding.capsule.js';
12
+ import { projectGroundingOrchestrationReadiness } from './grounding.orchestrationReadiness.js';
12
13
 
13
14
  export const PORTABLE_GROUNDING_READINESS_SCHEMA_ID = 'tiinex.portable.grounding-readiness.v1';
14
15
 
@@ -112,6 +113,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
112
113
  const route = authority?.selectedRoute || null;
113
114
  const roleState = String(authority?.role?.state || 'unresolved');
114
115
  const holderState = String(authority?.holderBinding?.state || 'unresolved');
116
+ const holderAuthorizationState = String(authority?.holderBinding?.authorization?.state || (holderState === 'not-applicable' ? 'not-applicable' : 'unresolved'));
115
117
  if (!route || String(authority?.status || '') === 'blocked') missing(missingEvidence, unresolved, 'authority-route-unqualified', 'The selected Handoff route is not qualified for this grounding result.');
116
118
  else known.push(evidence('qualified-handoff-route', 'qualified', route.id || route.pointerPath || 'selected-route'));
117
119
  if (roleState === 'qualified' || roleState === 'not-applicable') known.push(evidence('recipient-role-boundary', roleState, authority?.role?.endpoint?.label || 'recipient'));
@@ -119,7 +121,6 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
119
121
  else missing(missingEvidence, unresolved, 'recipient-role-unresolved', 'The Handoff recipient Role boundary is not qualified for act-ready grounding.');
120
122
 
121
123
  if (holderState === 'qualified' || holderState === 'not-applicable') {
122
- holderBindingActReady = true;
123
124
  known.push(evidence('session-holder-role-binding', holderState, authority?.holderBinding?.roleLabel || authority?.role?.endpoint?.label || 'recipient'));
124
125
  } else if (holderState === 'blocked') {
125
126
  holderBindingActReady = false;
@@ -130,13 +131,28 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
130
131
  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.'));
131
132
  }
132
133
 
134
+ if (holderState === 'not-applicable') {
135
+ holderBindingActReady = true;
136
+ known.push(evidence('session-holder-role-binding-authorization', 'not-applicable', 'selected Handoff recipient is not a Role endpoint'));
137
+ } else if (holderState === 'qualified') {
138
+ if (holderAuthorizationState === 'qualified') {
139
+ holderBindingActReady = true;
140
+ known.push(evidence('session-holder-role-binding-authorization', 'qualified', authority?.holderBinding?.authorization?.provenance?.roleArtifactPath || authority?.role?.endpoint?.label || 'recipient Role material'));
141
+ } else {
142
+ holderBindingActReady = false;
143
+ unresolved.push(evidence('session-holder-role-binding-authorization', holderAuthorizationState || 'unresolved', authority?.holderBinding?.authorization?.holderState || 'exact qualified Role Holder Relationship does not establish the explicit-session/Handoff assignment mode'));
144
+ reasons.push(reason('session-holder-role-binding-authorization-unresolved', 'The explicit consuming-session Role assertion matches the selected recipient Role, but exact qualified Role holder-assignment authority does not establish that assignment mode. Matching session input alone cannot make the route act-ready.'));
145
+ }
146
+ }
147
+
133
148
  const required = Array.isArray(requiredContext) ? requiredContext : [];
134
149
  const unresolvedRequired = required.filter((entry) => entry.state !== 'qualified');
135
150
  if (unresolvedRequired.length) missing(missingEvidence, unresolved, 'required-context-unqualified', `${unresolvedRequired.length} declared Required Context item(s) are not exact-qualified.`);
136
151
  else known.push(evidence('required-context-closure', 'qualified', `${required.length} item(s)`));
137
152
  if (String(continuation?.state || '') !== 'ready') missing(missingEvidence, unresolved, 'continuation-not-ready', 'The grounded continuation is not ready for substantive work.');
138
- if (String(contextAudit?.status || '') !== 'ready' || String(contextAudit?.coverage?.state || '') !== 'qualified') missing(missingEvidence, unresolved, 'workspace-snapshot-coverage-unqualified', 'Complete carried Workspace snapshot coverage is not qualified.');
139
- else known.push(evidence('workspace-snapshot-coverage', 'qualified', `${contextAudit.workspaceMaterializations?.length || 0} workspace(s)`));
153
+ const workspaceCoverage = projectWorkspaceActionCoverage(contextAudit);
154
+ if (!workspaceCoverage.qualified) missing(missingEvidence, unresolved, 'workspace-snapshot-coverage-unqualified', workspaceCoverage.message);
155
+ else known.push(evidence('workspace-snapshot-coverage', 'qualified', `${workspaceCoverage.count} workspace representation(s): ${workspaceCoverage.completeCount} complete, ${workspaceCoverage.boundedCount} bounded`));
140
156
  for (const item of requiredRecordResolution.missing) missing(missingEvidence, unresolved, 'required-context-not-in-snapshot', item);
141
157
  if (!routeRecordIds.size) missing(missingEvidence, unresolved, 'selected-route-not-in-snapshot', 'The qualified selected Handoff route was not found at its exact carried Workspace path.');
142
158
  } else {
@@ -147,7 +163,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
147
163
  if (!records.length) missing(missingEvidence, unresolved, 'no-artifact-records', 'No readable Tiinex artifact records were loaded for grounding.');
148
164
  else known.push(evidence('loaded-artifact-records', 'known', `${records.length} record(s)`));
149
165
 
150
- inferred.push(evidence('relevant-lineage-scope', 'bounded-inference', handoffMode ? 'directed declared-Parent cone around the exact selected Handoff route within complete carried Workspace snapshots plus independently qualified exact detached Parent-boundary cache records' : 'all loaded records'));
166
+ inferred.push(evidence('relevant-lineage-scope', 'bounded-inference', handoffMode ? 'directed declared-Parent cone around the exact selected Handoff route within qualified carried Workspace representations (complete or bounded as declared) plus independently qualified exact detached Parent-boundary cache records' : 'all loaded records'));
151
167
  inferred.push(evidence('lineage-leaf-role', 'bounded-inference', 'derived only from declared Parent edges in the shared resolver'));
152
168
 
153
169
  if (handoffMode) {
@@ -156,7 +172,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
156
172
  } else if (topology.routeLeaves.length) {
157
173
  known.push(evidence('selected-route-parent-lineage-leaf', 'resolved', `${topology.routeLeaves.length} selected-route leaf/leaves`));
158
174
  } else {
159
- missing(missingEvidence, unresolved, 'selected-route-lineage-leaf-missing', 'The selected Handoff route is not a resolved Parent-lineage leaf in the complete carried Workspace snapshots.');
175
+ missing(missingEvidence, unresolved, 'selected-route-lineage-leaf-missing', 'The selected Handoff route is not a resolved Parent-lineage leaf in the qualified carried Workspace material.');
160
176
  }
161
177
  if (lineageIssues.length > routeBlockingLineageIssues.length) unresolved.push(evidence('upstream-lineage-diagnostics', continuity.state === 'qualified' ? 'degraded-nonblocking' : 'blocking-for-cold-start-continuity', `${lineageIssues.length - routeBlockingLineageIssues.length} upstream Parent-lineage issue(s) remain outside the selected-route edge boundary.`));
162
178
  } else if (lineageIssues.length) {
@@ -189,7 +205,8 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
189
205
  let state = 'grounded-to-act';
190
206
  if (missingEvidence.length) state = 'insufficient-grounding';
191
207
  else if (!handoffMode || !holderBindingActReady || !topology.currentFrontier.length || humanOnly.length) state = 'grounded-to-discuss';
192
- if (state === 'grounded-to-act') reasons.push(reason('bounded-act-ready', 'Selected Handoff authority, explicit consuming-session holder Role binding, Required Context, carried Workspace coverage, cold-start continuity to a qualified semantic root, the selected-route Parent-lineage leaf, and declared current-work frontier evidence are all resolved enough for the next bounded action.'));
208
+ if (state === 'grounded-to-act') reasons.push(reason('bounded-act-ready', 'Selected Handoff authority, explicit consuming-session holder Role binding, exact qualified holder-assignment authorization where the recipient is a Role, exact Required Context, qualified carried Workspace coverage (complete or bounded as declared), cold-start continuity to a qualified semantic root, the selected-route Parent-lineage leaf, and declared current-work frontier evidence are all resolved enough for the next bounded action.'));
209
+ const orchestrationReadiness = projectGroundingOrchestrationReadiness({ readinessState: state, participantContext: capsule.participantContext, processApplicability: capsule.processApplicability, sourceEvidence: capsule.sourceEvidence, topology });
193
210
 
194
211
  return Object.freeze({
195
212
  schema: PORTABLE_GROUNDING_READINESS_SCHEMA_ID,
@@ -216,11 +233,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
216
233
  requestedSelectors: requiredContextProjection.requestedSelectors,
217
234
  unmatchedSelectors: requiredContextProjection.unmatchedSelectors
218
235
  }),
219
- workspaceSnapshots: contextAudit ? Object.freeze({
220
- state: String(contextAudit.coverage?.state || contextAudit.status || 'unresolved'),
221
- qualified: String(contextAudit.status || '') === 'ready',
222
- count: contextAudit.workspaceMaterializations?.length || 0
223
- }) : Object.freeze({ state: 'not-supplied', qualified: false, count: 0 })
236
+ workspaceSnapshots: contextAudit ? projectWorkspaceActionCoverage(contextAudit) : Object.freeze({ state: 'not-supplied', qualified: false, count: 0, completeCount: 0, boundedCount: 0, unqualified: Object.freeze([]), message: 'No carried Workspace context audit was supplied.' })
224
237
  }),
225
238
  lineage: Object.freeze({
226
239
  state: handoffMode ? (routeBlockingLineageIssues.length ? 'unresolved' : topology.routeLeaves.length ? (lineageIssues.length ? 'resolved-with-upstream-degradation' : 'resolved') : 'missing-leaf') : (lineageIssues.length ? 'unresolved' : topology.leaves.length ? 'resolved' : 'missing-leaf'),
@@ -240,6 +253,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
240
253
  boundary: 'Leaf/root roles are derived only from loaded declared Parent edges produced by the shared lineage resolver. Filename numbering, carrier dimensions, directory depth, branch names, and Task lifecycle labels are never substituted for Parent topology.'
241
254
  }),
242
255
  continuity,
256
+ orchestrationReadiness,
243
257
  capsule,
244
258
  currentWork: Object.freeze({
245
259
  state: topology.currentFrontier.length ? 'current-frontier-resolved' : topology.currentTasks.length ? 'current-candidates-without-frontier' : 'unresolved',
@@ -274,6 +288,47 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
274
288
  });
275
289
  }
276
290
 
291
+ function projectWorkspaceActionCoverage(contextAudit = {}) {
292
+ const workspaces = Array.isArray(contextAudit?.workspaceMaterializations) ? contextAudit.workspaceMaterializations : [];
293
+ const summaries = workspaces.map((workspace) => {
294
+ const coverage = workspaceCoverageState(workspace);
295
+ const qualification = String(workspace?.qualification || '').trim().toLowerCase();
296
+ const qualified = ['complete', 'bounded'].includes(coverage) && qualification === 'qualified';
297
+ return Object.freeze({ workspaceId: String(workspace?.workspaceId || ''), coverage, qualification: qualification || 'unresolved', qualified });
298
+ });
299
+ const aggregateReady = String(contextAudit?.status || '') === 'ready' && String(contextAudit?.coverage?.state || '') === 'qualified';
300
+ const qualified = aggregateReady && summaries.length > 0 && summaries.every((item) => item.qualified);
301
+ const completeCount = summaries.filter((item) => item.coverage === 'complete').length;
302
+ const boundedCount = summaries.filter((item) => item.coverage === 'bounded').length;
303
+ const unqualified = summaries.filter((item) => !item.qualified);
304
+ const message = qualified
305
+ ? `Qualified carried Workspace coverage is established for ${summaries.length} representation(s): ${completeCount} complete, ${boundedCount} bounded.`
306
+ : !aggregateReady
307
+ ? 'Carried Workspace context audit is not qualified for bounded action readiness.'
308
+ : !summaries.length
309
+ ? 'No qualified carried Workspace representation is available for the selected Handoff route.'
310
+ : `Carried Workspace representation qualification is incomplete for ${unqualified.length} workspace(s); bounded carriage is actionable only when each carried representation is independently qualified as complete or bounded.`;
311
+ return Object.freeze({
312
+ state: qualified ? 'qualified' : 'unqualified',
313
+ qualified,
314
+ count: summaries.length,
315
+ completeCount,
316
+ boundedCount,
317
+ unqualified: Object.freeze(unqualified),
318
+ message,
319
+ boundary: 'Complete and bounded carriage remain distinct. Bounded coverage can satisfy current-route action readiness only when the carried representation itself is qualified; it never implies whole-Workspace or whole-program authority.'
320
+ });
321
+ }
322
+
323
+ function workspaceCoverageState(workspace = {}) {
324
+ const explicit = String(workspace?.coverage || workspace?.materialization || '').trim().toLowerCase();
325
+ if (explicit === 'complete' || explicit === 'bounded') return explicit;
326
+ const reason = String(workspace?.reason || '').trim().toLowerCase();
327
+ if (reason.includes('bounded') || reason.includes('partial')) return 'bounded';
328
+ if (reason.includes('complete')) return 'complete';
329
+ return 'unresolved';
330
+ }
331
+
277
332
  function projectCurrentWork(topology = {}, records = [], includeCurrentWork = false) {
278
333
  const recordById = new Map((records || []).map((record) => [String(record.id || ''), record]));
279
334
  const frontier = (topology.currentFrontier || []).slice(0, MAX_ITEMS).map((item) => {
@@ -297,8 +352,13 @@ function projectCurrentWork(topology = {}, records = [], includeCurrentWork = fa
297
352
  }
298
353
 
299
354
  function nextActionFor(state, topology, continuity = {}, authority = null) {
300
- 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 + required context + cold-start root continuity + selected-route Parent leaf + declared current-work frontier' });
355
+ 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' });
301
356
  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' });
357
+ if (state === 'grounded-to-discuss' && String(authority?.holderBinding?.state || '') === 'qualified' && String(authority?.holderBinding?.authorization?.state || 'unresolved') !== 'qualified') return Object.freeze({
358
+ kind: 'resolve-session-holder-binding-authorization',
359
+ target: authority?.holderBinding?.authorization?.provenance?.roleArtifactPath || authority?.role?.endpoint?.label || authority?.handoff?.to || '',
360
+ basis: 'a matching explicit session Role assertion is not semantic authorization; exact qualified recipient Role Holder Relationship authority must establish the assignment mode'
361
+ });
302
362
  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' });
303
363
  if (continuity?.state === 'unproven') return Object.freeze({
304
364
  kind: continuity.recovery?.state === 'host-action-available' ? 'recover-required-parent-with-host-action' : 'request-exact-required-parent-material',
@@ -122,12 +122,16 @@ export function projectRequiredContext(requiredContext = [], selectors = []) {
122
122
  return Object.freeze({
123
123
  requirementId: entry.requirementId || '',
124
124
  name: entry.name || '',
125
+ material: entry.material || '',
126
+ purpose: entry.purpose || '',
127
+ declaredAvailability: entry.declaredAvailability || '',
125
128
  state: entry.state || '',
126
129
  workspaceId: entry.workspaceId || '',
127
130
  innerPath: entry.innerPath || entry.workspaceRelativePath || '',
128
131
  referenceTarget: entry.referenceTarget || '',
129
132
  bytes: Number(entry.bytes || entry.actualBytes || 0),
130
133
  sha256: entry.sha256 || entry.actualSha256 || '',
134
+ provenance: entry.provenance ? Object.freeze({ ...entry.provenance }) : null,
131
135
  contentProjected,
132
136
  ...(contentProjected ? { content: entry.content } : {})
133
137
  });
@@ -164,7 +168,7 @@ export function resolveRequiredContextRecords(requiredContext = [], records = []
164
168
  const record = byPath.get(expectedPath);
165
169
  if (record) { ids.add(record.id); matched += 1; continue; }
166
170
  if (isExactHydratedWorkspaceContext(entry)) { matched += 1; continue; }
167
- missing.push(`${entry.requirementId || entry.name || expectedPath}: exact qualified context was not found at ${expectedPath} inside the complete carried Workspace snapshots.`);
171
+ missing.push(`${entry.requirementId || entry.name || expectedPath}: exact qualified context was not found at ${expectedPath} inside the qualified carried Workspace material.`);
168
172
  }
169
173
  return Object.freeze({ ids, matched, missing: Object.freeze(missing) });
170
174
  }
@@ -1,12 +1,17 @@
1
1
  import { parseWorkspaceEntrypoints } from '../handoff/workspaceSourceIdentity.js';
2
2
  const MAX_WORKSPACES = 8;
3
3
  const MAX_SOURCES = 8;
4
+ const MAX_MATERIALS = 12;
5
+ const MAX_BLOCKERS = 8;
4
6
 
5
- export function projectGroundingSourceEvidence({ records = [], contextAudit = null, continuation = null, sourceProfiles = [] } = {}) {
7
+ export function projectGroundingSourceEvidence({ records = [], contextAudit = null, continuation = null, requiredContext = [], sourceProfiles = [] } = {}) {
6
8
  const byPath = new Map((records || []).map((record) => [String(record.path || ''), record]));
7
9
  const profiles = profileIndex(sourceProfiles);
10
+ const coverageByWorkspace = new Map();
8
11
  const workspaces = (contextAudit?.workspaceMaterializations || []).slice(0, MAX_WORKSPACES).map((workspace) => {
9
12
  const workspaceId = String(workspace.workspaceId || '');
13
+ const coverage = normalizeCoverage(workspace);
14
+ if (workspaceId) coverageByWorkspace.set(workspaceId, coverage);
10
15
  const innerPath = normalizePath(workspace.sourceWorkspaceTargetInnerPath || '');
11
16
  const exactPath = workspaceId && innerPath ? `${workspaceId}/${innerPath}` : '';
12
17
  const record = exactPath ? byPath.get(exactPath) : null;
@@ -21,10 +26,21 @@ export function projectGroundingSourceEvidence({ records = [], contextAudit = nu
21
26
  && record.hasContinuityContext
22
27
  && record.hasIntegrity
23
28
  );
24
- if (!qualifiedArtifact && !explicitProfile.length) return Object.freeze({ workspace: workspaceId, state: 'unresolved' });
29
+ if (!qualifiedArtifact && !explicitProfile.length) return Object.freeze({
30
+ workspace: workspaceId,
31
+ state: 'unresolved',
32
+ coverage,
33
+ carrier: String(workspace.reason || ''),
34
+ provenance: Object.freeze({
35
+ basis: 'carried-workspace-materialization-without-qualified-source-declaration',
36
+ sourceArtifactPath: exactPath,
37
+ boundary: 'Workspace carriage alone does not establish repository/source identity.'
38
+ })
39
+ });
25
40
  return Object.freeze({
26
41
  workspace: workspaceId,
27
42
  state: qualifiedArtifact ? 'qualified' : 'explicit-profile',
43
+ coverage,
28
44
  carrier: String(workspace.reason || 'qualified-workspace-snapshot'),
29
45
  sourceArtifactPath: exactPath,
30
46
  sourceArtifactSha256: String(workspace.sourceWorkspaceTargetSha256 || ''),
@@ -32,20 +48,150 @@ export function projectGroundingSourceEvidence({ records = [], contextAudit = nu
32
48
  ref: String(unique?.ref || ''),
33
49
  rootPath: String(unique?.rootPath || ''),
34
50
  remoteState: String(unique?.remoteState || 'not-checked'),
35
- sources: Object.freeze(sources.slice(0, MAX_SOURCES))
51
+ sources: Object.freeze(sources.slice(0, MAX_SOURCES)),
52
+ provenance: Object.freeze({
53
+ basis: qualifiedArtifact ? 'exact-qualified-workspace-source-artifact' : 'explicit-source-profile',
54
+ sourceArtifactPath: exactPath,
55
+ sourceArtifactSha256: String(workspace.sourceWorkspaceTargetSha256 || ''),
56
+ coverageBasis: String(workspace.reason || ''),
57
+ boundary: qualifiedArtifact
58
+ ? 'Source identity is projected only from the exact qualified Workspace artifact carried for this Workspace.'
59
+ : 'Source identity is projected only from an explicitly supplied source profile; no repository discovery is implied.'
60
+ })
36
61
  });
37
62
  });
63
+
64
+ const requirements = (requiredContext || []).slice(0, MAX_MATERIALS).map((entry) => projectRequirement(entry, coverageByWorkspace));
65
+ const unavailable = requirements.filter((entry) => entry.availability === 'unavailable');
66
+ const blockers = unavailable.slice(0, MAX_BLOCKERS).map((entry) => Object.freeze({
67
+ code: 'authoritative-material-unavailable',
68
+ requirementId: entry.requirementId,
69
+ name: entry.name,
70
+ requiredMaterial: Object.freeze({
71
+ material: entry.material,
72
+ referenceTarget: entry.referenceTarget,
73
+ workspace: entry.workspace,
74
+ path: entry.path
75
+ }),
76
+ owner: Object.freeze({
77
+ kind: 'selected-handoff-required-context',
78
+ requirementId: entry.requirementId,
79
+ name: entry.name,
80
+ purpose: entry.purpose
81
+ }),
82
+ basis: Object.freeze({
83
+ state: entry.state,
84
+ availability: entry.availability,
85
+ materialClass: entry.materialClass,
86
+ workspaceCoverage: entry.workspaceCoverage,
87
+ providerMode: entry.providerMode,
88
+ kind: entry.kind,
89
+ provenance: entry.provenance
90
+ }),
91
+ blockingReason: 'The exact declared Required Context material is not qualified in current carried/explicit material, so Tooling cannot claim that authority is available.',
92
+ workspace: entry.workspace,
93
+ path: entry.path,
94
+ referenceTarget: entry.referenceTarget,
95
+ request: exactMaterialRequest(entry)
96
+ }));
97
+ const boundedOrCache = requirements.filter((entry) => entry.availability === 'qualified' && ['bounded-workspace', 'cache'].includes(entry.materialClass));
98
+ const contextMaterials = [
99
+ ...(contextAudit?.materialCarriers || []).map((item) => projectAuditMaterial(item, 'requirement-material')),
100
+ ...(contextAudit?.explicitDetachedMaterial || []).map((item) => projectAuditMaterial(item, 'bounded-or-cache-material')),
101
+ ...(contextAudit?.lineageMaterializations || []).map((item) => projectAuditMaterial(item, 'lineage-cache-material'))
102
+ ].slice(0, MAX_MATERIALS);
103
+
38
104
  return Object.freeze({
39
105
  carrier: Object.freeze({
40
106
  state: String(contextAudit?.coverage?.state || contextAudit?.status || 'unresolved'),
41
107
  workspaceCount: Number(contextAudit?.workspaceMaterializations?.length || 0),
42
- packageSourcePath: String(continuation?.packageSourcePath || '')
108
+ packageSourcePath: String(continuation?.packageSourcePath || ''),
109
+ completeWorkspaceCount: workspaces.filter((item) => item.coverage === 'complete').length,
110
+ boundedWorkspaceCount: workspaces.filter((item) => item.coverage === 'bounded').length
43
111
  }),
44
112
  workspaces: Object.freeze(workspaces),
45
- boundary: 'Exact selected Workspace source artifact/profile only.'
113
+ requirements: Object.freeze(requirements),
114
+ boundedOrCache: Object.freeze(boundedOrCache),
115
+ carriedMaterial: Object.freeze(contextMaterials),
116
+ blockers: Object.freeze(blockers),
117
+ boundary: 'Exact selected Workspace/source declarations and exact qualified Required Context material only. Complete Workspace carriage, bounded Workspace/cache material, explicit requirements, and unavailable authoritative material remain distinct. Missing material never authorizes repository, connector, or network discovery.'
118
+ });
119
+ }
120
+
121
+ function projectRequirement(entry = {}, coverageByWorkspace = new Map()) {
122
+ const state = String(entry.state || 'unresolved');
123
+ const providerMode = String(entry.providerMode || '');
124
+ const workspace = String(entry.workspaceId || '');
125
+ const workspaceCoverage = coverageByWorkspace.get(workspace) || 'unresolved';
126
+ let materialClass = 'explicit-requirement';
127
+ if (state === 'qualified') {
128
+ if (providerMode === 'cache' || String(entry.kind || '') === 'workspace-cache-entry') materialClass = 'cache';
129
+ else if (providerMode === 'archive' && workspaceCoverage === 'bounded') materialClass = 'bounded-workspace';
130
+ else if (providerMode === 'archive' && workspaceCoverage === 'complete') materialClass = 'complete-workspace';
131
+ else if (providerMode === 'archive') materialClass = 'workspace-material';
132
+ else materialClass = 'qualified-material';
133
+ }
134
+ return Object.freeze({
135
+ requirementId: String(entry.requirementId || ''),
136
+ name: String(entry.name || ''),
137
+ material: String(entry.material || ''),
138
+ purpose: String(entry.purpose || ''),
139
+ declaredAvailability: String(entry.declaredAvailability || ''),
140
+ state,
141
+ availability: state === 'qualified' ? 'qualified' : 'unavailable',
142
+ materialClass,
143
+ workspace,
144
+ workspaceCoverage,
145
+ path: String(entry.innerPath || entry.workspaceRelativePath || ''),
146
+ packagePath: String(entry.packagePath || entry.archivePackagePath || ''),
147
+ providerMode,
148
+ kind: String(entry.kind || ''),
149
+ referenceTarget: String(entry.referenceTarget || ''),
150
+ bytes: Number(entry.bytes || 0),
151
+ sha256: String(entry.sha256 || ''),
152
+ provenance: Object.freeze({
153
+ basis: String(entry.provenance?.basis || 'selected-handoff-required-context-and-route-closure'),
154
+ declarationSource: entry.provenance?.declarationSource ? Object.freeze({ ...(entry.provenance.declarationSource || {}) }) : null,
155
+ resolutionKind: String(entry.provenance?.resolutionKind || entry.kind || ''),
156
+ providerMode: String(entry.provenance?.providerMode || providerMode),
157
+ boundary: String(entry.provenance?.boundary || 'Requirement identity comes from the selected Handoff declaration; qualification/material class comes from exact route closure and carried source state.')
158
+ })
159
+ });
160
+ }
161
+
162
+ function projectAuditMaterial(item = {}, classification = '') {
163
+ return Object.freeze({
164
+ classification,
165
+ requirementId: String(item.requirementId || item.requirement?.id || ''),
166
+ name: String(item.requirement?.name || ''),
167
+ workspace: String(item.workspaceId || item.targetWorkspaceId || item.selectedProvider?.workspaceId || ''),
168
+ path: String(item.workspaceRelativePath || item.targetPath || item.originalPath || item.selectedProvider?.workspaceRelativePath || ''),
169
+ packagePath: String(item.path || item.archivePackagePath || ''),
170
+ bytes: Number(item.bytes || item.actualBytes || 0),
171
+ sha256: String(item.sha256 || item.actualSha256 || ''),
172
+ authority: Object.freeze({ ...(item.authority || {}) }),
173
+ provenance: Object.freeze({
174
+ basis: classification,
175
+ carrierPath: String(item.path || item.archivePackagePath || ''),
176
+ boundary: 'Diagnostic carriage evidence only; presence does not create semantic authority beyond the requirement/material it exactly resolves.'
177
+ })
46
178
  });
47
179
  }
48
180
 
181
+ function exactMaterialRequest(entry = {}) {
182
+ const target = entry.referenceTarget || [entry.workspace, entry.path].filter(Boolean).join('::') || entry.name || entry.requirementId || 'the declared Required Context material';
183
+ return `Provide exact qualified material for ${target}, or an explicitly qualified bounded Workspace/cache carrier that resolves this declared requirement. Do not substitute GitHub, a connector, a repository checkout, or network discovery without separate authority.`;
184
+ }
185
+
186
+ function normalizeCoverage(workspace = {}) {
187
+ const explicit = String(workspace.coverage || '').trim().toLowerCase();
188
+ if (explicit === 'complete' || explicit === 'bounded') return explicit;
189
+ const reason = String(workspace.reason || '').toLowerCase();
190
+ if (reason.includes('bounded') || reason.includes('partial')) return 'bounded';
191
+ if (reason.includes('complete')) return 'complete';
192
+ return 'unresolved';
193
+ }
194
+
49
195
  function profileIndex(value = []) {
50
196
  const map = new Map();
51
197
  if (!value) return map;
@@ -64,8 +210,4 @@ function profileIndex(value = []) {
64
210
  }
65
211
  function normalizeProfileList(value) { return (Array.isArray(value) ? value : [value]).filter(Boolean).map(normalizeProfile); }
66
212
  function normalizeProfile(value = {}) { return Object.freeze({ label: String(value.label || ''), sourceKind: String(value.sourceKind || value.kind || ''), repository: String(value.repository || ''), ref: String(value.ref || ''), rootPath: String(value.rootPath || ''), remoteState: String(value.remoteState || 'not-checked'), basis: 'explicit-source-profile' }); }
67
- function section(markdown = '', heading = '') { const escaped = escape(heading); return String(markdown || '').match(new RegExp(`(?:^|\\n)##\\s+${escaped}\\s*\\r?\\n([\\s\\S]*?)(?=\\n##\\s+|\\n#\\s+Continuity Integrity|$)`, 'i'))?.[1]?.trim() || ''; }
68
- function field(markdown = '', label = '') { const escaped = escape(label); return strip(String(markdown || '').match(new RegExp(`^\\s*-\\s+${escaped}:\\s*(.+)$`, 'mi'))?.[1] || ''); }
69
213
  function normalizePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\/+/, ''); }
70
- function strip(value = '') { return String(value || '').replace(/^\[([^\]]+)\]\([^)]+\)$/, '$1').replace(/[`*_]/g, '').trim(); }
71
- function escape(value = '') { return String(value || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
@@ -76,7 +76,18 @@ function qualifyRequiredRequirement(bundle, descriptor, byteProvider, workspace,
76
76
  if (!resolution&&!reasons.length) resolution=resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath);
77
77
  if (!resolution&&!reasons.length) reasons.push('required-material-not-carried');
78
78
  if (resolution?.state!=='qualified'&&resolution?.reason) reasons.push(resolution.reason);
79
- return deepFreeze({requirementId:String(requirement.id||''),name:String(requirement.name||''),referenceTarget:target,state:!reasons.length&&resolution?.state==='qualified'?'qualified':'blocked',resolution:resolution?.state==='qualified'?resolution:null,reasons:Object.freeze([...new Set(reasons)])});
79
+ return deepFreeze({
80
+ requirementId:String(requirement.id||''),
81
+ name:String(requirement.name||''),
82
+ material:String(requirement.material||''),
83
+ purpose:String(requirement.purpose||''),
84
+ declaredAvailability:String(requirement.availability||''),
85
+ referenceTarget:target,
86
+ declarationSource:requirement.source||null,
87
+ state:!reasons.length&&resolution?.state==='qualified'?'qualified':'blocked',
88
+ resolution:resolution?.state==='qualified'?resolution:null,
89
+ reasons:Object.freeze([...new Set(reasons)])
90
+ });
80
91
  }
81
92
 
82
93
  function resolveWorkspaceRequiredMaterial(byteProvider, workspace, resolvedPath) {
@@ -31,6 +31,7 @@ import {
31
31
  normalizeStringList,
32
32
  normalizeToken
33
33
  } from './coldStartQualification.shared.js';
34
+ import { projectHolderBindingAuthorization } from '../grounding/grounding.holderBindingAuthorization.js';
34
35
 
35
36
  export function groundPortableColdConsumer(input = {}, options = {}) {
36
37
  const ingressKind = normalizeIngressKind(input.ingressKind || input.kind || (input.toolingAvailable === false ? COLD_START_INGRESS_KINDS.DEGRADED_CAPTURE : COLD_START_INGRESS_KINDS.HANDOFF));
@@ -59,7 +60,7 @@ export function groundPortableColdConsumer(input = {}, options = {}) {
59
60
 
60
61
  const bundle = input.bundle || input.package || input;
61
62
  const role = groundRecipientRole(input, handoff, bundle, orientation, selectedRoute, findings, materialContext);
62
- const holderBinding = groundHolderBinding(input, handoff, findings);
63
+ const holderBinding = groundHolderBinding(input, handoff, role, findings);
63
64
  const participation = groundParticipation(input, handoff, bundle, orientation, selectedRoute, findings, materialContext);
64
65
  const interaction = groundInteraction(input, handoff);
65
66
 
@@ -68,7 +69,12 @@ export function groundPortableColdConsumer(input = {}, options = {}) {
68
69
  }
69
70
 
70
71
  const blocked = findings.some((finding) => finding.severity === 'error');
71
- const degraded = degradedCapture.active || role.state === 'degraded' || holderBinding.state === 'unresolved' || interaction.modeState === 'unresolved' || participation.participantState === 'unresolved';
72
+ const degraded = degradedCapture.active
73
+ || role.state === 'degraded'
74
+ || holderBinding.state === 'unresolved'
75
+ || holderBinding.authorization?.state === 'unresolved'
76
+ || interaction.modeState === 'unresolved'
77
+ || participation.participantState === 'unresolved';
72
78
  return deepFreeze({
73
79
  schema: PORTABLE_COLD_CONSUMER_GROUNDING_SCHEMA_ID,
74
80
  version: 1,
@@ -178,13 +184,14 @@ function groundRecipientRole(input, handoff, bundle, orientation, selectedRoute,
178
184
  compatibility,
179
185
  exactBoundaryLoaded: selected ? selected.boundary : null,
180
186
  authorityBoundaryLoaded: selected ? selected.authorityBoundary : null,
187
+ holderRelationshipLoaded: selected ? selected.holderRelationship : null,
181
188
  interpretationLimitsLoaded: selected ? selected.interpretationLimits : null,
182
189
  boundary: 'A Handoff `To Kind: role` endpoint remains bounded even when current Role material is missing. Matching Role material qualifies the loaded boundary but does not prove a human holder, consent, or authority beyond the Role artifact itself.'
183
190
  });
184
191
  }
185
192
 
186
193
 
187
- function groundHolderBinding(input, handoff, findings) {
194
+ function groundHolderBinding(input, handoff, role, findings) {
188
195
  const raw = input.holderBinding || input.sessionHolderBinding || input.sessionRoleBinding || {};
189
196
  const explicit = typeof raw === 'string' ? { roleLabel: raw } : (raw && typeof raw === 'object' ? raw : {});
190
197
  const roleLabel = String(explicit.roleLabel || explicit.role || input.holderRole || input.sessionRole || '').trim();
@@ -193,6 +200,9 @@ function groundHolderBinding(input, handoff, findings) {
193
200
  const recipientRoleKind = normalizeToken(handoff.toKind || (recipientRoleLabel ? 'role' : ''));
194
201
  const roleRecipient = recipientRoleKind === 'role';
195
202
  const explicitlySupplied = Boolean(roleLabel || holderId);
203
+ const sourceDetail = holderBindingSourceDetail(input, explicit, explicitlySupplied);
204
+ const authorization = projectHolderBindingAuthorization(role);
205
+ const durableIdentity = holderDurableIdentityProjection(holderId);
196
206
 
197
207
  if (!roleRecipient) return deepFreeze({
198
208
  state: 'not-applicable',
@@ -201,6 +211,9 @@ function groundHolderBinding(input, handoff, findings) {
201
211
  recipientRoleLabel,
202
212
  recipientCompatibility: 'not-applicable',
203
213
  source: explicitlySupplied ? 'explicit-input' : 'none',
214
+ sourceDetail,
215
+ authorization,
216
+ durableIdentity,
204
217
  explicit: explicitlySupplied,
205
218
  inferredFromTransport: false,
206
219
  boundary: 'The selected Handoff recipient is not a Role endpoint, so no consuming-session Role holder binding is required or inferred.'
@@ -215,6 +228,9 @@ function groundHolderBinding(input, handoff, findings) {
215
228
  recipientRoleLabel,
216
229
  recipientCompatibility: 'unresolved',
217
230
  source: explicitlySupplied ? 'explicit-input' : 'none',
231
+ sourceDetail,
232
+ authorization,
233
+ durableIdentity,
218
234
  explicit: explicitlySupplied,
219
235
  inferredFromTransport: false,
220
236
  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.'
@@ -230,6 +246,9 @@ function groundHolderBinding(input, handoff, findings) {
230
246
  recipientRoleLabel,
231
247
  recipientCompatibility: 'mismatch',
232
248
  source: 'explicit-input',
249
+ sourceDetail,
250
+ authorization,
251
+ durableIdentity,
233
252
  explicit: true,
234
253
  inferredFromTransport: false,
235
254
  boundary: 'An explicit holder Role mismatch is contradictory and blocks act-ready grounding. Tooling does not relabel the session to make the route fit.'
@@ -243,12 +262,52 @@ function groundHolderBinding(input, handoff, findings) {
243
262
  recipientRoleLabel,
244
263
  recipientCompatibility: 'matched',
245
264
  source: 'explicit-input',
265
+ sourceDetail,
266
+ authorization,
267
+ durableIdentity,
246
268
  explicit: true,
247
269
  inferredFromTransport: false,
248
270
  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.'
249
271
  });
250
272
  }
251
273
 
274
+ function holderDurableIdentityProjection(holderId = '') {
275
+ return deepFreeze({
276
+ state: 'not-established',
277
+ declaredHolderId: String(holderId || ''),
278
+ boundary: 'A bounded session Role assertion and its assignment authorization do not establish durable Party/person/model holder identity. Exact holder/Party authority would be required separately.'
279
+ });
280
+ }
281
+
282
+ function holderBindingSourceDetail(input = {}, explicit = {}, explicitlySupplied = false) {
283
+ if (!explicitlySupplied) return deepFreeze({
284
+ kind: 'none',
285
+ locator: '',
286
+ authorityClass: 'none',
287
+ semanticAuthorityState: 'not-established',
288
+ qualifiedMaterialSource: false,
289
+ boundary: 'No consuming-session holder declaration was supplied.'
290
+ });
291
+ const declaredLocator = String(explicit.sourceLocator || explicit.source || '').trim();
292
+ let locator = declaredLocator;
293
+ if (!locator) {
294
+ if (input.holderBinding) locator = 'input.holderBinding';
295
+ else if (input.sessionHolderBinding) locator = 'input.sessionHolderBinding';
296
+ else if (input.sessionRoleBinding) locator = 'input.sessionRoleBinding';
297
+ else if (input.holderRole || input.holderId) locator = 'input.holderRole/input.holderId';
298
+ else if (input.sessionRole) locator = 'input.sessionRole';
299
+ else locator = 'explicit-session-input';
300
+ }
301
+ return deepFreeze({
302
+ kind: 'operator-session-input',
303
+ locator,
304
+ authorityClass: 'session-binding-input-only',
305
+ semanticAuthorityState: 'not-established',
306
+ qualifiedMaterialSource: false,
307
+ boundary: 'This source proves only the explicit consuming-session Role-capacity declaration supplied to Tooling. It is not semantic holder-assignment authority carried by qualified material.'
308
+ });
309
+ }
310
+
252
311
  function groundParticipation(input, handoff, bundle, orientation, selectedRoute, findings, materialContext) {
253
312
  const explicitParticipants = normalizeParticipants(input.participants || input.interaction?.participants || []);
254
313
  const packageRoleGrounding = resolvePackageParticipantRoles(bundle, orientation, selectedRoute, findings);
@@ -160,6 +160,7 @@ export function parseRoleMaterial(entry) {
160
160
  const roleSection = sectionText(parsed.body?.text || '', 'Role Identity');
161
161
  const boundarySection = sectionText(parsed.body?.text || '', 'Role Boundary');
162
162
  const authoritySection = sectionText(parsed.body?.text || '', 'Authority And Responsibility Boundary');
163
+ const holderSection = sectionText(parsed.body?.text || '', 'Holder Relationship');
163
164
  const limitsSection = sectionText(parsed.body?.text || '', 'Interpretation Limits');
164
165
  const label = sectionField(roleSection, 'Role Label');
165
166
  return deepFreeze({
@@ -172,6 +173,13 @@ export function parseRoleMaterial(entry) {
172
173
  roleKind: sectionField(roleSection, 'Role Kind'),
173
174
  boundary: Object.freeze({ inScope: sectionField(boundarySection, 'In Scope'), outOfScope: sectionField(boundarySection, 'Out Of Scope'), context: sectionField(boundarySection, 'Context') }),
174
175
  authorityBoundary: Object.freeze({ mayDo: sectionField(authoritySection, 'May Do'), doesNotAuthorize: sectionField(authoritySection, 'Does Not Authorize'), reviewBoundary: sectionField(authoritySection, 'Review Boundary') }),
176
+ holderRelationship: Object.freeze({
177
+ holderState: sectionField(holderSection, 'Holder State'),
178
+ currentHolder: sectionField(holderSection, 'Current Holder'),
179
+ possibleHolder: sectionField(holderSection, 'Possible Holder'),
180
+ unknownHolder: sectionField(holderSection, 'Unknown Holder'),
181
+ relationArtifact: sectionReferenceTarget(holderSection, 'Relation Artifact')
182
+ }),
175
183
  interpretationLimits: Object.freeze({ doesNotProve: sectionField(limitsSection, 'Does Not Prove'), mustNotBeTreatedAs: sectionField(limitsSection, 'Must Not Be Treated As') }),
176
184
  parentTrace: String(parsed.envelope?.parent?.trace || ''),
177
185
  parentSchemaId: String(parsed.envelope?.parent?.schema?.id || '')
@@ -232,6 +240,9 @@ function hydrateRequiredContextEntry(bundle = {}, entry = {}, context = null) {
232
240
  const base = {
233
241
  requirementId: String(entry.requirementId || ''),
234
242
  name: String(entry.name || ''),
243
+ material: String(entry.material || ''),
244
+ purpose: String(entry.purpose || ''),
245
+ declaredAvailability: String(entry.declaredAvailability || ''),
235
246
  state: String(entry.state || resolution.state || 'unresolved'),
236
247
  referenceTarget: String(entry.referenceTarget || ''),
237
248
  kind: String(resolution.kind || ''),
@@ -241,7 +252,14 @@ function hydrateRequiredContextEntry(bundle = {}, entry = {}, context = null) {
241
252
  packagePath: String(resolution.packagePath || ''),
242
253
  providerMode: String(resolution.providerMode || ''),
243
254
  bytes: Number(resolution.bytes || 0),
244
- sha256: String(resolution.sha256 || '')
255
+ sha256: String(resolution.sha256 || ''),
256
+ provenance: Object.freeze({
257
+ basis: 'selected-handoff-required-context-declaration',
258
+ declarationSource: entry.declarationSource ? Object.freeze({ ...(entry.declarationSource || {}) }) : null,
259
+ resolutionKind: String(resolution.kind || ''),
260
+ providerMode: String(resolution.providerMode || ''),
261
+ boundary: 'Material/Purpose/Availability are copied from the exact selected Handoff Required Context declaration; qualification and bytes come from exact route closure resolution.'
262
+ })
245
263
  };
246
264
  if (base.state !== 'qualified') return Object.freeze({ ...base, contentState: 'unavailable', content: '' });
247
265
  const hydrated = resolveQualifiedMaterialBytes(bundle, resolution, context);
@@ -184,7 +184,7 @@ function auditRecipientV2(bundle = {}) {
184
184
  sha256: String(material.sha256 || '')
185
185
  })))
186
186
  : [];
187
- return deepFreeze({ schema: PORTABLE_HANDOFF_CONTEXT_AUDIT_SCHEMA_ID, status: inspection.status === 'valid' && !unexplained ? 'ready' : 'blocked', coverage: Object.freeze({ nonControlCarrierCount: files.length, classifiedCarrierCount: classified, unexplainedCarrierCount: unexplained, state: unexplained ? 'incomplete' : 'qualified' }), workspaceMaterializations: Object.freeze((inspection.workspaces || []).map((item) => Object.freeze({ workspaceId: item.workspaceId, reason: 'complete-workspace-archive-representation', qualification: 'qualified', carrierMode: 'archive', workspaceTargetPackagePath: item.workspaceArtifactPath, archivePackagePath: item.workspaceArchivePath, sourceWorkspaceTargetInnerPath: item.sourceWorkspaceTargetInnerPath, sourceWorkspaceTargetSha256: item.sourceWorkspaceTargetSha256 }))), lineageMaterializations: Object.freeze(lineageMaterializations), materialCarriers: Object.freeze([]), generatedEntrypoints: Object.freeze([String(inspection.rootArtifact?.path || ''), RECIPIENT_V2_READ_PATH, ...(inspection.endpointRoles || []).map((item) => item.pointerPath), ...(inspection.participantRoles || []).map((item) => item.pointerPath), ...(inspection.routes || []).map((item) => item.pointerPath)].filter(Boolean)), namedPackageRequirements: Object.freeze([]), explicitDetachedMaterial: Object.freeze(cacheMaterials), unexplainedCarriers: Object.freeze([]), duplicateByteSummary: Object.freeze({ materialCarriersAlsoPresentInWorkspace: 0, totalMaterialCarriers: cacheMaterials.length, interpretation: 'Exact Workspace-scoped recipient cache material is permitted only when not satisfied by a qualified Workspace archive.' }), routeGrounding: Object.freeze((inspection.carrierProjection?.routes || []).map((route) => Object.freeze({ routeId: route.id, workspaceId: route.workspaceId, handoffPackagePath: route.packagePath, required: route.requiredClosure?.requirements || [] }))), inspections: Object.freeze({ recipientV2: inspection.status, parentBoundaryGrounding: parentBoundaryGroundingEligible ? 'qualified-package-v1' : 'not-projected' }), findings: Object.freeze(dedupeFindings(findings)), boundary: 'Recipient-facing v2 carriage audit over qualified visible Tiinex artifacts and exact payload bytes. Complete Workspace snapshots and independently qualified package-v1 detached Parent-boundary lineage are projected separately; detached lineage never implies whole-Workspace carriage or membership.' });
187
+ return deepFreeze({ schema: PORTABLE_HANDOFF_CONTEXT_AUDIT_SCHEMA_ID, status: inspection.status === 'valid' && !unexplained ? 'ready' : 'blocked', coverage: Object.freeze({ nonControlCarrierCount: files.length, classifiedCarrierCount: classified, unexplainedCarrierCount: unexplained, state: unexplained ? 'incomplete' : 'qualified' }), workspaceMaterializations: Object.freeze((inspection.workspaces || []).map((item) => Object.freeze({ workspaceId: item.workspaceId, coverage: String(item.coverage || 'unresolved'), reason: String(item.coverage || '') === 'complete' ? 'complete-workspace-archive-representation' : String(item.coverage || '') === 'bounded' ? 'bounded-workspace-archive-representation' : 'workspace-archive-representation', qualification: 'qualified', carrierMode: 'archive', workspaceTargetPackagePath: item.workspaceArtifactPath, archivePackagePath: item.workspaceArchivePath, sourceWorkspaceTargetInnerPath: item.sourceWorkspaceTargetInnerPath, sourceWorkspaceTargetSha256: item.sourceWorkspaceTargetSha256 }))), lineageMaterializations: Object.freeze(lineageMaterializations), materialCarriers: Object.freeze([]), generatedEntrypoints: Object.freeze([String(inspection.rootArtifact?.path || ''), RECIPIENT_V2_READ_PATH, ...(inspection.endpointRoles || []).map((item) => item.pointerPath), ...(inspection.participantRoles || []).map((item) => item.pointerPath), ...(inspection.routes || []).map((item) => item.pointerPath)].filter(Boolean)), namedPackageRequirements: Object.freeze([]), explicitDetachedMaterial: Object.freeze(cacheMaterials), unexplainedCarriers: Object.freeze([]), duplicateByteSummary: Object.freeze({ materialCarriersAlsoPresentInWorkspace: 0, totalMaterialCarriers: cacheMaterials.length, interpretation: 'Exact Workspace-scoped recipient cache material is permitted only when not satisfied by a qualified Workspace archive.' }), routeGrounding: Object.freeze((inspection.carrierProjection?.routes || []).map((route) => Object.freeze({ routeId: route.id, workspaceId: route.workspaceId, handoffPackagePath: route.packagePath, required: route.requiredClosure?.requirements || [] }))), inspections: Object.freeze({ recipientV2: inspection.status, parentBoundaryGrounding: parentBoundaryGroundingEligible ? 'qualified-package-v1' : 'not-projected' }), findings: Object.freeze(dedupeFindings(findings)), boundary: 'Recipient-facing v2 carriage audit over qualified visible Tiinex artifacts and exact payload bytes. Complete Workspace snapshots and independently qualified package-v1 detached Parent-boundary lineage are projected separately; detached lineage never implies whole-Workspace carriage or membership.' });
188
188
  }
189
189
 
190
190
  function indexWorkspaceEntries(workspaces = []) {