@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.
- package/package.json +7 -5
- package/src/tooling/portable/adapters/cli/cli.command-input.js +8 -1
- package/src/tooling/portable/adapters/cli/cli.common-author.js +29 -5
- package/src/tooling/portable/adapters/cli/cli.common-output.js +38 -3
- package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +33 -17
- package/src/tooling/portable/adapters/cli/cli.handoff-sibling-allocation.js +139 -2
- package/src/tooling/portable/adapters/cli/cli.help.js +1 -1
- package/src/tooling/portable/adapters/cli/cli.run.js +4 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.js +25 -12
- package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +43 -0
- package/src/tooling/portable/grounding/grounding.capsule.js +22 -3
- package/src/tooling/portable/grounding/grounding.holderBindingAuthorization.js +81 -0
- package/src/tooling/portable/grounding/grounding.implementationSourceAuthority.js +109 -0
- package/src/tooling/portable/grounding/grounding.orchestrationReadiness.js +33 -0
- package/src/tooling/portable/grounding/grounding.participantAuthority.js +1 -1
- package/src/tooling/portable/grounding/grounding.participantContext.js +58 -0
- package/src/tooling/portable/grounding/grounding.processApplicability.js +38 -0
- package/src/tooling/portable/grounding/grounding.readiness.authority.js +63 -3
- package/src/tooling/portable/grounding/grounding.readiness.js +72 -12
- package/src/tooling/portable/grounding/grounding.readiness.support.js +5 -1
- package/src/tooling/portable/grounding/grounding.sourceEvidence.js +151 -9
- package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +12 -1
- package/src/tooling/portable/handoff/coldStartQualification.grounding.js +62 -3
- package/src/tooling/portable/handoff/coldStartQualification.materials.js +19 -1
- package/src/tooling/portable/handoff/contextAudit.js +1 -1
- package/src/tooling/portable/handoff/delegationReturnReservation.js +4 -2
- package/src/tooling/portable/handoff/manufacture.js +1 -0
- package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +3 -0
- package/src/tooling/portable/handoff/recipientV2.packageV1.inspect.js +1 -1
- package/src/tooling/portable/handoff/recoveryAcceptanceAudit.js +5 -3
- package/src/tooling/portable/schema/contract.field-domain.js +43 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiinex/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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,
|
|
@@ -78,6 +78,8 @@
|
|
|
78
78
|
"./tooling/portable/engine.facade.js": "./src/tooling/portable/engine.facade.js",
|
|
79
79
|
"./tooling/portable/grounding/grounding.capsule.js": "./src/tooling/portable/grounding/grounding.capsule.js",
|
|
80
80
|
"./tooling/portable/grounding/grounding.participantAuthority.js": "./src/tooling/portable/grounding/grounding.participantAuthority.js",
|
|
81
|
+
"./tooling/portable/grounding/grounding.processApplicability.js": "./src/tooling/portable/grounding/grounding.processApplicability.js",
|
|
82
|
+
"./tooling/portable/grounding/grounding.implementationSourceAuthority.js": "./src/tooling/portable/grounding/grounding.implementationSourceAuthority.js",
|
|
81
83
|
"./tooling/portable/grounding/grounding.readiness.js": "./src/tooling/portable/grounding/grounding.readiness.js",
|
|
82
84
|
"./tooling/portable/grounding/grounding.workProvenance.js": "./src/tooling/portable/grounding/grounding.workProvenance.js",
|
|
83
85
|
"./tooling/portable/handoff/carrierLineage.js": "./src/tooling/portable/handoff/carrierLineage.js",
|
|
@@ -169,12 +171,12 @@
|
|
|
169
171
|
"type": "git",
|
|
170
172
|
"url": "git+https://github.com/Tiinex/core.git"
|
|
171
173
|
},
|
|
172
|
-
"gitHead": "
|
|
174
|
+
"gitHead": "fe01706aecacbf28c66e2ac052e4f639170dfe73",
|
|
173
175
|
"tiinexRelease": {
|
|
174
176
|
"policy": "tiinex.master-npm-release.v1",
|
|
175
|
-
"sourceCommit": "
|
|
176
|
-
"sourceTree": "
|
|
177
|
+
"sourceCommit": "fe01706aecacbf28c66e2ac052e4f639170dfe73",
|
|
178
|
+
"sourceTree": "b4e5dbb825a1504fef53f1e5281d4bd6fd3c87ff",
|
|
177
179
|
"repository": "Tiinex/core",
|
|
178
|
-
"previousVersion": "0.
|
|
180
|
+
"previousVersion": "0.18.0"
|
|
179
181
|
}
|
|
180
182
|
}
|
|
@@ -117,7 +117,7 @@ export async function commandInput(parsed, runtime = {}) {
|
|
|
117
117
|
packageSourcePath: packagePath,
|
|
118
118
|
includeLegacyTopics: Boolean(flags['include-legacy-topics']),
|
|
119
119
|
includeRequiredContext: flags['include-required-context'] || '',
|
|
120
|
-
holderBinding: { roleLabel: flags['holder-role'] || '', holderId: flags['holder-id'] || '' },
|
|
120
|
+
holderBinding: { roleLabel: flags['holder-role'] || '', holderId: flags['holder-id'] || '', sourceLocator: holderBindingCliSource(flags) },
|
|
121
121
|
host,
|
|
122
122
|
recoveryAcceptance
|
|
123
123
|
},
|
|
@@ -471,4 +471,11 @@ function mergeLoadedMaterial(primary = {}, secondary = {}) {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
function normalizeRuntimePaths(value) { const paths = Array.isArray(value) ? value : value ? [value] : []; return paths.map((entry) => String(entry || '').trim()).filter(Boolean); }
|
|
474
|
+
function holderBindingCliSource(flags = {}) {
|
|
475
|
+
const fields = [];
|
|
476
|
+
if (Object.prototype.hasOwnProperty.call(flags, 'holder-role')) fields.push('--holder-role');
|
|
477
|
+
if (Object.prototype.hasOwnProperty.call(flags, 'holder-id')) fields.push('--holder-id');
|
|
478
|
+
return fields.length ? `cli:${fields.join(',')}` : '';
|
|
479
|
+
}
|
|
480
|
+
|
|
474
481
|
function splitFlag(value) { return !value || value === true ? [] : String(value).split(',').map((item) => item.trim()).filter(Boolean); }
|
|
@@ -31,8 +31,8 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
|
|
|
31
31
|
|
|
32
32
|
const parentReference = resolveParentReference(flags, state);
|
|
33
33
|
const parentSource = String(flags['parent-source'] || flags['parent-file'] || '').trim();
|
|
34
|
-
if (isWorkspaceQualifiedReference(parentReference) && !parentSource) throw new Error(
|
|
35
|
-
if (parentSource && !parentReference) throw new Error('portable.cli.author.parent.required');
|
|
34
|
+
if (isWorkspaceQualifiedReference(parentReference) && !parentSource) throw new Error(`portable.cli.author.parent-source.required: --parent ${parentReference} names an explicit cross-Workspace Parent. Supply --parent-source <local-file> containing the exact qualified Parent bytes; Tooling will not discover or fetch that Parent automatically.`);
|
|
35
|
+
if (parentSource && !parentReference) throw new Error('portable.cli.author.parent.required: --parent-source supplies Parent bytes but no semantic Parent reference. Supply --parent <workspace::path|relative-path> explicitly; Tooling will not infer Parent identity from the source file.');
|
|
36
36
|
if (isWorkspaceQualifiedReference(parentReference) && !requestedArtifactRelativePath && !targetDirectory) throw new Error('portable.cli.author.cross-workspace-parent.target-required');
|
|
37
37
|
const parentPath = parentReference ? (parentSource ? path.resolve(parentSource) : safeWorkspaceTarget(workspaceRoot, parentReference)) : '';
|
|
38
38
|
const artifactRelativePath = requestedArtifactRelativePath || await allocateArtifactRelativePath({ workspaceRoot, targetDirectory, parentRelativePath: parentReference, schemaId, title });
|
|
@@ -80,6 +80,7 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
|
|
|
80
80
|
}, {});
|
|
81
81
|
const blocking = Number(audit?.findingSummary?.counts?.error || 0) + Number(stage?.findingSummary?.counts?.error || 0);
|
|
82
82
|
if (blocking) {
|
|
83
|
+
const actionableFindings = projectAuthorActionableFindings(audit, stage);
|
|
83
84
|
await rm(artifactPath, { force: true });
|
|
84
85
|
wrote = false;
|
|
85
86
|
return Object.freeze({
|
|
@@ -90,7 +91,8 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
|
|
|
90
91
|
audit,
|
|
91
92
|
stage,
|
|
92
93
|
findingSummary: mergeFindingSummaries(audit?.findingSummary, stage?.findingSummary),
|
|
93
|
-
|
|
94
|
+
actionableFindings,
|
|
95
|
+
nextAction: actionableFindings[0]?.nextAction || 'Resolve the reported schema/continuity finding, then rerun the same author command. No invalid durable artifact was retained.',
|
|
94
96
|
boundary: 'Common-path authoring composes the shared renderer, c14n-v2 sealing, runtime audit, and staging qualification. It may write only the requested local Workspace artifact and runtime-only .tiinex continuation state; it performs no remote mutation.'
|
|
95
97
|
});
|
|
96
98
|
}
|
|
@@ -125,12 +127,12 @@ async function parentRecordFromArtifact(parentPath, parentRelativePath, context
|
|
|
125
127
|
const schemaId = String(current.schema?.id || '').trim();
|
|
126
128
|
const schemaTarget = String(current.schema?.target || '').trim();
|
|
127
129
|
const self = canonicalC14nV2SelfState(markdown);
|
|
128
|
-
if (!schemaId) throw new Error('portable.cli.author.parent.schema-authority.required');
|
|
130
|
+
if (!schemaId) throw new Error('portable.cli.author.parent.schema-authority.required: the supplied Parent does not declare a Current Schema. Supply exact qualified Parent bytes with an explicit Current Schema reference; Tooling will not infer Parent schema authority from path or filename.');
|
|
129
131
|
if (self.state !== 'verified') throw new Error(`portable.cli.author.parent.integrity.${self.reason || self.state}`);
|
|
130
132
|
const schemaReferenceAuthority = schemaTarget
|
|
131
133
|
? exactDeclaredSchemaReferenceAuthority(schemaId, schemaTarget)
|
|
132
134
|
: await recoverQualifiedRuntimeSchemaReferenceAuthority(schemaId, context.runtime || {});
|
|
133
|
-
if (!schemaReferenceAuthority) throw new Error(
|
|
135
|
+
if (!schemaReferenceAuthority) throw new Error(`portable.cli.author.parent.schema-authority.required: Parent schema ${schemaId} lacks an exact qualified schema-reference authority. Supply Parent bytes with an exact Current Schema target or qualified runtime canonical schema material; Tooling will not invent the schema target.`);
|
|
134
136
|
return Object.freeze({
|
|
135
137
|
id: parentRelativePath,
|
|
136
138
|
path: parentRelativePath,
|
|
@@ -144,6 +146,28 @@ async function parentRecordFromArtifact(parentPath, parentRelativePath, context
|
|
|
144
146
|
});
|
|
145
147
|
}
|
|
146
148
|
|
|
149
|
+
function projectAuthorActionableFindings(audit = {}, stage = {}) {
|
|
150
|
+
const findings = [
|
|
151
|
+
...(audit.findings || audit.actionableFindings || []),
|
|
152
|
+
...(stage.findings || stage.actionableFindings || [])
|
|
153
|
+
].filter((item) => item && (item.severity === 'error' || item.severity === 'warning'));
|
|
154
|
+
const seen = new Set();
|
|
155
|
+
const out = [];
|
|
156
|
+
for (const item of findings) {
|
|
157
|
+
const code = String(item.code || '');
|
|
158
|
+
const key = `${code}\u0000${String(item.message || '')}`;
|
|
159
|
+
if (seen.has(key)) continue;
|
|
160
|
+
seen.add(key);
|
|
161
|
+
out.push(Object.freeze({
|
|
162
|
+
code,
|
|
163
|
+
message: String(item.message || ''),
|
|
164
|
+
...(item.contractGuidance ? { contractGuidance: Object.freeze({ ...item.contractGuidance }) } : {}),
|
|
165
|
+
nextAction: String(item.contractGuidance?.nextAction || 'Resolve this exact finding using its cited authority/evidence, then rerun the same author command. No invalid durable artifact was retained.')
|
|
166
|
+
}));
|
|
167
|
+
}
|
|
168
|
+
return Object.freeze(out.slice(0, 20));
|
|
169
|
+
}
|
|
170
|
+
|
|
147
171
|
export function parentRecoveryMode(reference = '') {
|
|
148
172
|
const classification = classifyParentRecoveryReference(reference);
|
|
149
173
|
if (classification.kind === 'workspace-qualified') return 'workspace-qualified';
|
|
@@ -103,6 +103,7 @@ function projectGroundDefault(result = {}, parsed = {}) {
|
|
|
103
103
|
status: result.status,
|
|
104
104
|
readiness: compactReadiness(result.readiness),
|
|
105
105
|
authority: compactGroundAuthority(result.authority),
|
|
106
|
+
orchestrationReadiness: compactOrchestrationReadiness(result.orchestrationReadiness),
|
|
106
107
|
requiredContext: Object.freeze({
|
|
107
108
|
declared: Number(required.declared || 0),
|
|
108
109
|
matchedInWorkspaceSnapshots: Number(required.matchedInWorkspaceSnapshots || 0),
|
|
@@ -162,6 +163,7 @@ function projectHandoffDefault(result = {}, parsed = {}) {
|
|
|
162
163
|
status: String(carrier.status || ''),
|
|
163
164
|
mode: String(carrier.mode || ''),
|
|
164
165
|
lineage: carrier.lineage ? compactCarrierLineage(carrier.lineage) : null,
|
|
166
|
+
allocation: result.carrierAllocation ? Object.freeze({ ...result.carrierAllocation }) : null,
|
|
165
167
|
route: Object.freeze({
|
|
166
168
|
id: String(route.id || ''),
|
|
167
169
|
state: String(route.state || ''),
|
|
@@ -254,13 +256,18 @@ function compactGroundAuthority(authority = {}) {
|
|
|
254
256
|
route: Object.freeze({
|
|
255
257
|
id: String(route.id || ''),
|
|
256
258
|
pointerPath: String(route.pointerPath || ''),
|
|
257
|
-
workspaceId: String(route.workspaceId || '')
|
|
259
|
+
workspaceId: String(route.workspaceId || ''),
|
|
260
|
+
workspaceRelativePath: String(route.workspaceRelativePath || ''),
|
|
261
|
+
sha256: String(route.sha256 || ''),
|
|
262
|
+
provenance: route.provenance ? Object.freeze({ ...route.provenance }) : null
|
|
258
263
|
}),
|
|
259
264
|
handoff: Object.freeze({
|
|
260
265
|
purpose: String(handoff.purpose || ''),
|
|
261
266
|
from: String(handoff.from || ''),
|
|
262
267
|
to: String(handoff.to || ''),
|
|
263
|
-
completionExpectation: handoff.completionExpectation || null
|
|
268
|
+
completionExpectation: handoff.completionExpectation || null,
|
|
269
|
+
transfers: Object.freeze((handoff.transfers || []).map((item) => Object.freeze({ ...item }))),
|
|
270
|
+
provenance: handoff.provenance ? Object.freeze({ ...handoff.provenance }) : null
|
|
264
271
|
}),
|
|
265
272
|
role: Object.freeze({
|
|
266
273
|
state: String(role.state || ''),
|
|
@@ -269,13 +276,20 @@ function compactGroundAuthority(authority = {}) {
|
|
|
269
276
|
}),
|
|
270
277
|
holderBinding: Object.freeze({
|
|
271
278
|
state: String(holderBinding.state || ''),
|
|
279
|
+
bindingPresent: Boolean(holderBinding.bindingPresent),
|
|
280
|
+
declarationPresent: Boolean(holderBinding.declarationPresent),
|
|
272
281
|
holderId: String(holderBinding.holderId || ''),
|
|
273
282
|
roleLabel: String(holderBinding.roleLabel || ''),
|
|
274
283
|
recipientRoleLabel: String(holderBinding.recipientRoleLabel || ''),
|
|
275
284
|
recipientCompatibility: String(holderBinding.recipientCompatibility || ''),
|
|
276
285
|
source: String(holderBinding.source || ''),
|
|
286
|
+
sourceDetail: holderBinding.sourceDetail ? Object.freeze({ ...holderBinding.sourceDetail }) : null,
|
|
287
|
+
authorization: holderBinding.authorization ? Object.freeze({ ...holderBinding.authorization, provenance: holderBinding.authorization.provenance ? Object.freeze({ ...holderBinding.authorization.provenance }) : null }) : null,
|
|
288
|
+
durableIdentity: holderBinding.durableIdentity ? Object.freeze({ ...holderBinding.durableIdentity }) : Object.freeze({ state: 'not-established' }),
|
|
289
|
+
semanticAuthorityState: String(holderBinding.semanticAuthorityState || 'not-established'),
|
|
277
290
|
explicit: Boolean(holderBinding.explicit),
|
|
278
|
-
inferredFromTransport: Boolean(holderBinding.inferredFromTransport)
|
|
291
|
+
inferredFromTransport: Boolean(holderBinding.inferredFromTransport),
|
|
292
|
+
provenance: holderBinding.provenance ? Object.freeze({ ...holderBinding.provenance }) : null
|
|
279
293
|
}),
|
|
280
294
|
operationBoundary: Object.freeze({
|
|
281
295
|
sourceMutation: Boolean(operationBoundary.sourceMutation),
|
|
@@ -286,14 +300,35 @@ function compactGroundAuthority(authority = {}) {
|
|
|
286
300
|
});
|
|
287
301
|
}
|
|
288
302
|
|
|
303
|
+
function compactOrchestrationReadiness(value = {}) {
|
|
304
|
+
if (!value || typeof value !== 'object') return null;
|
|
305
|
+
const wider = value.widerOrchestration || {};
|
|
306
|
+
return Object.freeze({
|
|
307
|
+
state: String(value.state || ''),
|
|
308
|
+
boundedActionReadiness: String(value.boundedActionReadiness || ''),
|
|
309
|
+
widerOrchestration: Object.freeze({
|
|
310
|
+
state: String(wider.state || ''),
|
|
311
|
+
blockers: Object.freeze((wider.blockers || []).slice(0, 8).map((item) => Object.freeze({ ...item })))
|
|
312
|
+
}),
|
|
313
|
+
participantMap: String(value.participantMap || ''),
|
|
314
|
+
sourceScope: String(value.sourceScope || ''),
|
|
315
|
+
processApplicability: value.processApplicability ? Object.freeze({ ...value.processApplicability, unresolved: Object.freeze([...(value.processApplicability.unresolved || [])].map((item) => Object.freeze({ ...item }))) }) : null,
|
|
316
|
+
boundary: String(value.boundary || '')
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
289
320
|
function projectRequiredContextItem(item = {}) {
|
|
290
321
|
const contentProjected = Boolean(item.contentProjected && typeof item.content === 'string');
|
|
291
322
|
return Object.freeze({
|
|
292
323
|
requirementId: String(item.requirementId || ''),
|
|
293
324
|
name: String(item.name || ''),
|
|
325
|
+
material: String(item.material || ''),
|
|
326
|
+
purpose: String(item.purpose || ''),
|
|
327
|
+
declaredAvailability: String(item.declaredAvailability || ''),
|
|
294
328
|
state: String(item.state || ''),
|
|
295
329
|
workspaceId: String(item.workspaceId || ''),
|
|
296
330
|
innerPath: String(item.innerPath || ''),
|
|
331
|
+
provenance: item.provenance ? Object.freeze({ ...item.provenance }) : null,
|
|
297
332
|
contentProjected,
|
|
298
333
|
...(contentProjected ? { content: item.content } : {})
|
|
299
334
|
});
|
|
@@ -10,7 +10,7 @@ import { projectRecipientV2HumanOutput } from '../../handoff/recipientV2.humanOu
|
|
|
10
10
|
import { inspectRecipientFacingV2Topology } from '../../handoff/recipientV2.inspect.js';
|
|
11
11
|
import { carrierLineageFromCliParent, initialHandoffCarrierLineage, parentHandoffCarrierLineageFromBundle, parentHandoffCarrierProfileFromBundle } from '../../handoff/carrierLineage.js';
|
|
12
12
|
import { loadNodePortableInput } from '../../input/node.input.js';
|
|
13
|
-
import {
|
|
13
|
+
import { resolveHandoffSiblingAllocation } from './cli.handoff-sibling-allocation.js';
|
|
14
14
|
import { normalizeHandoffCarrierProfile } from '../../handoff/carrierProfile.js';
|
|
15
15
|
|
|
16
16
|
export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime = {}) {
|
|
@@ -26,7 +26,6 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
|
|
|
26
26
|
const handoffPath = flags.handoff || parsed.positionals?.[1] || continuationState.returnHandoffPath || '';
|
|
27
27
|
if (!flags['workspace-id'] && continuationState.workspaceId) flags['workspace-id'] = continuationState.workspaceId;
|
|
28
28
|
if (!flags['workspace-target'] && continuationState.workspaceTarget) flags['workspace-target'] = continuationState.workspaceTarget;
|
|
29
|
-
if (!flags['package-sibling-index'] && continuationState.returnPackageSiblingIndex) flags['package-sibling-index'] = continuationState.returnPackageSiblingIndex;
|
|
30
29
|
if (!flags['package-parent'] && continuationState.packageParentPath) flags['package-parent'] = continuationState.packageParentPath;
|
|
31
30
|
if (!flags.route && handoffPath) flags.route = handoffPath;
|
|
32
31
|
if (!flags.output && !flags['output-dir'] && parsed.surfaceCommand === 'handoff' && continuationState.returnOutputDir) flags['output-dir'] = continuationState.returnOutputDir;
|
|
@@ -55,6 +54,7 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
|
|
|
55
54
|
let packageParentSha256 = '';
|
|
56
55
|
let carrierLineage = initialHandoffCarrierLineage();
|
|
57
56
|
let inheritedCarrierProfile = normalizeHandoffCarrierProfile(null);
|
|
57
|
+
let carrierAllocation = Object.freeze({ state: 'root', allocationMode: 'initial-root', siblingIndex: null, provenance: Object.freeze({ basis: 'initial-carrier-root' }) });
|
|
58
58
|
if (parentPackagePath) {
|
|
59
59
|
const resolvedParent = path.resolve(parentPackagePath);
|
|
60
60
|
const parentBytes = new Uint8Array(await readFile(resolvedParent));
|
|
@@ -86,21 +86,35 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
|
|
|
86
86
|
major: Boolean(flags['package-major']),
|
|
87
87
|
majorReason: flags['major-reason'] || ''
|
|
88
88
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
89
|
+
if (flags['package-major']) {
|
|
90
|
+
carrierLineage = provisionalLineage;
|
|
91
|
+
carrierAllocation = Object.freeze({
|
|
92
|
+
state: 'qualified', allocationMode: 'explicit-major', siblingIndex: null,
|
|
93
|
+
provenance: Object.freeze({ basis: 'explicit-major-request', parentPackagePath: resolvedParent, parentPackageSha256: provisionalLineage.parentPackageSha256, parentDimension: provisionalLineage.parentDimension }),
|
|
94
|
+
boundary: 'Carrier Major creation remains explicit and separate from non-Major pointer-order allocation.'
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
const parentInspection = inspectRecipientFacingV2Topology(parentBundle);
|
|
98
|
+
const siblingAllocation = await resolveHandoffSiblingAllocation({
|
|
99
|
+
parentInspection,
|
|
100
|
+
parentPackagePath: resolvedParent,
|
|
101
|
+
parentPackageSha256: provisionalLineage.parentPackageSha256,
|
|
102
|
+
parentDimension: provisionalLineage.parentDimension,
|
|
103
|
+
selectedRoutePointer: continuationState.selectedRoutePointer || flags['package-parent-route-pointer'] || '',
|
|
104
|
+
selectedRouteId: continuationState.selectedRouteId || flags['package-parent-route-id'] || '',
|
|
105
|
+
explicitSiblingIndex: flags['package-sibling-index'],
|
|
106
|
+
enabled: Boolean(flags.output || flags['output-dir'])
|
|
107
|
+
});
|
|
108
|
+
carrierAllocation = siblingAllocation;
|
|
109
|
+
carrierLineage = carrierLineageFromCliParent({
|
|
110
|
+
bundle: parentBundle,
|
|
111
|
+
parentPath: resolvedParent,
|
|
112
|
+
parentBytes,
|
|
113
|
+
routeDimensions,
|
|
114
|
+
qualifiedParentLineage: parentLineage,
|
|
115
|
+
siblingIndex: siblingAllocation.siblingIndex
|
|
116
|
+
});
|
|
117
|
+
}
|
|
104
118
|
packageParentSha256 = String(carrierLineage.parentPackageSha256 || '');
|
|
105
119
|
} else if (flags['package-major']) {
|
|
106
120
|
throw new Error('portable.cli.handoff-carrier.package-major.parent-required');
|
|
@@ -129,6 +143,7 @@ export async function prepareHandoffManufactureCliCommand(parsed = {}, runtime =
|
|
|
129
143
|
verifyRoundtrip,
|
|
130
144
|
recipientRouteSelector: flags.route || '',
|
|
131
145
|
carrierLineage,
|
|
146
|
+
carrierAllocation,
|
|
132
147
|
carrierProfile,
|
|
133
148
|
packageParentBundle,
|
|
134
149
|
packageParentPath: parentPackagePath ? path.resolve(parentPackagePath) : '',
|
|
@@ -329,6 +344,7 @@ export function summarizeHandoffManufactureCliOutput(result = {}, writeReceipt =
|
|
|
329
344
|
}) : null,
|
|
330
345
|
toolingBootstrap: result.toolingBootstrap || null,
|
|
331
346
|
carrierLineage: result.carrierLineage || projection.lineage || null,
|
|
347
|
+
carrierAllocation: result.carrierAllocation || result.manufacturingEvidence?.carrierAllocation || null,
|
|
332
348
|
majorReadiness: result.majorReadiness || null,
|
|
333
349
|
operationBoundary: result.operationBoundary ? Object.freeze({ ...result.operationBoundary }) : null,
|
|
334
350
|
manufacturingEvidence: result.manufacturingEvidence || null,
|
|
@@ -2,6 +2,125 @@ import { mkdir, open, readFile } from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
const MAX_SIBLING_INDEX = 9999;
|
|
5
|
+
const POINTER_PATH_RE = /^(\d{3}(?:-\d+)*)-handoff-pointer\.trace\.md$/;
|
|
6
|
+
|
|
7
|
+
export function deriveHandoffSiblingAllocation({ parentInspection = null, selectedRoutePointer = '', selectedRouteId = '', explicitSiblingIndex = null, parentPackagePath = '', parentPackageSha256 = '', parentDimension = '' } = {}) {
|
|
8
|
+
const explicit = normalizeSiblingIndex(explicitSiblingIndex);
|
|
9
|
+
const inspection = parentInspection && typeof parentInspection === 'object' ? parentInspection : null;
|
|
10
|
+
if (!inspection || inspection.detected === false) return freeze({
|
|
11
|
+
state: 'unavailable',
|
|
12
|
+
siblingIndex: explicit || null,
|
|
13
|
+
allocationMode: explicit ? 'explicit-override-only' : 'unavailable',
|
|
14
|
+
reasonCode: 'qualified-parent-route-topology-unavailable',
|
|
15
|
+
provenance: provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
|
|
16
|
+
boundary: allocationBoundary()
|
|
17
|
+
});
|
|
18
|
+
if (String(inspection.status || '') !== 'valid') return freeze({
|
|
19
|
+
state: 'blocked',
|
|
20
|
+
siblingIndex: null,
|
|
21
|
+
allocationMode: 'blocked',
|
|
22
|
+
reasonCode: 'qualified-parent-route-topology-invalid',
|
|
23
|
+
provenance: provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
|
|
24
|
+
boundary: allocationBoundary()
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const routes = [...(inspection.routes || [])].map((route) => ({
|
|
28
|
+
pointerPath: String(route.pointerPath || '').trim(),
|
|
29
|
+
routeId: String(route.routeId || '').trim(),
|
|
30
|
+
workspaceId: String(route.workspaceId || '').trim(),
|
|
31
|
+
workspaceRelativeHandoffPath: String(route.workspaceRelativeHandoffPath || '').trim()
|
|
32
|
+
}));
|
|
33
|
+
if (!routes.length) return blocked('qualified-parent-route-topology-empty');
|
|
34
|
+
|
|
35
|
+
const qualified = [];
|
|
36
|
+
const seenDimensions = new Set();
|
|
37
|
+
for (const route of routes) {
|
|
38
|
+
const match = route.pointerPath.match(POINTER_PATH_RE);
|
|
39
|
+
if (!match) return blocked('qualified-parent-route-pointer-order-unresolved');
|
|
40
|
+
const dimension = match[1];
|
|
41
|
+
if (seenDimensions.has(dimension)) return blocked('qualified-parent-route-pointer-order-ambiguous');
|
|
42
|
+
seenDimensions.add(dimension);
|
|
43
|
+
qualified.push({ ...route, pointerDimension: dimension, pointerSegments: dimension.split('-').map((value) => Number.parseInt(value, 10)) });
|
|
44
|
+
}
|
|
45
|
+
qualified.sort(comparePointerOrder);
|
|
46
|
+
|
|
47
|
+
const pointerSelector = String(selectedRoutePointer || '').trim();
|
|
48
|
+
const routeIdSelector = String(selectedRouteId || '').trim();
|
|
49
|
+
let selected = null;
|
|
50
|
+
if (pointerSelector) {
|
|
51
|
+
const matches = qualified.filter((route) => route.pointerPath === pointerSelector);
|
|
52
|
+
if (matches.length !== 1) return blocked(matches.length ? 'selected-parent-route-pointer-ambiguous' : 'selected-parent-route-pointer-unqualified');
|
|
53
|
+
selected = matches[0];
|
|
54
|
+
}
|
|
55
|
+
if (routeIdSelector) {
|
|
56
|
+
const matches = qualified.filter((route) => route.routeId === routeIdSelector);
|
|
57
|
+
if (matches.length !== 1) return blocked(matches.length ? 'selected-parent-route-id-ambiguous' : 'selected-parent-route-id-unqualified');
|
|
58
|
+
if (selected && selected.pointerPath !== matches[0].pointerPath) return blocked('selected-parent-route-selector-conflict');
|
|
59
|
+
selected = matches[0];
|
|
60
|
+
}
|
|
61
|
+
if (!selected) {
|
|
62
|
+
if (qualified.length !== 1) return blocked('selected-parent-route-required-for-parallel-topology');
|
|
63
|
+
selected = qualified[0];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const siblingIndex = qualified.findIndex((route) => route.pointerPath === selected.pointerPath) + 1;
|
|
67
|
+
if (!Number.isInteger(siblingIndex) || siblingIndex < 1 || siblingIndex > MAX_SIBLING_INDEX) return blocked('derived-sibling-index-out-of-range');
|
|
68
|
+
if (explicit && explicit !== siblingIndex) return blocked('explicit-sibling-index-conflicts-with-qualified-topology', { expectedSiblingIndex: siblingIndex });
|
|
69
|
+
|
|
70
|
+
return freeze({
|
|
71
|
+
state: 'qualified',
|
|
72
|
+
siblingIndex,
|
|
73
|
+
childDimension: parentDimension ? `${String(parentDimension).trim()}-${siblingIndex}` : '',
|
|
74
|
+
allocationMode: 'qualified-parent-route-pointer-ordinal',
|
|
75
|
+
explicitOverride: explicit ? 'matched-derived-value' : 'not-supplied',
|
|
76
|
+
reasonCode: '',
|
|
77
|
+
provenance: {
|
|
78
|
+
...provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
|
|
79
|
+
basis: 'qualified-parent-route-pointer-ordinal',
|
|
80
|
+
selectedRoutePointer: selected.pointerPath,
|
|
81
|
+
selectedRouteId: selected.routeId,
|
|
82
|
+
selectedWorkspaceId: selected.workspaceId,
|
|
83
|
+
selectedWorkspaceRelativeHandoffPath: selected.workspaceRelativeHandoffPath,
|
|
84
|
+
routeOrdinal: siblingIndex,
|
|
85
|
+
qualifiedRouteCount: qualified.length,
|
|
86
|
+
pointerOrder: qualified.map((route, index) => Object.freeze({ ordinal: index + 1, pointerPath: route.pointerPath, routeId: route.routeId }))
|
|
87
|
+
},
|
|
88
|
+
boundary: allocationBoundary()
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
function blocked(reasonCode, extra = {}) {
|
|
92
|
+
return freeze({
|
|
93
|
+
state: 'blocked', siblingIndex: null, allocationMode: 'blocked', reasonCode, ...extra,
|
|
94
|
+
provenance: provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
|
|
95
|
+
boundary: allocationBoundary()
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function resolveHandoffSiblingAllocation(input = {}) {
|
|
101
|
+
const derived = deriveHandoffSiblingAllocation(input);
|
|
102
|
+
if (derived.state === 'qualified') return derived;
|
|
103
|
+
if (derived.state === 'blocked') throw new Error(`portable.cli.handoff-carrier.sibling-allocation.${derived.reasonCode}`);
|
|
104
|
+
const explicit = normalizeSiblingIndex(input.explicitSiblingIndex ?? input.siblingIndex);
|
|
105
|
+
if (!explicit) throw new Error('portable.cli.handoff-carrier.sibling-allocation.explicit-index-required-when-topology-unavailable');
|
|
106
|
+
const legacy = await reserveHandoffSiblingIndex({
|
|
107
|
+
parentPackagePath: input.parentPackagePath,
|
|
108
|
+
parentPackageSha256: input.parentPackageSha256,
|
|
109
|
+
parentDimension: input.parentDimension,
|
|
110
|
+
enabled: input.enabled !== false,
|
|
111
|
+
siblingIndex: explicit
|
|
112
|
+
});
|
|
113
|
+
return freeze({
|
|
114
|
+
...legacy,
|
|
115
|
+
allocationMode: 'explicit-advanced-override',
|
|
116
|
+
explicitOverride: 'required-because-qualified-topology-unavailable',
|
|
117
|
+
provenance: {
|
|
118
|
+
...provenanceBase({ ...input, explicitSiblingIndex: explicit }),
|
|
119
|
+
basis: 'explicit-advanced-override-without-qualified-route-topology'
|
|
120
|
+
},
|
|
121
|
+
boundary: allocationBoundary()
|
|
122
|
+
});
|
|
123
|
+
}
|
|
5
124
|
|
|
6
125
|
export async function reserveHandoffSiblingIndex({ parentPackagePath = '', parentPackageSha256 = '', parentDimension = '', enabled = true, siblingIndex = null } = {}) {
|
|
7
126
|
const requestedSiblingIndex = normalizeSiblingIndex(siblingIndex);
|
|
@@ -35,21 +154,39 @@ export async function reserveHandoffSiblingIndex({ parentPackagePath = '', paren
|
|
|
35
154
|
}
|
|
36
155
|
}
|
|
37
156
|
|
|
157
|
+
function comparePointerOrder(left, right) {
|
|
158
|
+
const a = left.pointerSegments || [], b = right.pointerSegments || [];
|
|
159
|
+
for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
|
|
160
|
+
if (a[index] === undefined) return -1;
|
|
161
|
+
if (b[index] === undefined) return 1;
|
|
162
|
+
if (a[index] !== b[index]) return a[index] - b[index];
|
|
163
|
+
}
|
|
164
|
+
return left.pointerPath.localeCompare(right.pointerPath);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function provenanceBase({ parentPackagePath = '', parentPackageSha256 = '', parentDimension = '', explicitSiblingIndex = null } = {}) {
|
|
168
|
+
return {
|
|
169
|
+
parentPackagePath: String(parentPackagePath || ''),
|
|
170
|
+
parentPackageSha256: String(parentPackageSha256 || '').trim().toLowerCase(),
|
|
171
|
+
parentDimension: String(parentDimension || '').trim(),
|
|
172
|
+
explicitSiblingIndex: explicitSiblingIndex ? normalizeSiblingIndex(explicitSiblingIndex) : null
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
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.'; }
|
|
38
176
|
function normalizeSiblingIndex(value) {
|
|
39
177
|
if (value === null || value === undefined || value === '') return 0;
|
|
40
178
|
const parsed = Number(value);
|
|
41
179
|
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_SIBLING_INDEX) throw new Error('portable.cli.handoff-carrier.sibling-allocation.index-invalid');
|
|
42
180
|
return parsed;
|
|
43
181
|
}
|
|
44
|
-
|
|
45
182
|
async function readAllocation(allocationPath) {
|
|
46
183
|
try { return JSON.parse(await readFile(allocationPath, 'utf8')); }
|
|
47
184
|
catch { throw new Error('portable.cli.handoff-carrier.sibling-allocation.existing-reservation-invalid'); }
|
|
48
185
|
}
|
|
49
|
-
|
|
50
186
|
function sameAllocation(left = {}, right = {}) {
|
|
51
187
|
return String(left.parentPackageSha256 || '') === String(right.parentPackageSha256 || '')
|
|
52
188
|
&& String(left.parentDimension || '') === String(right.parentDimension || '')
|
|
53
189
|
&& Number(left.siblingIndex || 0) === Number(right.siblingIndex || 0)
|
|
54
190
|
&& String(left.childDimension || '') === String(right.childDimension || '');
|
|
55
191
|
}
|
|
192
|
+
function freeze(value) { if (Array.isArray(value)) return Object.freeze(value.map(freeze)); if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value; return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, freeze(item)]))); }
|
|
@@ -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.
|
|
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.',
|
|
87
87
|
'',
|
|
88
88
|
`Advanced/internal catalog: ${command} operations`
|
|
89
89
|
];
|
|
@@ -134,6 +134,9 @@ function cliColdStartQualificationSummary(result = {}, flags = {}) {
|
|
|
134
134
|
return Object.freeze({
|
|
135
135
|
requirementId: item.requirementId,
|
|
136
136
|
name: item.name,
|
|
137
|
+
material: item.material,
|
|
138
|
+
purpose: item.purpose,
|
|
139
|
+
declaredAvailability: item.declaredAvailability,
|
|
137
140
|
state: item.state,
|
|
138
141
|
referenceTarget: item.referenceTarget,
|
|
139
142
|
kind: item.kind,
|
|
@@ -147,6 +150,7 @@ function cliColdStartQualificationSummary(result = {}, flags = {}) {
|
|
|
147
150
|
actualBytes: item.actualBytes,
|
|
148
151
|
actualSha256: item.actualSha256,
|
|
149
152
|
contentState: item.contentState,
|
|
153
|
+
provenance: item.provenance,
|
|
150
154
|
contentProjected,
|
|
151
155
|
...(contentProjected ? { content: item.content } : {})
|
|
152
156
|
});
|
|
@@ -6,7 +6,7 @@ import { qualifyToolingRuntimeSourceAlignment } from './handoff.manufacture.runt
|
|
|
6
6
|
import { normalizeHandoffCarrierLineage } from '../../handoff/carrierLineage.js';
|
|
7
7
|
import { normalizeHandoffCarrierProfile } from '../../handoff/carrierProfile.js';
|
|
8
8
|
import { enumerateNodeWorkspace, PORTABLE_NODE_WORKSPACE_ENUMERATION_SCHEMA_ID } from './handoff.manufacture.enumeration.js';
|
|
9
|
-
import { preparePackageParentWorkspaceReuse } from './handoff.manufacture.packageParent.js';
|
|
9
|
+
import { preparePackageParentWorkspaceReuse, projectRequiredContextWorkspaceSelectionPreflight } from './handoff.manufacture.packageParent.js';
|
|
10
10
|
import { qualifyPortableSourceReconciliationProofForManufacture } from '../../comparison/sourceFrontierReconciliationProof.js';
|
|
11
11
|
import { qualifyPortableManufactureSchemaReferenceCandidate } from '../../handoff/schemaReferencePreflight.js';
|
|
12
12
|
import { qualifyDelegationReturnReservation } from '../../handoff/delegationReturnReservation.js';
|
|
@@ -46,14 +46,6 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
46
46
|
(value) => Object.freeze({ value, error: null }),
|
|
47
47
|
(error) => Object.freeze({ value: null, error })
|
|
48
48
|
);
|
|
49
|
-
const enumerationPromise = enumerateNodeWorkspace(workspaceRoot, {
|
|
50
|
-
workspaceId,
|
|
51
|
-
workspaceTitle: requestedWorkspaceTitle,
|
|
52
|
-
sourceMetadata: input.workspaceSource || input.sourceMetadata || {},
|
|
53
|
-
excludeDirectories: input.excludeDirectories || options.excludeDirectories,
|
|
54
|
-
excludeRelativePaths: input.excludeRelativePaths || options.excludeRelativePaths,
|
|
55
|
-
maxFiles: input.maxFiles || options.maxFiles
|
|
56
|
-
});
|
|
57
49
|
const additionalWorkspaceDescriptors = normalizeAdditionalWorkspaceDescriptors(input.additionalWorkspaces || input.workspaceRoots || input.workspaceDescriptors || []);
|
|
58
50
|
const seenWorkspaceIds = new Set([workspaceId]);
|
|
59
51
|
const additionalWorkspaceInputs = additionalWorkspaceDescriptors.map((descriptor) => {
|
|
@@ -77,6 +69,23 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
77
69
|
workspaceIds: input.packageParentWorkspaceIds || input.reusePackageParentWorkspaceIds || [],
|
|
78
70
|
workspaceAliases: input.packageParentWorkspaceAliases || input.workspaceAliases || {}
|
|
79
71
|
});
|
|
72
|
+
const handoffMarkdown = await handoffMarkdownPromise;
|
|
73
|
+
const requiredContextWorkspaceSelectionPreflight = projectRequiredContextWorkspaceSelectionPreflight({
|
|
74
|
+
handoffMarkdown,
|
|
75
|
+
currentWorkspaceIds: [...seenWorkspaceIds],
|
|
76
|
+
packageParentReuse
|
|
77
|
+
});
|
|
78
|
+
if (requiredContextWorkspaceSelectionPreflight.state === 'action-required') {
|
|
79
|
+
throw new Error(`portable.handoff-manufacture.required-context.workspace-selection.required: ${requiredContextWorkspaceSelectionPreflight.nextAction} Missing Workspace ids: ${requiredContextWorkspaceSelectionPreflight.missingWorkspaceIds.join(',')}. Tooling will not auto-select package-parent Workspace source from carrier lineage.`);
|
|
80
|
+
}
|
|
81
|
+
const enumerationPromise = enumerateNodeWorkspace(workspaceRoot, {
|
|
82
|
+
workspaceId,
|
|
83
|
+
workspaceTitle: requestedWorkspaceTitle,
|
|
84
|
+
sourceMetadata: input.workspaceSource || input.sourceMetadata || {},
|
|
85
|
+
excludeDirectories: input.excludeDirectories || options.excludeDirectories,
|
|
86
|
+
excludeRelativePaths: input.excludeRelativePaths || options.excludeRelativePaths,
|
|
87
|
+
maxFiles: input.maxFiles || options.maxFiles
|
|
88
|
+
});
|
|
80
89
|
const additionalEnumerationsPromise = Promise.all(additionalWorkspaceInputs.map(async ({ descriptor, id, root, requestedTitle }) => {
|
|
81
90
|
const enumerated = await enumerateNodeWorkspace(root, {
|
|
82
91
|
workspaceId: id,
|
|
@@ -90,8 +99,7 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
90
99
|
return Object.freeze({ descriptor, id, root, requestedTitle, enumerated });
|
|
91
100
|
}));
|
|
92
101
|
|
|
93
|
-
const [
|
|
94
|
-
handoffMarkdownPromise,
|
|
102
|
+
const [enumeration, additionalEnumerations] = await Promise.all([
|
|
95
103
|
enumerationPromise,
|
|
96
104
|
additionalEnumerationsPromise
|
|
97
105
|
]);
|
|
@@ -132,7 +140,8 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
132
140
|
}
|
|
133
141
|
const suppliedTransportRoutes = [...(input.transportRoutes || input.handoffRoutes || [])].map((route) => normalizeTransportRoute(route, workspaceId)).filter(Boolean);
|
|
134
142
|
const reservationProjection = returnCarrierReservationPreflight.state === 'qualified' && returnCarrierReservationPreflight.returnExpected
|
|
135
|
-
|
|
143
|
+
&& (returnCarrierReservationPreflight.carrierKind === 'major' || Number.isInteger(returnCarrierReservationPreflight.siblingIndex))
|
|
144
|
+
? Object.freeze({ carrierKind: returnCarrierReservationPreflight.carrierKind, ...(Number.isInteger(returnCarrierReservationPreflight.siblingIndex) ? { siblingIndex: returnCarrierReservationPreflight.siblingIndex } : {}) })
|
|
136
145
|
: null;
|
|
137
146
|
const transportRoutes = Object.freeze((suppliedTransportRoutes.length ? suppliedTransportRoutes : [Object.freeze({ workspaceId, path: handoffPath })]).map((route) => Object.freeze({ ...route, ...(route.path === handoffPath && String(route.workspaceId || '') === workspaceId && reservationProjection ? { returnCarrierReservation: reservationProjection } : {}) })));
|
|
138
147
|
const workspaceTargets = mergeWorkspaceTargetBindings(normalizeWorkspaceTargetBindings({
|
|
@@ -197,6 +206,7 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
197
206
|
transportRoutes,
|
|
198
207
|
workspaceTargets,
|
|
199
208
|
carrierLineage: normalizeHandoffCarrierLineage(input.carrierLineage || null),
|
|
209
|
+
carrierAllocation: input.carrierAllocation ? Object.freeze({ ...input.carrierAllocation }) : null,
|
|
200
210
|
carrierProfile: normalizeHandoffCarrierProfile(input.carrierProfile || null),
|
|
201
211
|
toolingBootstrap: toolingBootstrap.summary,
|
|
202
212
|
reconciliationProofQualification,
|
|
@@ -210,6 +220,7 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
210
220
|
reconciliationProof: reconciliationProofQualification,
|
|
211
221
|
schemaReferencePreflight,
|
|
212
222
|
returnCarrierReservationPreflight,
|
|
223
|
+
carrierAllocation: input.carrierAllocation ? Object.freeze({ ...input.carrierAllocation }) : null,
|
|
213
224
|
packageParentWorkspaceReuse: Object.freeze({
|
|
214
225
|
state: String(packageParentReuse.state || ''),
|
|
215
226
|
providerState: String(packageParentReuse.providerState || ''),
|
|
@@ -217,10 +228,12 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
|
|
|
217
228
|
selectionMode: String(packageParentReuse.selectionMode || ''),
|
|
218
229
|
requestedWorkspaceIds: Object.freeze([...(packageParentReuse.requestedWorkspaceIds || [])].map(String)),
|
|
219
230
|
providerWorkspaceIds: Object.freeze([...(packageParentReuse.providerWorkspaceIds || [])].map(String)),
|
|
231
|
+
providerWorkspaceTargets: Object.freeze([...(packageParentReuse.providerWorkspaceTargets || [])].map((item) => Object.freeze({ ...item }))),
|
|
220
232
|
inheritedWorkspaceIds: Object.freeze((packageParentReuse.inherited || []).map((item) => String(item.id || ''))),
|
|
221
233
|
workspaceAliases: Object.freeze([...(packageParentReuse.workspaceAliases || [])].map((item) => Object.freeze({ ...item }))),
|
|
222
234
|
boundary: String(packageParentReuse.boundary || '')
|
|
223
235
|
}),
|
|
236
|
+
requiredContextWorkspaceSelectionPreflight,
|
|
224
237
|
carrierProjection: Object.freeze({ requestedRoutes: transportRoutes.length || 1, carrierLineage: normalizeHandoffCarrierLineage(input.carrierLineage || null), carrierProfile: normalizeHandoffCarrierProfile(input.carrierProfile || null), boundary: 'Routes are qualified later against packaged workspace bytes; adapter text is not authority.' })
|
|
225
238
|
}),
|
|
226
239
|
verifyRoundtrip: input.verifyRoundtrip !== false
|