@tiinex/core 0.19.0 → 0.20.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 -6
- package/src/schemas/creation.contracts.js +1 -1
- package/src/schemas/party/role/tiinex.party.role.v1.schema.js +5 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.json +2 -2
- package/src/schemas/party/role/tiinex.party.role.v1.schema.md +313 -0
- package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +18 -6
- package/src/schemas/party/role/tiinex.party.role.v1.validate.js +36 -0
- package/src/schemas/schema.reference.js +29 -0
- package/src/tooling/portable/adapters/cli/cli.common-author.js +117 -6
- package/src/tooling/portable/adapters/cli/cli.common-output.js +19 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.js +26 -4
- package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +123 -0
- package/src/tooling/portable/audit/audit.capability.js +10 -4
- package/src/tooling/portable/grounding/grounding.capsule.js +26 -2
- package/src/tooling/portable/grounding/grounding.delegationArtifactAuthority.js +220 -0
- package/src/tooling/portable/grounding/grounding.delegationReadiness.js +241 -0
- package/src/tooling/portable/grounding/grounding.holderAssignmentModes.js +125 -0
- package/src/tooling/portable/grounding/grounding.holderBindingAuthorization.js +49 -50
- package/src/tooling/portable/grounding/grounding.readiness.js +19 -3
- package/src/tooling/portable/grounding/grounding.readiness.support.js +1 -1
- package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +20 -4
- package/src/tooling/portable/handoff/coldStartQualification.grounding.js +55 -3
- package/src/tooling/portable/handoff/coldStartQualification.materials.js +84 -10
- package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +1 -1
- package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +5 -2
- package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +2 -2
- package/src/tooling/portable/handoff/recipientV2.topology.js +5 -3
- package/src/tooling/portable/handoff/recipientV2.topology.materials.js +0 -0
|
@@ -1,81 +1,80 @@
|
|
|
1
|
-
import { deepFreeze,
|
|
1
|
+
import { deepFreeze, normalizeToken } from '../handoff/coldStartQualification.shared.js';
|
|
2
|
+
import {
|
|
3
|
+
HOLDER_ASSIGNMENT_MODE,
|
|
4
|
+
isCanonicalHolderAssignmentMode,
|
|
5
|
+
projectHolderAssignmentModeAuthority
|
|
6
|
+
} from './grounding.holderAssignmentModes.js';
|
|
2
7
|
|
|
3
|
-
export
|
|
4
|
-
export const CURRENT_ROLE_EXPLICIT_SESSION_OR_HANDOFF_HOLDER_STATE = 'assignable per explicit session, role invocation, or Handoff; no permanent holder asserted';
|
|
5
|
-
export const ANCHOR_EXPLICIT_SESSION_OR_HANDOFF_HOLDER_STATE = 'assignable per explicit session or Handoff; no permanent holder asserted';
|
|
6
|
-
|
|
7
|
-
const AUTHORIZED_EXPLICIT_SESSION_OR_HANDOFF_STATES = new Set([
|
|
8
|
-
normalizeComparable(EXPLICIT_SESSION_OR_HANDOFF_HOLDER_STATE),
|
|
9
|
-
normalizeComparable(CURRENT_ROLE_EXPLICIT_SESSION_OR_HANDOFF_HOLDER_STATE),
|
|
10
|
-
normalizeComparable(ANCHOR_EXPLICIT_SESSION_OR_HANDOFF_HOLDER_STATE)
|
|
11
|
-
]);
|
|
12
|
-
|
|
13
|
-
export function projectHolderBindingAuthorization(role = {}) {
|
|
8
|
+
export function projectHolderBindingAuthorization(role = {}, options = {}) {
|
|
14
9
|
const endpointKind = normalizeToken(role?.endpoint?.kind || '');
|
|
10
|
+
const requestedMode = String(options.assertionMode || options.assignmentMode || HOLDER_ASSIGNMENT_MODE.EXPLICIT_SESSION).trim();
|
|
15
11
|
if (endpointKind !== 'role') return deepFreeze({
|
|
16
12
|
state: 'not-applicable',
|
|
17
13
|
assignmentMode: '',
|
|
14
|
+
authorizedModes: deepFreeze([]),
|
|
18
15
|
holderState: '',
|
|
19
16
|
source: 'none',
|
|
20
17
|
reasonCode: 'recipient-not-role',
|
|
18
|
+
modeAuthority: projectHolderAssignmentModeAuthority(role),
|
|
21
19
|
provenance: {
|
|
22
|
-
basis: 'recipient-not-role',
|
|
23
|
-
roleArtifactPath: '',
|
|
24
|
-
roleArtifactSha256: '',
|
|
25
|
-
section: 'Holder Relationship',
|
|
26
|
-
field: 'Holder State',
|
|
27
|
-
boundary: 'Holder-assignment authorization is only applicable when the selected Handoff recipient is a Role endpoint.'
|
|
20
|
+
basis: 'recipient-not-role', roleArtifactPath: '', roleArtifactSha256: '', section: 'Holder Relationship', field: 'Assignment Modes', exactValue: '', assertionMode: '', boundary: 'Holder-assignment authorization is only applicable when the selected Handoff recipient is a Role endpoint.'
|
|
28
21
|
},
|
|
29
22
|
boundary: 'No Role assignment authorization is required for a non-Role recipient.'
|
|
30
23
|
});
|
|
31
24
|
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const provenance = {
|
|
40
|
-
basis: qualifiedMaterial ? 'exact-qualified-role-holder-relationship' : 'exact-qualified-role-holder-relationship-not-established',
|
|
41
|
-
roleArtifactPath: String(material?.path || ''),
|
|
42
|
-
roleArtifactSha256: String(material?.sha256 || ''),
|
|
43
|
-
roleSchemaId: String(material?.schemaId || ''),
|
|
44
|
-
roleLabel: String(material?.roleLabel || role?.endpoint?.label || ''),
|
|
45
|
-
section: 'Holder Relationship',
|
|
46
|
-
field: 'Holder State',
|
|
47
|
-
exactValue: holderState,
|
|
48
|
-
boundary: 'Only exact qualified recipient Role material may authorize the bounded session assignment mode. Handoff endpoints, transport identity, explicit session input, filenames, and package placement do not provide this authority.'
|
|
49
|
-
};
|
|
25
|
+
const modeAuthority = projectHolderAssignmentModeAuthority(role);
|
|
26
|
+
const holderState = String(modeAuthority.holderState || role?.holderRelationshipLoaded?.holderState || '').trim();
|
|
27
|
+
const provenance = deepFreeze({
|
|
28
|
+
...(modeAuthority.provenance || {}),
|
|
29
|
+
assertionMode: requestedMode,
|
|
30
|
+
boundary: 'The bounded binding result compares one explicit assertion mechanism to exact qualified canonical assignment-mode authority. Holder State prose remains diagnostic-only.'
|
|
31
|
+
});
|
|
50
32
|
|
|
51
|
-
if (
|
|
33
|
+
if (modeAuthority.state !== 'qualified') return deepFreeze({
|
|
52
34
|
state: 'unresolved',
|
|
53
|
-
assignmentMode:
|
|
35
|
+
assignmentMode: requestedMode,
|
|
36
|
+
authorizedModes: deepFreeze([]),
|
|
54
37
|
holderState,
|
|
55
|
-
source: 'none',
|
|
56
|
-
reasonCode: '
|
|
38
|
+
source: modeAuthority.source || 'none',
|
|
39
|
+
reasonCode: modeAuthority.reasonCode || 'holder-assignment-mode-authority-unresolved',
|
|
40
|
+
modeAuthority,
|
|
57
41
|
provenance,
|
|
58
|
-
boundary: 'A matching
|
|
42
|
+
boundary: 'A matching Role assertion remains unauthorized until exact qualified canonical assignment-mode authority is established.'
|
|
59
43
|
});
|
|
60
44
|
|
|
61
|
-
|
|
62
|
-
if (!assignmentAuthorized) return deepFreeze({
|
|
45
|
+
if (!isCanonicalHolderAssignmentMode(requestedMode)) return deepFreeze({
|
|
63
46
|
state: 'unresolved',
|
|
64
|
-
assignmentMode:
|
|
47
|
+
assignmentMode: requestedMode,
|
|
48
|
+
authorizedModes: deepFreeze([...(modeAuthority.modes || [])]),
|
|
49
|
+
holderState,
|
|
50
|
+
source: modeAuthority.source,
|
|
51
|
+
reasonCode: 'holder-binding-assertion-mode-unqualified',
|
|
52
|
+
modeAuthority,
|
|
53
|
+
provenance,
|
|
54
|
+
boundary: 'The asserted binding mechanism is not a canonical mode established by semantic authority. Core does not reinterpret arbitrary assertion labels.'
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!(modeAuthority.modes || []).includes(requestedMode)) return deepFreeze({
|
|
58
|
+
state: 'unresolved',
|
|
59
|
+
assignmentMode: requestedMode,
|
|
60
|
+
authorizedModes: deepFreeze([...(modeAuthority.modes || [])]),
|
|
65
61
|
holderState,
|
|
66
|
-
source:
|
|
67
|
-
reasonCode:
|
|
62
|
+
source: modeAuthority.source,
|
|
63
|
+
reasonCode: 'holder-assignment-mode-not-authorized',
|
|
64
|
+
modeAuthority,
|
|
68
65
|
provenance,
|
|
69
|
-
boundary: 'The exact qualified
|
|
66
|
+
boundary: 'The exact qualified canonical mode set does not authorize the asserted bounded binding mechanism. No widening between session, user-session, invocation, Handoff, or participation modes is permitted.'
|
|
70
67
|
});
|
|
71
68
|
|
|
72
69
|
return deepFreeze({
|
|
73
70
|
state: 'qualified',
|
|
74
|
-
assignmentMode:
|
|
71
|
+
assignmentMode: requestedMode,
|
|
72
|
+
authorizedModes: deepFreeze([...(modeAuthority.modes || [])]),
|
|
75
73
|
holderState,
|
|
76
|
-
source:
|
|
74
|
+
source: modeAuthority.source,
|
|
77
75
|
reasonCode: 'holder-assignment-mode-authorized',
|
|
76
|
+
modeAuthority,
|
|
78
77
|
provenance,
|
|
79
|
-
boundary: 'Exact qualified
|
|
78
|
+
boundary: 'Exact qualified canonical assignment-mode authority authorizes only this bounded assertion mechanism; it does not establish durable holder identity or broader participant/process/delegation/source/acceptance authority.'
|
|
80
79
|
});
|
|
81
80
|
}
|
|
@@ -41,6 +41,7 @@ export function projectPortableGroundingReadiness(input = {}, options = {}) {
|
|
|
41
41
|
route,
|
|
42
42
|
toolingAvailable: true
|
|
43
43
|
}, { ...options, coldStartMaterialContext: materialContext });
|
|
44
|
+
const authority = withExplicitGroundingAuthorityInputs(grounding, input);
|
|
44
45
|
const continuation = projectGroundedContinuation({
|
|
45
46
|
bundle,
|
|
46
47
|
route,
|
|
@@ -62,7 +63,7 @@ export function projectPortableGroundingReadiness(input = {}, options = {}) {
|
|
|
62
63
|
});
|
|
63
64
|
return composeGroundingReadiness({
|
|
64
65
|
mode: 'routed-handoff-package',
|
|
65
|
-
authority
|
|
66
|
+
authority,
|
|
66
67
|
continuation,
|
|
67
68
|
contextAudit,
|
|
68
69
|
material,
|
|
@@ -140,8 +141,8 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
|
|
|
140
141
|
known.push(evidence('session-holder-role-binding-authorization', 'qualified', authority?.holderBinding?.authorization?.provenance?.roleArtifactPath || authority?.role?.endpoint?.label || 'recipient Role material'));
|
|
141
142
|
} else {
|
|
142
143
|
holderBindingActReady = false;
|
|
143
|
-
unresolved.push(evidence('session-holder-role-binding-authorization', holderAuthorizationState || 'unresolved', authority?.holderBinding?.authorization?.
|
|
144
|
-
reasons.push(reason('session-holder-role-binding-authorization-unresolved', 'The explicit consuming-session Role assertion matches the selected recipient Role, but exact qualified
|
|
144
|
+
unresolved.push(evidence('session-holder-role-binding-authorization', holderAuthorizationState || 'unresolved', authority?.holderBinding?.authorization?.reasonCode || 'exact qualified canonical assignment-mode authority does not authorize the asserted binding mechanism'));
|
|
145
|
+
reasons.push(reason('session-holder-role-binding-authorization-unresolved', 'The explicit consuming-session Role assertion matches the selected recipient Role, but exact qualified canonical assignment-mode authority does not authorize the asserted mechanism. Matching session input alone cannot make the route act-ready.'));
|
|
145
146
|
}
|
|
146
147
|
}
|
|
147
148
|
|
|
@@ -254,6 +255,7 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
|
|
|
254
255
|
}),
|
|
255
256
|
continuity,
|
|
256
257
|
orchestrationReadiness,
|
|
258
|
+
delegationReadiness: capsule.delegationReadiness,
|
|
257
259
|
capsule,
|
|
258
260
|
currentWork: Object.freeze({
|
|
259
261
|
state: topology.currentFrontier.length ? 'current-frontier-resolved' : topology.currentTasks.length ? 'current-candidates-without-frontier' : 'unresolved',
|
|
@@ -288,6 +290,20 @@ export function composeGroundingReadiness({ mode = 'loaded-material', authority
|
|
|
288
290
|
});
|
|
289
291
|
}
|
|
290
292
|
|
|
293
|
+
|
|
294
|
+
function withExplicitGroundingAuthorityInputs(grounding = {}, input = {}) {
|
|
295
|
+
const context = input.delegationContext && typeof input.delegationContext === 'object' ? input.delegationContext : {};
|
|
296
|
+
const selected = {
|
|
297
|
+
delegateCapabilityAuthority: input.delegateCapabilityAuthority || context.delegateCapabilityAuthority || null,
|
|
298
|
+
processApplicability: input.processApplicability || context.processApplicability || null,
|
|
299
|
+
delegationTargetAuthority: input.delegationTargetAuthority || context.delegationTargetAuthority || context.targetAuthority || null,
|
|
300
|
+
implementationSourceAuthority: input.implementationSourceAuthority || context.implementationSourceAuthority || context.sourceAuthority || null,
|
|
301
|
+
delegationReturnReconciliationExpectation: input.delegationReturnReconciliationExpectation || context.delegationReturnReconciliationExpectation || context.returnReconciliationExpectation || null
|
|
302
|
+
};
|
|
303
|
+
const additions = Object.fromEntries(Object.entries(selected).filter(([, value]) => value && typeof value === 'object'));
|
|
304
|
+
return Object.freeze({ ...(grounding || {}), ...additions, ...(Object.keys(context).length ? { delegationContext: Object.freeze({ ...context }) } : {}) });
|
|
305
|
+
}
|
|
306
|
+
|
|
291
307
|
function projectWorkspaceActionCoverage(contextAudit = {}) {
|
|
292
308
|
const workspaces = Array.isArray(contextAudit?.workspaceMaterializations) ? contextAudit.workspaceMaterializations : [];
|
|
293
309
|
const summaries = workspaces.map((workspace) => {
|
|
@@ -174,7 +174,7 @@ export function resolveRequiredContextRecords(requiredContext = [], records = []
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
function isExactHydratedWorkspaceContext(entry = {}) {
|
|
177
|
-
if (String(entry.providerMode || '')
|
|
177
|
+
if (!['archive', 'cache'].includes(String(entry.providerMode || ''))) return false;
|
|
178
178
|
if (!['hydrated-text', 'qualified-locator-only'].includes(String(entry.contentState || ''))) return false;
|
|
179
179
|
const expectedBytes = Number(entry.bytes || 0);
|
|
180
180
|
const actualBytes = Number(entry.actualBytes || 0);
|
|
@@ -71,8 +71,22 @@ function qualifyRequiredRequirement(bundle, descriptor, byteProvider, workspace,
|
|
|
71
71
|
let resolution=null;
|
|
72
72
|
if (!target||target.startsWith('#')) { resolution=resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath); if(!resolution) reasons.push('exact-required-material-reference-or-binding-unresolved'); }
|
|
73
73
|
const qualified=parseWorkspaceQualifiedReference(target);
|
|
74
|
-
if (!resolution&&!reasons.length&&qualified)
|
|
75
|
-
|
|
74
|
+
if (!resolution&&!reasons.length&&qualified) {
|
|
75
|
+
const workspaceResolution=resolveWorkspaceRequiredMaterial(byteProvider,{id:qualified.workspaceId},qualified.path);
|
|
76
|
+
resolution=workspaceResolution.state==='qualified'
|
|
77
|
+
? workspaceResolution
|
|
78
|
+
: (resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath)||workspaceResolution);
|
|
79
|
+
}
|
|
80
|
+
if (!resolution&&!reasons.length&&!qualified&&!isExternalReference(target)) {
|
|
81
|
+
const resolvedPath=resolveWorkspaceReference(routePath,target);
|
|
82
|
+
if(!resolvedPath) reasons.push('workspace-reference-outside-or-invalid');
|
|
83
|
+
else {
|
|
84
|
+
const workspaceResolution=resolveWorkspaceRequiredMaterial(byteProvider,workspace,resolvedPath);
|
|
85
|
+
resolution=workspaceResolution.state==='qualified'
|
|
86
|
+
? workspaceResolution
|
|
87
|
+
: (resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath)||workspaceResolution);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
76
90
|
if (!resolution&&!reasons.length) resolution=resolveDescriptorMaterial(bundle,descriptor,byteProvider,target,requirementId,workspace.id,routePath);
|
|
77
91
|
if (!resolution&&!reasons.length) reasons.push('required-material-not-carried');
|
|
78
92
|
if (resolution?.state!=='qualified'&&resolution?.reason) reasons.push(resolution.reason);
|
|
@@ -190,8 +204,10 @@ function resolveRouteParent(bundle, descriptor, byteProvider, workspace, routePa
|
|
|
190
204
|
if (!markdown) continue;
|
|
191
205
|
const self = validatedC14nV2PrimarySelfDigest(markdown);
|
|
192
206
|
if (self.state !== 'verified' || self.value !== digest) continue;
|
|
193
|
-
const
|
|
194
|
-
|
|
207
|
+
const candidatePath = normalizeWorkspacePath(candidate.workspaceRelativePath || '');
|
|
208
|
+
const candidateSha256 = sha256Hex(data);
|
|
209
|
+
const key = `${candidate.workspaceId || ''}\u0000${candidatePath}\u0000${candidateSha256}`;
|
|
210
|
+
if (!digestMatches.has(key)) digestMatches.set(key, Object.freeze({ state: 'qualified', markdown, basis: 'parent-target-digest-candidate', workspaceRelativePath: candidatePath, packagePath: String(candidate.packagePath || ''), sha256: candidateSha256 }));
|
|
195
211
|
}
|
|
196
212
|
if (digestMatches.size === 1) return [...digestMatches.values()][0];
|
|
197
213
|
if (digestMatches.size > 1) return Object.freeze({ state: 'ambiguous', reason: 'multiple-parent-target-digest-candidates' });
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
resolveGroundingRouteMarkdown,
|
|
20
20
|
recipientFactsIndexForColdStart,
|
|
21
21
|
resolveReferencedRoleMaterial,
|
|
22
|
+
resolveReferencedEndpointRoleMaterial,
|
|
22
23
|
selectGroundingRoute
|
|
23
24
|
} from './coldStartQualification.materials.js';
|
|
24
25
|
import {
|
|
@@ -60,6 +61,7 @@ export function groundPortableColdConsumer(input = {}, options = {}) {
|
|
|
60
61
|
|
|
61
62
|
const bundle = input.bundle || input.package || input;
|
|
62
63
|
const role = groundRecipientRole(input, handoff, bundle, orientation, selectedRoute, findings, materialContext);
|
|
64
|
+
const senderRole = groundSenderRole(handoff, bundle, orientation, selectedRoute, materialContext);
|
|
63
65
|
const holderBinding = groundHolderBinding(input, handoff, role, findings);
|
|
64
66
|
const participation = groundParticipation(input, handoff, bundle, orientation, selectedRoute, findings, materialContext);
|
|
65
67
|
const interaction = groundInteraction(input, handoff);
|
|
@@ -84,6 +86,7 @@ export function groundPortableColdConsumer(input = {}, options = {}) {
|
|
|
84
86
|
selectedRoute,
|
|
85
87
|
handoff,
|
|
86
88
|
role,
|
|
89
|
+
senderRole,
|
|
87
90
|
holderBinding,
|
|
88
91
|
participation,
|
|
89
92
|
interaction,
|
|
@@ -120,6 +123,50 @@ export function groundPortableColdConsumer(input = {}, options = {}) {
|
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
function groundSenderRole(handoff, bundle, orientation, selectedRoute, materialContext) {
|
|
127
|
+
const fromKind = normalizeToken(handoff.fromKind);
|
|
128
|
+
if (fromKind && fromKind !== 'role') return deepFreeze({
|
|
129
|
+
state: 'not-applicable',
|
|
130
|
+
endpoint: Object.freeze({ label: handoff.from || '', kind: handoff.fromKind || '', bounded: Boolean(handoff.from) }),
|
|
131
|
+
material: Object.freeze({ state: 'not-required', artifact: null }),
|
|
132
|
+
exactBoundaryLoaded: null,
|
|
133
|
+
authorityBoundaryLoaded: null,
|
|
134
|
+
boundary: 'Sender endpoint is not declared as Role; no sender Role authority is invented.'
|
|
135
|
+
});
|
|
136
|
+
if (!handoff.fromReference) return deepFreeze({
|
|
137
|
+
state: 'unresolved',
|
|
138
|
+
endpoint: Object.freeze({ label: handoff.from || '', kind: handoff.fromKind || (handoff.from ? 'role' : ''), bounded: Boolean(handoff.from) }),
|
|
139
|
+
material: Object.freeze({ state: 'missing-exact-reference', artifact: null }),
|
|
140
|
+
exactBoundaryLoaded: null,
|
|
141
|
+
authorityBoundaryLoaded: null,
|
|
142
|
+
boundary: 'Delegation projection requires an exact Handoff From Reference; Role inventory and endpoint labels are not substituted.'
|
|
143
|
+
});
|
|
144
|
+
const localFindings = [];
|
|
145
|
+
const material = resolveReferencedEndpointRoleMaterial(bundle, handoff, orientation, selectedRoute, localFindings, materialContext, 'from');
|
|
146
|
+
const parsed = material ? parseRoleMaterial(material) : null;
|
|
147
|
+
const target = normalizeComparable(handoff.from || '');
|
|
148
|
+
if (!parsed || (target && normalizeComparable(parsed.label) !== target)) return deepFreeze({
|
|
149
|
+
state: 'unresolved',
|
|
150
|
+
endpoint: Object.freeze({ label: handoff.from || '', kind: handoff.fromKind || (handoff.from ? 'role' : ''), bounded: Boolean(handoff.from) }),
|
|
151
|
+
material: Object.freeze({ state: localFindings.length ? 'unresolved-exact-reference' : 'missing', artifact: null }),
|
|
152
|
+
exactBoundaryLoaded: null,
|
|
153
|
+
authorityBoundaryLoaded: null,
|
|
154
|
+
boundary: 'Exact sender Role material did not qualify; sender authority is not inferred from carried Role inventory.'
|
|
155
|
+
});
|
|
156
|
+
return deepFreeze({
|
|
157
|
+
state: 'qualified',
|
|
158
|
+
endpoint: Object.freeze({ label: handoff.from || parsed.label || '', kind: handoff.fromKind || 'role', bounded: Boolean(handoff.from) }),
|
|
159
|
+
material: Object.freeze({
|
|
160
|
+
state: 'qualified',
|
|
161
|
+
artifact: Object.freeze({ path: parsed.path, sha256: parsed.sha256, schemaId: parsed.schemaId, title: parsed.title, roleLabel: parsed.label, roleKind: parsed.roleKind, reference: handoff.fromReference || '' })
|
|
162
|
+
}),
|
|
163
|
+
exactBoundaryLoaded: parsed.boundary,
|
|
164
|
+
authorityBoundaryLoaded: parsed.authorityBoundary,
|
|
165
|
+
interpretationLimitsLoaded: parsed.interpretationLimits,
|
|
166
|
+
boundary: 'Exact Handoff From Reference Role material only. Sender Role authority remains separate from Handoff transfer and is never inferred from endpoint naming or cache inventory.'
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
123
170
|
function groundRecipientRole(input, handoff, bundle, orientation, selectedRoute, findings, materialContext) {
|
|
124
171
|
const toKind = normalizeToken(handoff.toKind);
|
|
125
172
|
if (toKind && toKind !== 'role') return deepFreeze({
|
|
@@ -201,12 +248,14 @@ function groundHolderBinding(input, handoff, role, findings) {
|
|
|
201
248
|
const roleRecipient = recipientRoleKind === 'role';
|
|
202
249
|
const explicitlySupplied = Boolean(roleLabel || holderId);
|
|
203
250
|
const sourceDetail = holderBindingSourceDetail(input, explicit, explicitlySupplied);
|
|
204
|
-
const
|
|
251
|
+
const assertionMode = String(explicit.assignmentMode || explicit.bindingMode || explicit.mechanism || input.holderAssignmentMode || input.sessionAssignmentMode || 'explicit-session').trim();
|
|
252
|
+
const authorization = projectHolderBindingAuthorization(role, { assertionMode });
|
|
205
253
|
const durableIdentity = holderDurableIdentityProjection(holderId);
|
|
206
254
|
|
|
207
255
|
if (!roleRecipient) return deepFreeze({
|
|
208
256
|
state: 'not-applicable',
|
|
209
257
|
holderId,
|
|
258
|
+
assertionMode,
|
|
210
259
|
roleLabel,
|
|
211
260
|
recipientRoleLabel,
|
|
212
261
|
recipientCompatibility: 'not-applicable',
|
|
@@ -224,6 +273,7 @@ function groundHolderBinding(input, handoff, role, findings) {
|
|
|
224
273
|
return deepFreeze({
|
|
225
274
|
state: 'unresolved',
|
|
226
275
|
holderId,
|
|
276
|
+
assertionMode,
|
|
227
277
|
roleLabel: '',
|
|
228
278
|
recipientRoleLabel,
|
|
229
279
|
recipientCompatibility: 'unresolved',
|
|
@@ -242,6 +292,7 @@ function groundHolderBinding(input, handoff, role, findings) {
|
|
|
242
292
|
return deepFreeze({
|
|
243
293
|
state: 'blocked',
|
|
244
294
|
holderId,
|
|
295
|
+
assertionMode,
|
|
245
296
|
roleLabel,
|
|
246
297
|
recipientRoleLabel,
|
|
247
298
|
recipientCompatibility: 'mismatch',
|
|
@@ -258,6 +309,7 @@ function groundHolderBinding(input, handoff, role, findings) {
|
|
|
258
309
|
return deepFreeze({
|
|
259
310
|
state: 'qualified',
|
|
260
311
|
holderId,
|
|
312
|
+
assertionMode,
|
|
261
313
|
roleLabel,
|
|
262
314
|
recipientRoleLabel,
|
|
263
315
|
recipientCompatibility: 'matched',
|
|
@@ -310,7 +362,7 @@ function holderBindingSourceDetail(input = {}, explicit = {}, explicitlySupplied
|
|
|
310
362
|
|
|
311
363
|
function groundParticipation(input, handoff, bundle, orientation, selectedRoute, findings, materialContext) {
|
|
312
364
|
const explicitParticipants = normalizeParticipants(input.participants || input.interaction?.participants || []);
|
|
313
|
-
const packageRoleGrounding = resolvePackageParticipantRoles(bundle, orientation, selectedRoute, findings);
|
|
365
|
+
const packageRoleGrounding = resolvePackageParticipantRoles(bundle, orientation, selectedRoute, findings, materialContext);
|
|
314
366
|
const participants = dedupeGroundedParticipants(explicitParticipants);
|
|
315
367
|
const contributions = normalizeContributions(input.contributions || input.interaction?.contributions || []);
|
|
316
368
|
const currentContributionId = String(input.currentContributionId || input.interaction?.currentContributionId || '').trim();
|
|
@@ -345,7 +397,7 @@ function resolvePackageParticipantRoles(bundle = {}, orientation = null, selecte
|
|
|
345
397
|
const pointerPath = String(pointerPaths[index] || '');
|
|
346
398
|
const pointerFile = findFile(bundle, pointerPath);
|
|
347
399
|
if (!pointerFile) { findings.push(portableFinding('error', 'portable.cold-start.participant-role.pointer.missing', 'Selected Handoff route declares Role grounding Pointer ancestry that is not carried.', { pointerPath })); continue; }
|
|
348
|
-
const compatibilityFacts =
|
|
400
|
+
const compatibilityFacts = recipientFactsIndexForColdStart(bundle, materialContext).map.get(pointerPath) || null;
|
|
349
401
|
const projectedFacts = (orientation?.participantRoles || []).find((item) => String(item.pointerPath || '') === pointerPath) || null;
|
|
350
402
|
const facts = compatibilityFacts?.role === 'participant-role'
|
|
351
403
|
? compatibilityFacts
|
|
@@ -3,6 +3,7 @@ import { packageFileBytes, sha256Hex } from '../../../export/package.bytes.js';
|
|
|
3
3
|
import { portableFinding } from '../findings.js';
|
|
4
4
|
import { inspectStoredWorkspaceArchive } from './workspaceByteProvider.js';
|
|
5
5
|
import { recipientV2FactsIndex } from './recipientV2.transportManifest.js';
|
|
6
|
+
import { deriveRecipientV2ArtifactFirstPhase1Facts } from './recipientV2.artifactFirst.materials.js';
|
|
6
7
|
import { parseNamedDeclarationSection } from '../schema/named.declarations.js';
|
|
7
8
|
import { resolveColdStartRolePointerMaterial } from './coldStartRolePointers.js';
|
|
8
9
|
import {
|
|
@@ -58,7 +59,12 @@ export function collectPackageRoleMaterials(bundle = {}) {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export function resolveReferencedRoleMaterial(bundle = {}, handoff = {}, orientation = null, selectedRoute = null, findings = [], context = null) {
|
|
61
|
-
|
|
62
|
+
return resolveReferencedEndpointRoleMaterial(bundle, handoff, orientation, selectedRoute, findings, context, 'to');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function resolveReferencedEndpointRoleMaterial(bundle = {}, handoff = {}, orientation = null, selectedRoute = null, findings = [], context = null, endpointParty = 'to') {
|
|
66
|
+
const party = String(endpointParty || 'to').trim().toLowerCase() === 'from' ? 'from' : 'to';
|
|
67
|
+
const reference = String(party === 'from' ? handoff.fromReference : handoff.toReference || '').trim();
|
|
62
68
|
if (!reference) return null;
|
|
63
69
|
if (!isExternalReference(reference)) {
|
|
64
70
|
const workspaceZip = findFile(bundle, String(handoff.packagePath || ''));
|
|
@@ -71,7 +77,7 @@ export function resolveReferencedRoleMaterial(bundle = {}, handoff = {}, orienta
|
|
|
71
77
|
const markdown = decodeUtf8(matches[0].data || new Uint8Array());
|
|
72
78
|
if (markdown) return Object.freeze({ path: `${workspaceZip.path}::${resolvedPath}`, markdown, explicit: false, exactReference: reference });
|
|
73
79
|
}
|
|
74
|
-
if (matches.length > 1) findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff
|
|
80
|
+
if (matches.length > 1) findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff endpoint Reference resolves to multiple entries in the selected Workspace archive.', { reference, resolvedPath }));
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
}
|
|
@@ -85,14 +91,14 @@ export function resolveReferencedRoleMaterial(bundle = {}, handoff = {}, orienta
|
|
|
85
91
|
: projectedFacts
|
|
86
92
|
? { role: 'endpoint-role', ...projectedFacts }
|
|
87
93
|
: {};
|
|
88
|
-
if (facts.role !== 'endpoint-role' || String(facts.endpointParty || '').toLowerCase() !==
|
|
94
|
+
if (facts.role !== 'endpoint-role' || String(facts.endpointParty || '').toLowerCase() !== party) continue;
|
|
89
95
|
if (facts.referenceTarget && String(facts.referenceTarget) !== reference) continue;
|
|
90
96
|
const material = resolveColdStartRolePointerMaterial(bundle, facts, findings, String(pointerPath || ''), 'endpoint-role');
|
|
91
97
|
if (material) endpointPointerMatches.push(Object.freeze({ ...material, exactReference: reference }));
|
|
92
98
|
}
|
|
93
99
|
if (endpointPointerMatches.length === 1) return endpointPointerMatches[0];
|
|
94
100
|
if (endpointPointerMatches.length > 1) {
|
|
95
|
-
findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff
|
|
101
|
+
findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff endpoint Reference resolves through multiple qualified endpoint Role Pointers.', { reference, count: endpointPointerMatches.length }));
|
|
96
102
|
return null;
|
|
97
103
|
}
|
|
98
104
|
const cacheMatches = [];
|
|
@@ -114,7 +120,7 @@ export function resolveReferencedRoleMaterial(bundle = {}, handoff = {}, orienta
|
|
|
114
120
|
}
|
|
115
121
|
}
|
|
116
122
|
if (cacheMatches.length === 1) return cacheMatches[0];
|
|
117
|
-
if (cacheMatches.length > 1) findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff
|
|
123
|
+
if (cacheMatches.length > 1) findings.push(portableFinding('error', 'portable.cold-start.role.reference-material.ambiguous', 'Handoff endpoint Reference resolves to multiple cached exact byte carriers.', { reference, count: cacheMatches.length }));
|
|
118
124
|
return null;
|
|
119
125
|
}
|
|
120
126
|
|
|
@@ -172,9 +178,16 @@ export function parseRoleMaterial(entry) {
|
|
|
172
178
|
label,
|
|
173
179
|
roleKind: sectionField(roleSection, 'Role Kind'),
|
|
174
180
|
boundary: Object.freeze({ inScope: sectionField(boundarySection, 'In Scope'), outOfScope: sectionField(boundarySection, 'Out Of Scope'), context: sectionField(boundarySection, 'Context') }),
|
|
175
|
-
authorityBoundary: Object.freeze({
|
|
181
|
+
authorityBoundary: Object.freeze({
|
|
182
|
+
mayDo: sectionField(authoritySection, 'May Do'),
|
|
183
|
+
doesNotAuthorize: sectionField(authoritySection, 'Does Not Authorize'),
|
|
184
|
+
requiredInstrument: sectionField(authoritySection, 'Required Instrument'),
|
|
185
|
+
delegation: sectionField(authoritySection, 'Delegation'),
|
|
186
|
+
reviewBoundary: sectionField(authoritySection, 'Review Boundary')
|
|
187
|
+
}),
|
|
176
188
|
holderRelationship: Object.freeze({
|
|
177
189
|
holderState: sectionField(holderSection, 'Holder State'),
|
|
190
|
+
assignmentModes: sectionField(holderSection, 'Assignment Modes'),
|
|
178
191
|
currentHolder: sectionField(holderSection, 'Current Holder'),
|
|
179
192
|
possibleHolder: sectionField(holderSection, 'Possible Holder'),
|
|
180
193
|
unknownHolder: sectionField(holderSection, 'Unknown Holder'),
|
|
@@ -262,7 +275,7 @@ function hydrateRequiredContextEntry(bundle = {}, entry = {}, context = null) {
|
|
|
262
275
|
})
|
|
263
276
|
};
|
|
264
277
|
if (base.state !== 'qualified') return Object.freeze({ ...base, contentState: 'unavailable', content: '' });
|
|
265
|
-
const hydrated = resolveQualifiedMaterialBytes(bundle, resolution, context);
|
|
278
|
+
const hydrated = resolveQualifiedMaterialBytes(bundle, resolution, context, base);
|
|
266
279
|
if (!hydrated.bytes) return Object.freeze({ ...base, state: 'unresolved', contentState: 'unavailable', content: '' });
|
|
267
280
|
const actualSha256 = sha256Hex(hydrated.bytes);
|
|
268
281
|
const identityQualified = (!base.bytes || hydrated.bytes.byteLength === base.bytes) && (!base.sha256 || actualSha256 === base.sha256);
|
|
@@ -270,14 +283,21 @@ function hydrateRequiredContextEntry(bundle = {}, entry = {}, context = null) {
|
|
|
270
283
|
return Object.freeze({
|
|
271
284
|
...base,
|
|
272
285
|
state: identityQualified ? 'qualified' : 'identity-mismatch',
|
|
286
|
+
workspaceId: String(hydrated.workspaceId || base.workspaceId || ''),
|
|
287
|
+
archivePackagePath: String(hydrated.archivePackagePath || base.archivePackagePath || ''),
|
|
288
|
+
innerPath: String(hydrated.innerPath || base.innerPath || ''),
|
|
289
|
+
packagePath: String(hydrated.packagePath || base.packagePath || ''),
|
|
290
|
+
providerMode: String(hydrated.providerMode || base.providerMode || ''),
|
|
291
|
+
kind: String(hydrated.kind || base.kind || ''),
|
|
273
292
|
actualBytes: hydrated.bytes.byteLength,
|
|
274
293
|
actualSha256,
|
|
294
|
+
provenance: Object.freeze({ ...(base.provenance || {}), providerMode: String(hydrated.providerMode || base.providerMode || ''), resolutionKind: String(hydrated.kind || base.kind || '') }),
|
|
275
295
|
contentState: text ? 'hydrated-text' : identityQualified ? 'qualified-locator-only' : 'unavailable',
|
|
276
296
|
content: text
|
|
277
297
|
});
|
|
278
298
|
}
|
|
279
299
|
|
|
280
|
-
function resolveQualifiedMaterialBytes(bundle = {}, resolution = {}, context = null) {
|
|
300
|
+
function resolveQualifiedMaterialBytes(bundle = {}, resolution = {}, context = null, requirement = {}) {
|
|
281
301
|
const kind = String(resolution.kind || '');
|
|
282
302
|
if (kind === 'workspace-archive-entry' || kind === 'workspace-cache-entry') {
|
|
283
303
|
const archivePath = String(resolution.archivePackagePath || resolution.packagePath || '');
|
|
@@ -293,17 +313,64 @@ function resolveQualifiedMaterialBytes(bundle = {}, resolution = {}, context = n
|
|
|
293
313
|
}
|
|
294
314
|
const packagePath = String(resolution.packagePath || '');
|
|
295
315
|
const file = packagePath ? findFile(bundle, packagePath) : null;
|
|
296
|
-
return Object.freeze({ bytes:
|
|
316
|
+
if (file) return Object.freeze({ bytes: packageFileBytes(file), packagePath });
|
|
317
|
+
if (kind === 'materialized-required-material') {
|
|
318
|
+
const requirementId = String(requirement.requirementId || '');
|
|
319
|
+
const referenceTarget = String(requirement.referenceTarget || '');
|
|
320
|
+
const matches = [];
|
|
321
|
+
const factsIndex = recipientFactsIndexForColdStart(bundle, context).map;
|
|
322
|
+
const visibleFactsIndex = deriveRecipientV2ArtifactFirstPhase1Facts(bundle.files || []);
|
|
323
|
+
for (const candidateFile of bundle.files || []) {
|
|
324
|
+
const candidatePath = String(candidateFile.path || '');
|
|
325
|
+
const facts = factsIndex.get(candidatePath) || visibleFactsIndex.get(candidatePath) || null;
|
|
326
|
+
if (facts?.role !== 'workspace-dependency-cache' && !/dependency cache/i.test(String(facts?.role || ''))) continue;
|
|
327
|
+
for (const material of facts.materials || []) {
|
|
328
|
+
if (requirementId && String(material.requirementId || '') !== requirementId) continue;
|
|
329
|
+
if (referenceTarget && String(material.referenceTarget || '') !== referenceTarget) continue;
|
|
330
|
+
const archivePath = String(facts.archivePath || '');
|
|
331
|
+
const archiveFile = findFile(bundle, archivePath);
|
|
332
|
+
if (!archiveFile) continue;
|
|
333
|
+
const archive = inspectWorkspaceArchiveForColdStart(archiveFile, context);
|
|
334
|
+
if (archive.state !== 'qualified') continue;
|
|
335
|
+
const entries = (archive.entries || []).filter((entry) => String(entry.path || '') === String(material.archiveEntry || ''));
|
|
336
|
+
if (entries.length !== 1) continue;
|
|
337
|
+
const entry = entries[0];
|
|
338
|
+
const data = packageFileBytes({ data: entry.data });
|
|
339
|
+
const actualSha = sha256Hex(data);
|
|
340
|
+
if (Number(material.bytes || 0) && Number(material.bytes || 0) !== data.byteLength) continue;
|
|
341
|
+
if (String(material.sha256 || '') && String(material.sha256 || '') !== actualSha) continue;
|
|
342
|
+
if (Number(resolution.bytes || 0) && Number(resolution.bytes || 0) !== data.byteLength) continue;
|
|
343
|
+
if (String(resolution.sha256 || '') && String(resolution.sha256 || '') !== actualSha) continue;
|
|
344
|
+
matches.push(Object.freeze({
|
|
345
|
+
bytes: data, providerMode: 'cache', kind: 'workspace-cache-entry',
|
|
346
|
+
workspaceId: String(material.targetWorkspaceId || material.sourceWorkspaceId || facts.workspaceId || ''),
|
|
347
|
+
innerPath: String(material.targetPath || material.originalPath || ''),
|
|
348
|
+
archivePackagePath: archivePath, packagePath: archivePath
|
|
349
|
+
}));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (matches.length === 1) return matches[0];
|
|
353
|
+
}
|
|
354
|
+
return Object.freeze({ bytes: null });
|
|
297
355
|
}
|
|
298
356
|
|
|
299
357
|
export function parseHandoffGrounding(markdown, route) {
|
|
300
358
|
const parties = sectionText(markdown, 'Handoff Parties');
|
|
301
359
|
const transferSection = parseNamedDeclarationSection(markdown, '## Transfers');
|
|
360
|
+
const retainedSection = parseNamedDeclarationSection(markdown, '## Retained Responsibilities');
|
|
302
361
|
const completion = sectionText(markdown, 'Completion Expectation');
|
|
303
362
|
const transfers = Object.freeze((transferSection.entries || []).filter((entry) => String(entry.name || '').trim().toLowerCase() !== 'none').map((entry) => Object.freeze({
|
|
304
363
|
id: String(entry.name || ''),
|
|
305
364
|
transferKind: String(entry.fields?.['Transfer Kind'] || ''),
|
|
306
365
|
description: String(entry.fields?.Description || ''),
|
|
366
|
+
controllingArtifact: String(entry.fields?.['Controlling Artifact'] || ''),
|
|
367
|
+
controllingArtifactTarget: markdownReferenceTarget(entry.fields?.['Controlling Artifact'] || ''),
|
|
368
|
+
boundary: String(entry.fields?.Boundary || '')
|
|
369
|
+
})));
|
|
370
|
+
const retainedResponsibilities = Object.freeze((retainedSection.entries || []).filter((entry) => String(entry.name || '').trim().toLowerCase() !== 'none').map((entry) => Object.freeze({
|
|
371
|
+
id: String(entry.name || ''),
|
|
372
|
+
retainedBy: String(entry.fields?.['Retained By'] || ''),
|
|
373
|
+
responsibility: String(entry.fields?.Responsibility || ''),
|
|
307
374
|
boundary: String(entry.fields?.Boundary || '')
|
|
308
375
|
})));
|
|
309
376
|
return deepFreeze({
|
|
@@ -316,6 +383,7 @@ export function parseHandoffGrounding(markdown, route) {
|
|
|
316
383
|
fromReference: sectionReferenceTarget(parties, 'From Reference'),
|
|
317
384
|
toReference: sectionReferenceTarget(parties, 'To Reference'),
|
|
318
385
|
transfers,
|
|
386
|
+
retainedResponsibilities,
|
|
319
387
|
completionExpectation: Object.freeze({
|
|
320
388
|
signalKind: sectionField(completion, 'Signal Kind'),
|
|
321
389
|
signalMeaning: sectionField(completion, 'Signal Meaning'),
|
|
@@ -330,8 +398,14 @@ export function parseHandoffGrounding(markdown, route) {
|
|
|
330
398
|
});
|
|
331
399
|
}
|
|
332
400
|
|
|
401
|
+
function markdownReferenceTarget(value = '') {
|
|
402
|
+
const text = String(value || '').trim();
|
|
403
|
+
const match = text.match(/\[[^\]]*\]\(([^)]+)\)/);
|
|
404
|
+
return match ? String(match[1] || '').trim() : '';
|
|
405
|
+
}
|
|
406
|
+
|
|
333
407
|
export function emptyHandoffGrounding() {
|
|
334
|
-
return deepFreeze({ schemaId: '', purpose: '', from: '', fromKind: '', fromReference: '', to: '', toKind: '', toReference: '', transfers: Object.freeze([]), completionExpectation: Object.freeze({ signalKind: '', signalMeaning: '', returnTo: '' }), routeId: '', workspaceId: '', workspaceRelativePath: '', packagePath: '', sha256: '', boundary: 'No Handoff material supplied.' });
|
|
408
|
+
return deepFreeze({ schemaId: '', purpose: '', from: '', fromKind: '', fromReference: '', to: '', toKind: '', toReference: '', transfers: Object.freeze([]), retainedResponsibilities: Object.freeze([]), completionExpectation: Object.freeze({ signalKind: '', signalMeaning: '', returnTo: '' }), routeId: '', workspaceId: '', workspaceRelativePath: '', packagePath: '', sha256: '', boundary: 'No Handoff material supplied.' });
|
|
335
409
|
}
|
|
336
410
|
|
|
337
411
|
export function resolveGroundingRouteMarkdown(bundle = {}, selectedRoute = {}, findings = [], context = null) {
|
|
@@ -136,7 +136,7 @@ export function buildParticipantRolePointerChain(input = {}) {
|
|
|
136
136
|
prose: 'This Pointer is recipient discovery/grounding only. It does not declare semantic participation, change Handoff From/To, prove a human holder, or create Role authority; participation meaning remains owned by authoritative Handoff/Relation/context authority.',
|
|
137
137
|
currentRead: [
|
|
138
138
|
{ label: 'Route Id', value: `\`${String(input.route?.id || '')}\`` },
|
|
139
|
-
{ label: '
|
|
139
|
+
{ label: 'Participant Requirement Id', value: `\`${String(requirement.id || '')}\`` },
|
|
140
140
|
...(roleFacts.roleLabelHint ? [{ label: 'Role Label Hint', value: roleFacts.roleLabelHint }] : []),
|
|
141
141
|
{ label: 'Role Reference', value: roleFacts.referenceTarget ? `\`${roleFacts.referenceTarget}\`` : 'exact carried target' },
|
|
142
142
|
{ label: 'Target Carrier Kind', value: target.carrierKind },
|
|
@@ -38,14 +38,17 @@ export function projectRecipientV2EndpointRoles(pointers = []) {
|
|
|
38
38
|
export function projectRecipientV2ParticipantRoles(pointers = []) {
|
|
39
39
|
return Object.freeze(pointers.map((item) => Object.freeze({
|
|
40
40
|
pointerPath: item.path,
|
|
41
|
-
routeId: String(item.facts?.routeId || qualified?.id || ''),
|
|
42
|
-
workspaceId: String(item.facts?.workspaceId || ''),
|
|
43
41
|
routeId: String(item.facts?.routeId || ''),
|
|
42
|
+
workspaceId: String(item.facts?.workspaceId || ''),
|
|
43
|
+
requirementId: String(item.facts?.participantRequirementId || ''),
|
|
44
44
|
roleLabelHint: String(item.facts?.roleLabelHint || ''),
|
|
45
45
|
referenceTarget: String(item.facts?.referenceTarget || ''),
|
|
46
46
|
targetCarrierKind: String(item.facts?.targetCarrierKind || ''),
|
|
47
47
|
targetWorkspaceId: String(item.facts?.targetWorkspaceId || ''),
|
|
48
|
+
archivePath: String(item.facts?.archivePath || ''),
|
|
48
49
|
targetInnerPath: String(item.facts?.targetInnerPath || item.facts?.targetArchiveEntry || ''),
|
|
50
|
+
targetArchiveEntry: String(item.facts?.targetArchiveEntry || ''),
|
|
51
|
+
targetBytes: Number(item.facts?.targetBytes || 0),
|
|
49
52
|
targetSha256: String(item.facts?.targetSha256 || '')
|
|
50
53
|
})));
|
|
51
54
|
}
|
|
@@ -9,7 +9,7 @@ import { RECIPIENT_V2_ROUTE_SELECTION_AUTHORITY, RECIPIENT_V2_SIBLING_ROUTE_INFE
|
|
|
9
9
|
import { recipientV2TransportFacts } from './recipientV2.transportManifest.js';
|
|
10
10
|
import { buildRecipientV2BootstrapCarrier, buildRecipientV2WorkspaceCarriers, recipientV2ParentAuthority } from './recipientV2.topology.workspaces.js';
|
|
11
11
|
import { buildEndpointRolePointerChain, buildParticipantRolePointerChain } from './recipientV2.endpointRolePointers.js';
|
|
12
|
-
import { bindingForWorkspace, boundedWorkspaceClaimsDetachedRecovery, detachedMaterial, duplicates, finding, roleMaterialTarget, routeClaimsDetachedMaterial, safeToken, uniqueFileIndex } from './recipientV2.topology.materials.js';
|
|
12
|
+
import { bindingForWorkspace, boundedWorkspaceClaimsDetachedRecovery, coalesceDetachedCacheMaterials, detachedMaterial, duplicates, finding, roleMaterialTarget, routeClaimsDetachedMaterial, safeToken, uniqueFileIndex } from './recipientV2.topology.materials.js';
|
|
13
13
|
import { RECIPIENT_V2_PACKAGE_V1_FORMAT_ID, RECIPIENT_V2_PACKAGE_V1_ROOT_PATH, RECIPIENT_V2_PACKAGE_V1_SCHEMA_ID, RECIPIENT_V2_PACKAGE_V1_SCHEMA_TARGET } from './recipientV2.packageV1.constants.js';
|
|
14
14
|
import { renderHandoffPackageV1 } from './recipientV2.packageV1.contract.js';
|
|
15
15
|
import { inspectRecipientFacingV2PackageV1 } from './recipientV2.packageV1.inspect.js';
|
|
@@ -136,7 +136,7 @@ function buildRecipientFacingV2PackageV1Prepared(input = {}, sealedByWorkspaceId
|
|
|
136
136
|
const workspace = workspaceById.get(plan.workspaceId);
|
|
137
137
|
if (!workspace) continue;
|
|
138
138
|
const binding = bindingForWorkspace(descriptor, workspace.workspaceId);
|
|
139
|
-
const materials = detached.filter((item) => (workspace.workspaceId === String(route.workspaceId || '') && routeClaimsDetachedMaterial(route, item)) || boundedWorkspaceClaimsDetachedRecovery(binding, item));
|
|
139
|
+
const materials = coalesceDetachedCacheMaterials(detached.filter((item) => (workspace.workspaceId === String(route.workspaceId || '') && routeClaimsDetachedMaterial(route, item)) || boundedWorkspaceClaimsDetachedRecovery(binding, item)));
|
|
140
140
|
if (!materials.length) continue;
|
|
141
141
|
const artifactPath = `${plan.prefix}-1-cache.trace.md`;
|
|
142
142
|
const archivePath = `${plan.prefix}-1-cache.zip`;
|