@tiinex/core 0.3.0 → 0.5.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 (41) hide show
  1. package/package.json +8 -6
  2. package/src/public/index.js +21 -0
  3. package/src/public/node.js +1 -0
  4. package/src/release/plan.mjs +18 -5
  5. package/src/release/run.mjs +7 -5
  6. package/src/tooling/portable/adapters/cli/cli.command-input.js +3 -0
  7. package/src/tooling/portable/adapters/cli/cli.common-output.js +23 -0
  8. package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +3 -1
  9. package/src/tooling/portable/adapters/cli/cli.help.js +18 -2
  10. package/src/tooling/portable/adapters/cli/cli.material-policy.js +0 -1
  11. package/src/tooling/portable/adapters/cli/cli.operator-bridge.js +0 -13
  12. package/src/tooling/portable/adapters/cli/cli.run.js +1 -1
  13. package/src/tooling/portable/adapters/cli/cli.source-frontier-comparison.js +50 -0
  14. package/src/tooling/portable/adapters/node/handoff.manufacture.js +14 -0
  15. package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +80 -16
  16. package/src/tooling/portable/adapters/node/handoff.manufacture.requirements.js +44 -11
  17. package/src/tooling/portable/adapters/node/handoff.manufacture.scope.js +96 -1
  18. package/src/tooling/portable/adapters/node/sourceFrontierComparison.js +194 -0
  19. package/src/tooling/portable/comparison/sourceFrontierComparison.js +501 -0
  20. package/src/tooling/portable/grounding/grounding.readiness.js +8 -4
  21. package/src/tooling/portable/grounding/grounding.readiness.support.js +63 -1
  22. package/src/tooling/portable/handoff/contextAudit.js +21 -1
  23. package/src/tooling/portable/handoff/materialClosure.descriptor.js +1 -1
  24. package/src/tooling/portable/handoff/materialClosure.materials.js +1 -1
  25. package/src/tooling/portable/handoff/recipientV2.artifacts.js +1 -1
  26. package/src/tooling/portable/handoff/recipientV2.inspect.helpers.js +6 -1
  27. package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +93 -19
  28. package/src/tooling/portable/handoff/recipientV2.packageV1.contract.js +30 -1
  29. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.helpers.js +8 -2
  30. package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +122 -10
  31. package/src/tooling/portable/handoff/recipientV2.packageV1.js +2 -1
  32. package/src/tooling/portable/handoff/recipientV2.packageV1.secure.js +87 -0
  33. package/src/tooling/portable/handoff/recipientV2.packageV1.shared.js +9 -1
  34. package/src/tooling/portable/handoff/recipientV2.topology.js +2 -2
  35. package/src/tooling/portable/handoff/recipientV2.topology.materials.js +9 -1
  36. package/src/tooling/portable/handoff/transportEnvelopeV1.js +76 -0
  37. package/src/tooling/portable/index.js +4 -0
  38. package/src/tooling/portable/operation.catalog.js +8 -0
  39. package/src/tooling/portable/operation.catalog.package.js +0 -8
  40. package/src/transport/secureTransportV1.js +339 -0
  41. package/src/tooling/portable/handoff/sourceFrontierComparison.js +0 -186
@@ -21,7 +21,7 @@ export async function projectManufacturingRequirements({ handoff, workspaceId, h
21
21
  if (!runtime) throw new Error(`portable.handoff-manufacture.route.workspace-unresolved:${routeWorkspaceId}`);
22
22
  const routeMarkdown = routeWorkspaceId === workspaceId && routePath === handoffPath
23
23
  ? handoff.markdown
24
- : await readWorkspaceText(runtime.root, routePath, 'portable.handoff-manufacture.route.path');
24
+ : await readWorkspaceRuntimeText(runtime, routePath, 'portable.handoff-manufacture.route.path');
25
25
  const projected = routeWorkspaceId === workspaceId && routePath === handoffPath
26
26
  ? primary
27
27
  : projectHandoffMaterialRequirements({ id: routePath, path: routePath, semanticStatus: 'unknown', markdown: routeMarkdown });
@@ -75,7 +75,7 @@ export async function resolveWorkspaceRequirementMaterials(requirements, workspa
75
75
  const targetRuntime = workspaceRuntimeById.get(targetWorkspaceId);
76
76
  const entry = targetRuntime ? entryFromEnumeration(targetRuntime.enumeration, targetPath) : null;
77
77
  if (entry) {
78
- out.push(materialCandidateFromWorkspaceEntry(requirement, targetWorkspaceId, targetPath, entry, targetRuntime.enumeration));
78
+ out.push(materialCandidateFromWorkspaceEntry(requirement, targetWorkspaceId, targetPath, entry, targetRuntime.enumeration, targetRuntime));
79
79
  continue;
80
80
  }
81
81
  }
@@ -85,20 +85,28 @@ export async function resolveWorkspaceRequirementMaterials(requirements, workspa
85
85
  if (workspaceQualified) {
86
86
  const targetRuntime = workspaceRuntimeById.get(workspaceQualified.workspaceId);
87
87
  const entry = targetRuntime ? entryFromEnumeration(targetRuntime.enumeration, workspaceQualified.path) : null;
88
- if (entry) out.push(materialCandidateFromWorkspaceEntry(requirement, workspaceQualified.workspaceId, workspaceQualified.path, entry, targetRuntime.enumeration));
88
+ if (entry) out.push(materialCandidateFromWorkspaceEntry(requirement, workspaceQualified.workspaceId, workspaceQualified.path, entry, targetRuntime.enumeration, targetRuntime));
89
89
  continue;
90
90
  }
91
91
  if (isExternalReference(target) || target.startsWith('#')) continue;
92
92
  const routeWorkspaceId = String(requirement.routeWorkspaceId || [...workspaceRuntimeById.keys()][0] || '');
93
93
  const runtime = workspaceRuntimeById.get(routeWorkspaceId);
94
94
  if (!runtime) continue;
95
+ if (!runtime.root) {
96
+ const relative = resolveRelativeWorkspaceTarget(String(requirement.routePath || ''), target);
97
+ if (!relative) continue;
98
+ const entry = entryFromEnumeration(runtime.enumeration, relative);
99
+ if (!entry) continue;
100
+ out.push(materialCandidateFromWorkspaceEntry(requirement, routeWorkspaceId, relative, entry, runtime.enumeration, runtime));
101
+ continue;
102
+ }
95
103
  const handoffDir = path.dirname(path.resolve(runtime.root, String(requirement.routePath || '')));
96
104
  const absolute = path.resolve(handoffDir, decodeURIComponent(target.split('#')[0]));
97
105
  if (!inside(runtime.root, absolute)) continue;
98
106
  const relative = normalizeRelativePath(path.relative(runtime.root, absolute));
99
107
  const entry = entryFromEnumeration(runtime.enumeration, relative);
100
108
  if (!entry) continue;
101
- out.push(materialCandidateFromWorkspaceEntry(requirement, routeWorkspaceId, relative, entry, runtime.enumeration));
109
+ out.push(materialCandidateFromWorkspaceEntry(requirement, routeWorkspaceId, relative, entry, runtime.enumeration, runtime));
102
110
  }
103
111
  return out;
104
112
  }
@@ -207,7 +215,7 @@ async function resolveDerivedDependencyMaterial(requirement, sourceMaterial, wor
207
215
  if (requirement.targetWorkspaceId && requirement.targetPath) {
208
216
  const runtime = workspaceRuntimeById.get(String(requirement.targetWorkspaceId));
209
217
  const entry = runtime ? entryFromEnumeration(runtime.enumeration, requirement.targetPath) : null;
210
- if (entry) return materialCandidateFromWorkspaceEntry(requirement, requirement.targetWorkspaceId, requirement.targetPath, entry, runtime.enumeration);
218
+ if (entry) return materialCandidateFromWorkspaceEntry(requirement, requirement.targetWorkspaceId, requirement.targetPath, entry, runtime.enumeration, runtime);
211
219
  }
212
220
  const target = String(requirement.reference?.target || '');
213
221
  const sourcePath = String(sourceMaterial.provenance?.sourcePath || '').trim();
@@ -291,7 +299,19 @@ export function entryFromEnumeration(enumeration = {}, relative = '') {
291
299
  return matches.length === 1 ? matches[0] : null;
292
300
  }
293
301
 
294
- export function materialCandidateFromWorkspaceEntry(requirement, workspaceId, relative, entry, enumeration) {
302
+ export function materialCandidateFromWorkspaceEntry(requirement, workspaceId, relative, entry, enumeration, runtime = {}) {
303
+ const packageParentProvider = String(runtime.provider || '').startsWith('qualified-package-parent-workspace');
304
+ const materializationSource = enumeration?.materialization?.source || {};
305
+ const provenance = packageParentProvider
306
+ ? Object.freeze({
307
+ workspaceId,
308
+ path: relative,
309
+ boundary: '.',
310
+ parentPackagePath: String(materializationSource.parentPackagePath || ''),
311
+ parentPackageSha256: String(materializationSource.parentPackageSha256 || ''),
312
+ parentWorkspaceArchivePath: String(materializationSource.parentWorkspaceArchivePath || '')
313
+ })
314
+ : Object.freeze({ workspaceId, path: relative, boundary: '.' });
295
315
  return Object.freeze({
296
316
  requirementId: requirement.id,
297
317
  referenceTarget: String(requirement.reference?.target || requirement.referenceTarget || ''),
@@ -300,10 +320,14 @@ export function materialCandidateFromWorkspaceEntry(requirement, workspaceId, re
300
320
  bytes: entry.bytes,
301
321
  sha256: entry.sha256,
302
322
  mediaType: entry.mediaType,
303
- providerId: 'node-workspace-enumerator',
304
- providerKind: 'qualified-local-workspace',
305
- provenance: Object.freeze({ workspaceId, path: relative, boundary: '.' }),
306
- authority: Object.freeze({ localIdentityQualified: true, completenessEvidenceFingerprint: enumeration.evidence.entriesFingerprint })
323
+ providerId: packageParentProvider ? 'package-parent-workspace-enumerator' : 'node-workspace-enumerator',
324
+ providerKind: packageParentProvider ? 'qualified-package-parent-workspace' : 'qualified-local-workspace',
325
+ provenance,
326
+ authority: Object.freeze({
327
+ localIdentityQualified: true,
328
+ packageParentWorkspaceQualified: packageParentProvider,
329
+ completenessEvidenceFingerprint: enumeration.evidence.entriesFingerprint
330
+ })
307
331
  });
308
332
  }
309
333
 
@@ -316,7 +340,7 @@ function materialCandidateFromWorkspaceBinding(requirement, binding, workspaceRu
316
340
  const runtime = workspaceRuntimeById.get(workspaceId);
317
341
  const entry = runtime ? entryFromEnumeration(runtime.enumeration, relative) : null;
318
342
  if (!entry) return null;
319
- return materialCandidateFromWorkspaceEntry(requirement, workspaceId, relative, entry, runtime.enumeration);
343
+ return materialCandidateFromWorkspaceEntry(requirement, workspaceId, relative, entry, runtime.enumeration, runtime);
320
344
  }
321
345
 
322
346
  async function materialCandidateFromBinding(requirement, binding, workspaceRoot) {
@@ -343,6 +367,15 @@ async function readWorkspaceText(root, relative, code) {
343
367
  return readFile(absolute, 'utf8');
344
368
  }
345
369
 
370
+ async function readWorkspaceRuntimeText(runtime, relative, code) {
371
+ if (runtime?.root) return readWorkspaceText(runtime.root, relative, code);
372
+ const entry = entryFromEnumeration(runtime?.enumeration, relative);
373
+ if (!entry) throw new Error(`${code}.unresolved`);
374
+ const markdown = decodeUtf8(entry.data);
375
+ if (!markdown) throw new Error(`${code}.non-text`);
376
+ return markdown;
377
+ }
378
+
346
379
 
347
380
  export function normalizeRelativePath(value = '') { return String(value || '').replace(/\\/g, '/').replace(/^\/+/, '').split('/').filter((part) => part && part !== '.').join('/'); }
348
381
  function inside(root, absolute) { const relative = path.relative(root, absolute); return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative)); }
@@ -1,4 +1,5 @@
1
1
  import { parseArtifactMarkdown } from '../../../../artifacts/artifact.parse.js';
2
+ import { parseWorkspaceQualifiedReference } from '../../handoff/workspaceQualifiedReference.js';
2
3
  import { safeWorkspaceToken } from './handoff.manufacture.multiRoot.js';
3
4
  import {
4
5
  decodeUtf8,
@@ -136,7 +137,7 @@ export function expandBoundedParentBoundaryClosure(input = {}) {
136
137
  fields: Object.freeze({ RouteWorkspace: workspaceId, RoutePath: sourcePath, TargetWorkspace: workspaceId, TargetPath: parentPath, Reference: reference })
137
138
  });
138
139
  dependencies.push(requirement);
139
- materials.push(materialCandidateFromWorkspaceEntry(requirement, workspaceId, parentPath, parentEntry, runtime.enumeration));
140
+ materials.push(materialCandidateFromWorkspaceEntry(requirement, workspaceId, parentPath, parentEntry, runtime.enumeration, runtime));
140
141
  }
141
142
  }
142
143
  }
@@ -145,3 +146,97 @@ export function expandBoundedParentBoundaryClosure(input = {}) {
145
146
  materials: Object.freeze(materials)
146
147
  });
147
148
  }
149
+
150
+ export function expandRouteParentBoundaryClosure(input = {}) {
151
+ const requirements = input.requirements || {};
152
+ const dependencies = [...(requirements.dependencies || [])];
153
+ const materials = [...(input.materials || [])];
154
+ const materializationByWorkspaceId = new Map((input.workspaceMaterializations || []).map((item) => [String(item.id || item.workspaceId || ''), item]));
155
+ const seenRequirementIds = new Set(dependencies.map((item) => String(item.id || '')));
156
+ const seenRouteTargets = new Set(dependencies.map((item) => `${String(item.routeWorkspaceId || '')}\0${normalizeRelativePath(item.routePath || '')}\0${String(item.targetWorkspaceId || '')}\0${normalizeRelativePath(item.targetPath || '')}`));
157
+
158
+ for (const route of input.routeSpecs || []) {
159
+ const routeWorkspaceId = String(route.workspaceId || '').trim();
160
+ const routePath = normalizeRelativePath(route.path || route.workspaceRelativePath || '');
161
+ if (!routeWorkspaceId || !routePath) continue;
162
+ let currentWorkspaceId = routeWorkspaceId;
163
+ let currentPath = routePath;
164
+ const visited = new Set();
165
+ for (let depth = 0; depth < 256; depth += 1) {
166
+ const visitKey = `${currentWorkspaceId}\0${currentPath}`;
167
+ if (visited.has(visitKey)) break;
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);
173
+ if (!markdown) break;
174
+ let parent;
175
+ try { parent = parseArtifactMarkdown(markdown).envelope?.parent || {}; } catch { break; }
176
+ const reference = String(parent.trace || (parent.originEntries || []).find((item) => String(item?.label || '').trim() === 'relative')?.target || '').trim();
177
+ if (!reference) break;
178
+
179
+ let targetWorkspaceId = currentWorkspaceId;
180
+ let targetPath = '';
181
+ const qualified = parseWorkspaceQualifiedReference(reference);
182
+ if (qualified) {
183
+ targetWorkspaceId = qualified.workspaceId;
184
+ targetPath = normalizeRelativePath(qualified.path);
185
+ } else {
186
+ if (isExternalReference(reference) || reference.startsWith('#')) break;
187
+ targetPath = resolveRelativeWorkspaceTarget(currentPath, reference);
188
+ }
189
+ if (!targetWorkspaceId || !targetPath) break;
190
+
191
+ const targetRuntime = input.workspaceRuntimeById?.get(targetWorkspaceId);
192
+ const targetEntry = targetRuntime ? entryFromEnumeration(targetRuntime.enumeration, targetPath) : null;
193
+ const targetMaterialization = materializationByWorkspaceId.get(targetWorkspaceId);
194
+ const targetAlreadyCarried = workspaceMaterializationIncludesPath(targetMaterialization, targetPath);
195
+ const routeTargetKey = `${routeWorkspaceId}\0${routePath}\0${targetWorkspaceId}\0${targetPath}`;
196
+ if (!targetAlreadyCarried && !seenRouteTargets.has(routeTargetKey)) {
197
+ seenRouteTargets.add(routeTargetKey);
198
+ const id = `route-parent:${safeWorkspaceToken(routeWorkspaceId)}:${sha256Text(`${routePath}\0${currentWorkspaceId}\0${currentPath}\0${targetWorkspaceId}\0${targetPath}`).slice(0, 20)}`;
199
+ if (!seenRequirementIds.has(id)) {
200
+ seenRequirementIds.add(id);
201
+ const requirement = Object.freeze({
202
+ id,
203
+ name: `Route Parent boundary for ${currentWorkspaceId}:${currentPath}`,
204
+ classification: 'parent-boundary',
205
+ material: 'exact detached Parent continuity dependency',
206
+ purpose: 'preserve selected Handoff route continuity across a Workspace carriage boundary without requiring complete unrelated Workspace carriage',
207
+ availability: 'declared',
208
+ materialReference: reference,
209
+ reference: Object.freeze({ form: qualified ? 'parent-workspace-qualified-target' : 'parent-relative-target', raw: reference, label: '', target: reference, exactTargetDeclared: true }),
210
+ routeWorkspaceId,
211
+ routePath,
212
+ sourceWorkspaceId: currentWorkspaceId,
213
+ sourcePath: currentPath,
214
+ targetWorkspaceId,
215
+ targetPath,
216
+ sourceRequirementId: '',
217
+ fields: Object.freeze({ RouteWorkspace: routeWorkspaceId, RoutePath: routePath, SourceWorkspace: currentWorkspaceId, SourcePath: currentPath, TargetWorkspace: targetWorkspaceId, TargetPath: targetPath, Reference: reference })
218
+ });
219
+ dependencies.push(requirement);
220
+ if (targetEntry) materials.push(materialCandidateFromWorkspaceEntry(requirement, targetWorkspaceId, targetPath, targetEntry, targetRuntime.enumeration, targetRuntime));
221
+ }
222
+ }
223
+ if (!targetEntry) break;
224
+ currentWorkspaceId = targetWorkspaceId;
225
+ currentPath = targetPath;
226
+ }
227
+ }
228
+
229
+ return Object.freeze({
230
+ requirements: Object.freeze({ ...requirements, dependencies: Object.freeze(dependencies), counts: Object.freeze({ ...(requirements.counts || {}), dependencies: dependencies.length }) }),
231
+ materials: Object.freeze(materials)
232
+ });
233
+ }
234
+
235
+ function workspaceMaterializationIncludesPath(materialization = null, targetPath = '') {
236
+ if (!materialization) return false;
237
+ const state = String(materialization.state || materialization.materialization || '');
238
+ if (state === 'complete') return true;
239
+ if (state !== 'bounded') return false;
240
+ const normalized = normalizeRelativePath(targetPath);
241
+ return (materialization.includedEntries || materialization.entries || []).some((entry) => normalizeRelativePath(entry.path || '') === normalized);
242
+ }
@@ -0,0 +1,194 @@
1
+ import path from 'node:path';
2
+ import { enumerateNodeWorkspace } from './handoff.manufacture.enumeration.js';
3
+ import { loadNodePortableInput } from '../../input/node.input.js';
4
+ import { inspectRecipientFacingV2Topology } from '../../handoff/recipientV2.inspect.js';
5
+ import { handoffWorkspaceProviderForId, listHandoffWorkspaceEntries } from '../../handoff/workspaceByteProvider.js';
6
+ import { safeWorkspaceToken } from './handoff.manufacture.multiRoot.js';
7
+ import { portableFinding } from '../../findings.js';
8
+ import {
9
+ PORTABLE_SOURCE_FRONTIER_SCHEMA_ID,
10
+ compareOrReconcilePortableSourceFrontiers,
11
+ createPortableSourceFrontier
12
+ } from '../../comparison/sourceFrontierComparison.js';
13
+
14
+ export const PORTABLE_NODE_SOURCE_FRONTIER_INPUT_SCHEMA_ID = 'tiinex.portable.node-source-frontier-input.v1';
15
+
16
+ export async function prepareNodeSourceFrontierComparisonInput(input = {}, options = {}) {
17
+ if (input.base || input.incoming || input.current) {
18
+ if (!input.base || !input.incoming || !input.current) return { base: invalidFrontier('base', 'three-way-input-incomplete'), incoming: invalidFrontier('incoming', 'three-way-input-incomplete'), current: invalidFrontier('current', 'three-way-input-incomplete') };
19
+ const [base, incoming, current] = await Promise.all([
20
+ prepareNodeSourceFrontier(input.base, { ...options, side: 'base' }),
21
+ prepareNodeSourceFrontier(input.incoming, { ...options, side: 'incoming' }),
22
+ prepareNodeSourceFrontier(input.current, { ...options, side: 'current' })
23
+ ]);
24
+ return Object.freeze({ base, incoming, current });
25
+ }
26
+ const [left, right] = await Promise.all([
27
+ prepareNodeSourceFrontier(input.left, { ...options, side: 'left' }),
28
+ prepareNodeSourceFrontier(input.right, { ...options, side: 'right' })
29
+ ]);
30
+ return Object.freeze({ left, right });
31
+ }
32
+
33
+ export async function compareNodeSourceFrontiers(input = {}, options = {}) {
34
+ const normalized = await prepareNodeSourceFrontierComparisonInput(input, options);
35
+ return compareOrReconcilePortableSourceFrontiers(normalized);
36
+ }
37
+
38
+ export async function prepareNodeSourceFrontier(descriptor = {}, options = {}) {
39
+ if (descriptor?.schema === PORTABLE_SOURCE_FRONTIER_SCHEMA_ID) return createPortableSourceFrontier(descriptor);
40
+ const kind = String(descriptor?.kind || '').trim().toLowerCase();
41
+ if (!kind) return invalidFrontier(options.side || '', 'input-kind-required', portableFinding('error', 'portable.source-frontier.node.kind-required', 'Node source-frontier input requires an explicit kind; filesystem/package type is never guessed.', { side: options.side || '' }));
42
+ if (kind === 'local-workspace') return frontierFromLocalWorkspace(descriptor, options);
43
+ if (kind === 'local-frontier') return frontierFromLocalWorkspaceSet(descriptor, options);
44
+ if (kind === 'handoff-package') return frontierFromHandoffPackage(descriptor, options);
45
+ if (kind === 'qualified-workspace-provider') return frontierFromQualifiedProvider(descriptor, options);
46
+ if (kind === 'normalized-frontier') return createPortableSourceFrontier(descriptor.frontier || descriptor.value || {});
47
+ return invalidFrontier(options.side || '', 'input-kind-unsupported', portableFinding('error', 'portable.source-frontier.node.kind-unsupported', 'Node source-frontier input kind is unsupported.', { kind, side: options.side || '' }));
48
+ }
49
+
50
+ async function frontierFromLocalWorkspace(descriptor, options) {
51
+ const rootText = String(descriptor.root || descriptor.path || descriptor.workspaceRoot || '').trim();
52
+ if (!rootText) return invalidFrontier(options.side || '', 'local-workspace-root-required', portableFinding('error', 'portable.source-frontier.node.local-root-required', 'Local Workspace comparison input requires an explicit root path.', { side: options.side || '' }));
53
+ const root = path.resolve(rootText);
54
+ const workspaceId = safeWorkspaceToken(descriptor.workspaceId || descriptor.id || path.basename(root) || 'workspace');
55
+ try {
56
+ const enumeration = await enumerateNodeWorkspace(root, enumerationOptions(descriptor, options, workspaceId));
57
+ if (enumeration.status !== 'qualified-complete') return invalidFrontier(options.side || '', `local-enumeration-${enumeration.status}`, portableFinding('error', 'portable.source-frontier.node.local-enumeration-unqualified', 'Local Workspace source enumeration did not qualify as complete under the shared manufacture snapshot contract.', { workspaceId, status: enumeration.status }));
58
+ return createPortableSourceFrontier({
59
+ id: descriptor.label || `${options.side || 'input'}:${workspaceId}`,
60
+ source: { kind: 'local-workspace', ref: root, snapshotContract: 'shared-handoff-manufacture-node-enumeration-v1' },
61
+ workspaces: [workspaceFromEnumeration(workspaceId, enumeration, root)],
62
+ boundary: 'Local source is enumerated by the same deterministic Node Workspace enumerator used by Handoff manufacture; excluded directories and symlink policy therefore remain shared.'
63
+ });
64
+ } catch (error) {
65
+ return createPortableSourceFrontier({ id: descriptor.label || options.side || '', state: 'qualification-error', source: { kind: 'local-workspace', ref: root }, workspaces: [{ workspaceId, state: 'unavailable', reason: 'local-workspace-read-failed', source: { kind: 'local-workspace', ref: root } }], findings: [portableFinding('error', 'portable.source-frontier.node.local-read-failed', 'Local Workspace source could not be enumerated.', { workspaceId, ref: root, detail: String(error?.message || error || '') })] });
66
+ }
67
+ }
68
+
69
+ async function frontierFromLocalWorkspaceSet(descriptor, options) {
70
+ const specs = Array.isArray(descriptor.workspaces) ? descriptor.workspaces : [];
71
+ if (!specs.length) return invalidFrontier(options.side || '', 'local-frontier-workspaces-required', portableFinding('error', 'portable.source-frontier.node.local-frontier-empty', 'Local multi-Workspace frontier requires at least one explicit Workspace root binding.', { side: options.side || '' }));
72
+ const results = await Promise.all(specs.map(async (spec, index) => {
73
+ const rootText = String(spec.root || spec.path || spec.workspaceRoot || '').trim();
74
+ if (!rootText) return { workspaceId: String(spec.workspaceId || spec.id || `workspace-${index + 1}`), state: 'unavailable', reason: 'local-workspace-root-required', source: { kind: 'local-workspace' }, finding: portableFinding('error', 'portable.source-frontier.node.local-root-required', 'Local frontier Workspace binding requires an explicit root path.', { index }) };
75
+ const root = path.resolve(rootText);
76
+ const workspaceId = safeWorkspaceToken(spec.workspaceId || spec.id || '');
77
+ if (!spec.workspaceId && !spec.id) return { workspaceId: `unresolved-${index + 1}`, state: 'qualification-error', reason: 'workspace-id-required', source: { kind: 'local-workspace', ref: root }, finding: portableFinding('error', 'portable.source-frontier.node.local-frontier-id-required', 'Every local multi-Workspace root requires an explicit Workspace id.', { ref: root }) };
78
+ try {
79
+ const enumeration = await enumerateNodeWorkspace(root, enumerationOptions({ ...descriptor, ...spec }, options, workspaceId));
80
+ if (enumeration.status !== 'qualified-complete') return { workspaceId, state: 'qualification-error', reason: `enumeration-${enumeration.status}`, source: { kind: 'local-workspace', ref: root }, finding: portableFinding('error', 'portable.source-frontier.node.local-enumeration-unqualified', 'Local frontier Workspace did not qualify as a complete manufacture-equivalent snapshot.', { workspaceId, status: enumeration.status }) };
81
+ return workspaceFromEnumeration(workspaceId, enumeration, root);
82
+ } catch (error) {
83
+ return { workspaceId, state: 'unavailable', reason: 'local-workspace-read-failed', source: { kind: 'local-workspace', ref: root }, finding: portableFinding('error', 'portable.source-frontier.node.local-read-failed', 'Local frontier Workspace source could not be enumerated.', { workspaceId, ref: root, detail: String(error?.message || error || '') }) };
84
+ }
85
+ }));
86
+ const findings = results.map((item) => item.finding).filter(Boolean);
87
+ return createPortableSourceFrontier({
88
+ id: descriptor.label || options.side || 'local-frontier',
89
+ state: findings.some((item) => item.severity === 'error') ? 'qualification-error' : 'qualified',
90
+ source: { kind: 'local-frontier', workspaceCount: specs.length, snapshotContract: 'shared-handoff-manufacture-node-enumeration-v1' },
91
+ workspaces: results.map(({ finding, ...workspace }) => workspace),
92
+ findings,
93
+ boundary: 'Explicit local multi-Workspace roots, each enumerated by the shared Handoff-manufacture Workspace snapshot contract. Workspace ids are never inferred across the multi-root boundary.'
94
+ });
95
+ }
96
+
97
+ async function frontierFromHandoffPackage(descriptor, options) {
98
+ const packagePathText = String(descriptor.path || descriptor.packagePath || descriptor.root || '').trim();
99
+ if (!packagePathText) return invalidFrontier(options.side || '', 'handoff-package-path-required', portableFinding('error', 'portable.source-frontier.node.package-path-required', 'Handoff-package comparison input requires an explicit package path.', { side: options.side || '' }));
100
+ const packagePath = path.resolve(packagePathText);
101
+ let material;
102
+ try {
103
+ material = await loadNodePortableInput([packagePath], { maxFiles: descriptor.maxCarrierFiles || options.maxCarrierFiles || 10000, maxTextBytes: descriptor.maxTextBytes || options.maxTextBytes || 16 * 1024 * 1024 });
104
+ } catch (error) {
105
+ return invalidFrontier(options.side || '', 'handoff-package-read-failed', portableFinding('error', 'portable.source-frontier.node.package-read-failed', 'Handoff package could not be read by current trusted Core Tooling.', { ref: packagePath, detail: String(error?.message || error || '') }));
106
+ }
107
+ const loaderErrors = (material.findings || []).filter((item) => item.severity === 'error');
108
+ const inspection = inspectRecipientFacingV2Topology(material);
109
+ if (loaderErrors.length || inspection.status !== 'valid') {
110
+ return createPortableSourceFrontier({
111
+ id: descriptor.label || options.side || '', state: 'qualification-error', source: { kind: 'handoff-package', ref: packagePath, qualification: inspection.status || 'invalid' }, workspaces: [],
112
+ findings: [...loaderErrors, ...(inspection.findings || []).filter((item) => item.severity === 'error').map((item) => portableFinding('error', item.code || 'portable.source-frontier.package-unqualified', item.message || 'Handoff package qualification failed.', { ref: item.path || packagePath }))],
113
+ boundary: 'Received Handoff package failed current trusted Core package qualification; no Workspace source paths are projected for comparison.'
114
+ });
115
+ }
116
+
117
+ const availableIds = new Set([...(inspection.workspaces || []).map((item) => String(item.workspaceId || '')), ...(inspection.sealedWorkspaces || []).map((item) => String(item.workspaceId || ''))].filter(Boolean));
118
+ const selectors = normalizeSelectors(descriptor.workspaceIds || descriptor.select || descriptor.workspaces);
119
+ const ids = selectors.length ? selectors : [...availableIds].sort();
120
+ const openedById = new Map((descriptor.openedWorkspaces || []).map((item) => [String(item?.workspaceId || ''), item]).filter(([id]) => id));
121
+ const sealedById = new Map((inspection.sealedWorkspaces || []).map((item) => [String(item.workspaceId || ''), item]).filter(([id]) => id));
122
+ const workspaces = ids.map((workspaceId) => {
123
+ if (!availableIds.has(workspaceId)) return { workspaceId, state: 'unavailable', reason: 'workspace-not-carried', source: { kind: 'handoff-package', ref: packagePath } };
124
+ const sealedBinding = sealedById.get(workspaceId) || null;
125
+ const opened = openedById.get(workspaceId) || null;
126
+ if (sealedBinding && authorizedOpenMatchesSealedBinding(opened, sealedBinding, workspaceId)) {
127
+ const normalized = workspaceFromProvider(workspaceId, opened.provider, { kind: 'authorized-opened-workspace-provider', packageRef: packagePath });
128
+ if (normalized.state === 'qualified') return normalized;
129
+ }
130
+ if (sealedBinding) return { workspaceId, state: 'locked', qualification: 'locked-qualified-sealed-binding', reason: opened ? 'authorized-open-result-does-not-match-sealed-binding' : 'password-sealed-workspace-not-opened', source: { kind: 'handoff-package', ref: packagePath, binding: 'password-sealed-workspace-byte-tree' } };
131
+ return workspaceFromProvider(workspaceId, inspection.workspaceByteProvider, { kind: 'qualified-handoff-package-workspace', packageRef: packagePath });
132
+ });
133
+ return createPortableSourceFrontier({
134
+ id: descriptor.label || options.side || path.basename(packagePath),
135
+ source: { kind: 'handoff-package', ref: packagePath, qualification: 'qualified-current-tooling', format: String(inspection.format || '') },
136
+ workspaces,
137
+ boundary: 'Handoff inputs are inspected by the receiver current trusted Core Tooling. Clear qualified Workspace providers expose exact path/hash source; sealed bindings remain locked unless caller supplies an already-authorized qualified opened provider.'
138
+ });
139
+ }
140
+
141
+ function authorizedOpenMatchesSealedBinding(opened, sealedBinding, workspaceId) {
142
+ if (!opened || opened.state !== 'opened-qualified' || !opened.provider) return false;
143
+ if (String(opened.workspaceId || '') !== String(workspaceId || '')) return false;
144
+ if (String(opened.workspaceArtifactPath || '') !== String(sealedBinding.workspaceArtifactPath || '')) return false;
145
+ if (String(opened.workspaceArtifactSha256 || '').toLowerCase() !== String(sealedBinding.workspaceArtifactSha256 || '').toLowerCase()) return false;
146
+ return true;
147
+ }
148
+
149
+ function frontierFromQualifiedProvider(descriptor, options) {
150
+ const provider = descriptor.provider || descriptor.value || null;
151
+ const providerIds = Array.isArray(provider?.workspaces) ? provider.workspaces.map((item) => String(item?.id || '')).filter(Boolean) : [];
152
+ const selectors = normalizeSelectors(descriptor.workspaceIds || descriptor.select || descriptor.workspaces);
153
+ const ids = selectors.length ? selectors : providerIds.sort();
154
+ if (!provider || !ids.length) return invalidFrontier(options.side || '', 'provider-unavailable', portableFinding('error', 'portable.source-frontier.node.provider-unavailable', 'Qualified Workspace provider input must expose at least one explicit or discoverable Workspace id.', { side: options.side || '' }));
155
+ return createPortableSourceFrontier({ id: descriptor.label || options.side || 'qualified-provider', source: { kind: 'qualified-workspace-provider' }, workspaces: ids.map((id) => workspaceFromProvider(id, provider, { kind: 'qualified-workspace-provider' })) });
156
+ }
157
+
158
+ function workspaceFromEnumeration(workspaceId, enumeration, root) {
159
+ return {
160
+ workspaceId, state: 'qualified', qualification: 'qualified-complete-manufacture-enumeration', source: { kind: 'local-workspace', ref: root },
161
+ entries: (enumeration.materialization?.includedEntries || []).map((entry) => ({ path: entry.path, bytes: entry.bytes, sha256: entry.sha256 })),
162
+ evidence: { ...(enumeration.evidence || {}), sourceSelection: 'enumerateNodeWorkspace' }
163
+ };
164
+ }
165
+
166
+ function workspaceFromProvider(workspaceId, provider, source) {
167
+ const workspace = handoffWorkspaceProviderForId(provider, workspaceId);
168
+ if (!workspace || workspace.state !== 'qualified') return { workspaceId, state: workspace?.state === 'locked' ? 'locked' : 'qualification-error', qualification: String(workspace?.state || 'provider-unresolved'), reason: 'qualified-workspace-provider-unresolved', source };
169
+ const entries = listHandoffWorkspaceEntries(provider, workspaceId);
170
+ return {
171
+ workspaceId, state: 'qualified', qualification: 'qualified-exact-package-provider', source,
172
+ entries: entries.map((entry) => ({ path: entry.path || entry.innerPath, bytes: entry.bytes, sha256: entry.sha256 })),
173
+ evidence: { providerSchema: String(provider.schema || ''), providerState: String(provider.status || ''), workspaceMode: String(workspace.mode || ''), coverage: String(workspace.materialization?.materialization || workspace.binding?.coverage || '') }
174
+ };
175
+ }
176
+
177
+ function enumerationOptions(descriptor, options, workspaceId) {
178
+ return {
179
+ workspaceId,
180
+ workspaceTitle: String(descriptor.workspaceTitle || descriptor.title || workspaceId),
181
+ sourceMetadata: descriptor.sourceMetadata || {},
182
+ excludeDirectories: descriptor.excludeDirectories || options.excludeDirectories,
183
+ maxFiles: descriptor.maxFiles || options.maxFiles
184
+ };
185
+ }
186
+
187
+ function normalizeSelectors(value) {
188
+ const list = Array.isArray(value) ? value : value ? String(value).split(',') : [];
189
+ return [...new Set(list.map((item) => typeof item === 'string' ? item.trim() : String(item?.workspaceId || item?.id || '').trim()).filter(Boolean))].sort();
190
+ }
191
+
192
+ function invalidFrontier(id, reason, finding = null) {
193
+ return createPortableSourceFrontier({ id, state: 'qualification-error', source: { kind: 'unavailable', reason }, workspaces: [], findings: [finding || portableFinding('error', 'portable.source-frontier.node.input-invalid', 'Node source-frontier input is invalid.', { reason })] });
194
+ }