@tiinex/core 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/package.json +7 -6
  2. package/src/schemas/creation.contracts.js +1 -1
  3. package/src/schemas/party/role/tiinex.party.role.v1.schema.js +5 -0
  4. package/src/schemas/party/role/tiinex.party.role.v1.schema.json +2 -2
  5. package/src/schemas/party/role/tiinex.party.role.v1.schema.md +313 -0
  6. package/src/schemas/party/role/tiinex.party.role.v1.schema.runtime.json +18 -6
  7. package/src/schemas/party/role/tiinex.party.role.v1.validate.js +36 -0
  8. package/src/schemas/schema.reference.js +29 -0
  9. package/src/tooling/portable/adapters/cli/cli.common-author.js +117 -6
  10. package/src/tooling/portable/adapters/cli/cli.common-output.js +19 -0
  11. package/src/tooling/portable/adapters/node/handoff.manufacture.js +26 -4
  12. package/src/tooling/portable/adapters/node/handoff.manufacture.packageParent.js +123 -0
  13. package/src/tooling/portable/audit/audit.capability.js +10 -4
  14. package/src/tooling/portable/grounding/grounding.capsule.js +26 -2
  15. package/src/tooling/portable/grounding/grounding.delegationArtifactAuthority.js +314 -0
  16. package/src/tooling/portable/grounding/grounding.delegationReadiness.js +241 -0
  17. package/src/tooling/portable/grounding/grounding.holderAssignmentModes.js +125 -0
  18. package/src/tooling/portable/grounding/grounding.holderBindingAuthorization.js +49 -50
  19. package/src/tooling/portable/grounding/grounding.readiness.js +19 -3
  20. package/src/tooling/portable/grounding/grounding.readiness.support.js +1 -1
  21. package/src/tooling/portable/handoff/carrierProjection.routeQualification.js +20 -4
  22. package/src/tooling/portable/handoff/coldStartQualification.grounding.js +67 -4
  23. package/src/tooling/portable/handoff/coldStartQualification.materials.js +84 -10
  24. package/src/tooling/portable/handoff/recipientV2.endpointRolePointers.js +1 -1
  25. package/src/tooling/portable/handoff/recipientV2.inspect.projection.js +5 -2
  26. package/src/tooling/portable/handoff/recipientV2.packageV1.build.js +2 -2
  27. package/src/tooling/portable/handoff/recipientV2.topology.js +5 -3
  28. package/src/tooling/portable/handoff/recipientV2.topology.materials.js +0 -0
@@ -11,6 +11,8 @@ import { runPortableOperation } from '../../operation.catalog.js';
11
11
  import { markPortableBootstrapCanonicalSource } from '../../providers/schema.bootstrap.provenance.js';
12
12
  import { allocateContinuationPath, allocateDirectoryArtifactPath } from '../../../../transitions/record.transitions.js';
13
13
  import { classifyParentRecoveryReference } from '../../../../lineage/parentRecoveryReference.js';
14
+ import { creationSchemaReferenceValidationContext } from '../../draft/draft.validation-context.js';
15
+ import { isQualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority, qualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority } from '../../../../schemas/schema.reference.js';
14
16
 
15
17
  const STATE_RELATIVE_PATH = '.tiinex/continuation.json';
16
18
 
@@ -66,16 +68,21 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
66
68
  await writeFile(artifactPath, markdown, { encoding: 'utf8', flag: flags.overwrite ? 'w' : 'wx' });
67
69
  wrote = true;
68
70
  const auditMaterial = await loadNodePortableInput(
69
- [artifactPath, ...(parentPath ? [parentPath] : [])],
71
+ [artifactPath],
70
72
  { maxFiles: flags['max-files'], maxTextBytes: flags['max-text-bytes'] }
71
73
  );
72
- const audit = await runPortableOperation('audit', auditMaterial, {});
74
+ const candidateAudit = await runPortableOperation('audit', auditMaterial, {});
75
+ const parentAudit = parentPath
76
+ ? await runHistoricalParentAudit(parentPath, parentRecord, contract, flags)
77
+ : null;
78
+ const audit = mergeAuthorAuditResults(candidateAudit, parentAudit);
73
79
  const stageMaterial = await loadNodePortableInput(
74
80
  normalizeRuntimePaths(runtime.defaultSchemaMaterialPaths),
75
81
  { maxFiles: flags['max-files'], maxTextBytes: flags['max-text-bytes'] }
76
82
  );
77
83
  const stage = await runPortableOperation('stage-draft', {
78
84
  ...stageMaterial,
85
+ schemaReferenceAuthorities: creationSchemaReferenceValidationContext(contract, parentRecord),
79
86
  draft: { path: artifactRelativePath, markdown, schemaId, sourceMode: 'local-common-author', source: null }
80
87
  }, {});
81
88
  const blocking = Number(audit?.findingSummary?.counts?.error || 0) + Number(stage?.findingSummary?.counts?.error || 0);
@@ -87,7 +94,7 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
87
94
  schema: 'tiinex.portable.common-author.result.v1',
88
95
  operation: 'author',
89
96
  status: 'blocked',
90
- artifact: Object.freeze({ path: artifactRelativePath, schemaId, written: false }),
97
+ artifact: Object.freeze({ path: artifactRelativePath, schemaId, written: false, parentPath: parentReference, parentSource: parentSource || '', parentSchemaReferenceAuthority: projectHistoricalParentReferenceAuthority(parentRecord) }),
91
98
  audit,
92
99
  stage,
93
100
  findingSummary: mergeFindingSummaries(audit?.findingSummary, stage?.findingSummary),
@@ -105,7 +112,7 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
105
112
  schema: 'tiinex.portable.common-author.result.v1',
106
113
  operation: 'author',
107
114
  status: 'qualified',
108
- artifact: Object.freeze({ path: artifactRelativePath, absolutePath: artifactPath, schemaId, parentPath: parentReference, parentSource: parentSource || '', selfIntegrity: selfIntegrity.state, written: true }),
115
+ artifact: Object.freeze({ path: artifactRelativePath, absolutePath: artifactPath, schemaId, parentPath: parentReference, parentSource: parentSource || '', parentSchemaReferenceAuthority: projectHistoricalParentReferenceAuthority(parentRecord), selfIntegrity: selfIntegrity.state, written: true }),
109
116
  qualification: Object.freeze({ audit: audit.status, stage: stage.status, exportReady: Boolean(stage?.stagedArtifact?.qualification?.exportReady) }),
110
117
  findingSummary: mergeFindingSummaries(audit?.findingSummary, stage?.findingSummary),
111
118
  nextAction: schemaId === 'tiinex.handoff.v1'
@@ -120,6 +127,88 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
120
127
  }
121
128
  }
122
129
 
130
+ async function runHistoricalParentAudit(parentPath, parentRecord = {}, contract = {}, flags = {}) {
131
+ const material = await loadNodePortableInput(
132
+ [parentPath],
133
+ { maxFiles: flags['max-files'], maxTextBytes: flags['max-text-bytes'] }
134
+ );
135
+ const exactCurrentMatch = sameExactSchemaReferenceAuthority(
136
+ parentRecord.schemaReferenceAuthority || null,
137
+ contract?.schemaReferences?.current || null,
138
+ parentRecord.schemaId || parentRecord.currentSchemaId || ''
139
+ );
140
+ return runPortableOperation('audit', material, {
141
+ schemaReferenceContext: 'historical',
142
+ schemaReferenceAuthorities: Object.freeze({ current: parentRecord.schemaReferenceAuthority || null }),
143
+ ...(exactCurrentMatch ? {} : {
144
+ schemaValidationAuthority: historicalParentSchemaValidationAuthority(parentRecord)
145
+ })
146
+ });
147
+ }
148
+
149
+ export function sameExactSchemaReferenceAuthority(parentAuthority = null, currentAuthority = null, schemaId = '') {
150
+ if (!parentAuthority || !currentAuthority) return false;
151
+ const expectedSchemaId = String(schemaId || '').trim();
152
+ const parentSchemaId = String(parentAuthority.schemaId || '').trim();
153
+ const currentSchemaId = String(currentAuthority.schemaId || '').trim();
154
+ if (!expectedSchemaId || parentSchemaId !== expectedSchemaId || currentSchemaId !== expectedSchemaId) return false;
155
+ if (String(parentAuthority.resolutionState || parentAuthority.state || '') !== 'qualified') return false;
156
+ if (String(currentAuthority.resolutionState || currentAuthority.state || '') !== 'qualified') return false;
157
+ const parentTargets = exactSchemaReferenceTargets(parentAuthority);
158
+ const currentTargets = new Set(exactSchemaReferenceTargets(currentAuthority));
159
+ return parentTargets.length > 0 && parentTargets.some((target) => currentTargets.has(target));
160
+ }
161
+
162
+ function exactSchemaReferenceTargets(authority = {}) {
163
+ return [...new Set([
164
+ ...(Array.isArray(authority.exactTargets) ? authority.exactTargets : []),
165
+ authority.preferredTarget || authority.target || ''
166
+ ].map((item) => String(item || '').trim()).filter(Boolean))];
167
+ }
168
+
169
+ function historicalParentSchemaValidationAuthority(parentRecord = {}) {
170
+ const schemaId = String(parentRecord.schemaId || parentRecord.currentSchemaId || '').trim();
171
+ const target = String(parentRecord.schemaReferenceAuthority?.preferredTarget || parentRecord.schemaReferenceAuthority?.target || '').trim();
172
+ const identifierOnly = isQualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority(parentRecord.schemaReferenceAuthority || {});
173
+ return Object.freeze({
174
+ schema: 'tiinex.portable.historical-parent-schema-validation-authority.v1',
175
+ state: 'unavailable',
176
+ reason: identifierOnly ? 'historical-parent-schema-revision-unresolved-identifier-only' : 'historical-parent-schema-revision-not-qualified-as-current-candidate-authority',
177
+ schemaId,
178
+ currentReference: Object.freeze({
179
+ state: identifierOnly ? 'historical-identifier-only-preserved' : target ? 'historical-exact-reference-preserved' : 'unavailable',
180
+ basis: identifierOnly ? 'historical-parent-declared-schema-identifier-only' : 'historical-parent-declared-schema-reference',
181
+ raw: '',
182
+ target,
183
+ exactRevisionState: identifierOnly ? 'unresolved' : target ? 'declared-exact-reference' : 'unavailable'
184
+ }),
185
+ lineage: Object.freeze([]),
186
+ findings: Object.freeze([
187
+ identifierOnly
188
+ ? `Historical Parent ${parentRecord.path || parentRecord.id || '(parent)'} preserves only the declared ${schemaId || 'Current Schema'} identifier; exact historical schema revision remains unresolved and current candidate schema validation is withheld for the Parent.`
189
+ : `Historical Parent ${parentRecord.path || parentRecord.id || '(parent)'} is preserved under its exact declared ${schemaId || 'Current Schema'} reference${target ? ` ${target}` : ''}; current candidate schema validation is withheld because exact same-revision current authority is not qualified.`
190
+ ]),
191
+ compiledContract: null,
192
+ boundary: 'Historical Parent validation still runs Root readability, exact declared schema-identifier/reference-shape checks, recovery and integrity. Identifier-only authority never becomes exact historical schema-revision authority; current schema-specific machine/companion validation is applied only when the Parent and current creation contract share exact qualified schema-revision authority.'
193
+ });
194
+ }
195
+
196
+ function mergeAuthorAuditResults(candidateAudit = {}, parentAudit = null) {
197
+ if (!parentAudit) return candidateAudit;
198
+ const audits = Object.freeze([...(candidateAudit.audits || []), ...(parentAudit.audits || [])]);
199
+ const findings = Object.freeze([...(candidateAudit.findings || []), ...(parentAudit.findings || [])]);
200
+ return Object.freeze({
201
+ ...candidateAudit,
202
+ audits,
203
+ findings,
204
+ findingSummary: mergeFindingSummaries(candidateAudit.findingSummary, parentAudit.findingSummary),
205
+ boundary: Object.freeze({
206
+ ...(candidateAudit.boundary || {}),
207
+ historicalParentAudit: 'separate exact-byte historical audit; current schema-specific validation only when exact same-revision authority is qualified'
208
+ })
209
+ });
210
+ }
211
+
123
212
  async function parentRecordFromArtifact(parentPath, parentRelativePath, context = {}) {
124
213
  const markdown = await readFile(parentPath, 'utf8');
125
214
  const parsed = parseArtifactMarkdown(markdown);
@@ -131,8 +220,11 @@ async function parentRecordFromArtifact(parentPath, parentRelativePath, context
131
220
  if (self.state !== 'verified') throw new Error(`portable.cli.author.parent.integrity.${self.reason || self.state}`);
132
221
  const schemaReferenceAuthority = schemaTarget
133
222
  ? exactDeclaredSchemaReferenceAuthority(schemaId, schemaTarget)
134
- : await recoverQualifiedRuntimeSchemaReferenceAuthority(schemaId, context.runtime || {});
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.`);
223
+ : qualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority(schemaId, {
224
+ basis: 'exact-historical-parent-current-schema-identifier',
225
+ parentPath: String(parentRelativePath || ''),
226
+ parentSha256: sha256Hex(utf8Bytes(markdown))
227
+ });
136
228
  return Object.freeze({
137
229
  id: parentRelativePath,
138
230
  path: parentRelativePath,
@@ -146,6 +238,25 @@ async function parentRecordFromArtifact(parentPath, parentRelativePath, context
146
238
  });
147
239
  }
148
240
 
241
+ function projectHistoricalParentReferenceAuthority(parentRecord = {}) {
242
+ const authority = parentRecord?.schemaReferenceAuthority || null;
243
+ if (!authority || !String(parentRecord?.schemaId || parentRecord?.currentSchemaId || '').trim()) return null;
244
+ const schemaId = String(parentRecord.schemaId || parentRecord.currentSchemaId || '').trim();
245
+ const target = String(authority.preferredTarget || authority.target || '').trim();
246
+ const identifierOnly = isQualifiedIdentifierOnlyHistoricalSchemaReferenceAuthority(authority);
247
+ return Object.freeze({
248
+ state: String(authority.resolutionState || authority.state || 'unavailable'),
249
+ kind: identifierOnly ? 'identifier-only' : target ? 'exact-target' : 'unresolved',
250
+ schemaId,
251
+ target,
252
+ exactRevisionState: identifierOnly ? 'unresolved' : target ? 'declared-exact-reference' : 'unresolved',
253
+ provenance: Object.freeze({ ...(authority.resolutionEvidence || authority.evidence || {}) }),
254
+ boundary: identifierOnly
255
+ ? 'Exact historical Parent artifact identity/integrity and declared schema identifier are qualified; no exact historical schema representation target is claimed or inferred.'
256
+ : 'Historical Parent schema-reference authority is projected only at the exact strength carried by the supplied Parent bytes.'
257
+ });
258
+ }
259
+
149
260
  function projectAuthorActionableFindings(audit = {}, stage = {}) {
150
261
  const findings = [
151
262
  ...(audit.findings || audit.actionableFindings || []),
@@ -104,6 +104,7 @@ function projectGroundDefault(result = {}, parsed = {}) {
104
104
  readiness: compactReadiness(result.readiness),
105
105
  authority: compactGroundAuthority(result.authority),
106
106
  orchestrationReadiness: compactOrchestrationReadiness(result.orchestrationReadiness),
107
+ delegationReadiness: compactDelegationReadiness(result.delegationReadiness),
107
108
  requiredContext: Object.freeze({
108
109
  declared: Number(required.declared || 0),
109
110
  matchedInWorkspaceSnapshots: Number(required.matchedInWorkspaceSnapshots || 0),
@@ -300,6 +301,24 @@ function compactGroundAuthority(authority = {}) {
300
301
  });
301
302
  }
302
303
 
304
+
305
+ function compactDelegationReadiness(value = {}) {
306
+ if (!value || typeof value !== 'object') return null;
307
+ return Object.freeze({
308
+ state: String(value.state || ''),
309
+ delegateCapabilityAuthority: value.delegateCapabilityAuthority ? Object.freeze({ ...value.delegateCapabilityAuthority }) : null,
310
+ processApplicability: value.processApplicability ? Object.freeze({ ...value.processApplicability }) : null,
311
+ targetAuthority: value.targetAuthority ? Object.freeze({ ...value.targetAuthority }) : null,
312
+ sourceAuthority: value.sourceAuthority ? Object.freeze({ ...value.sourceAuthority }) : null,
313
+ returnReconciliationExpectation: value.returnReconciliationExpectation ? Object.freeze({ ...value.returnReconciliationExpectation }) : null,
314
+ blockers: Object.freeze((value.blockers || []).slice(0, 8).map((item) => Object.freeze({ ...item }))),
315
+ plainChatFallbackPermitted: Boolean(value.plainChatFallbackPermitted),
316
+ repositoryScanningFallbackPermitted: Boolean(value.repositoryScanningFallbackPermitted),
317
+ nextOperations: Object.freeze((value.nextOperations || []).slice(0, 4).map((item) => Object.freeze({ ...item }))),
318
+ boundary: String(value.boundary || '')
319
+ });
320
+ }
321
+
303
322
  function compactOrchestrationReadiness(value = {}) {
304
323
  if (!value || typeof value !== 'object') return null;
305
324
  const wider = value.widerOrchestration || {};
@@ -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, projectRequiredContextWorkspaceSelectionPreflight } from './handoff.manufacture.packageParent.js';
9
+ import { preparePackageParentExactMaterialProvider, preparePackageParentWorkspaceReuse, projectPackageParentMaterialClosurePreflight, projectRequiredContextWorkspaceSelectionPreflight, resolvePackageParentRequirementMaterials } 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';
@@ -69,6 +69,12 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
69
69
  workspaceIds: input.packageParentWorkspaceIds || input.reusePackageParentWorkspaceIds || [],
70
70
  workspaceAliases: input.packageParentWorkspaceAliases || input.workspaceAliases || {}
71
71
  });
72
+ const packageParentExactMaterialProvider = preparePackageParentExactMaterialProvider({
73
+ bundle: input.packageParentBundle || null,
74
+ currentWorkspaceIds: [...seenWorkspaceIds],
75
+ parentPackagePath: input.packageParentPath || '',
76
+ parentPackageSha256: input.packageParentSha256 || ''
77
+ });
72
78
  const handoffMarkdown = await handoffMarkdownPromise;
73
79
  const requiredContextWorkspaceSelectionPreflight = projectRequiredContextWorkspaceSelectionPreflight({
74
80
  handoffMarkdown,
@@ -169,16 +175,18 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
169
175
 
170
176
  const routeSpecs = transportRoutes.length ? transportRoutes : Object.freeze([{ workspaceId, path: handoffPath }]);
171
177
  let requirements = await projectManufacturingRequirements({ handoff, workspaceId, handoffPath, routeSpecs, workspaceRuntimeById });
178
+ const packageParentMaterialClosurePreflight = projectPackageParentMaterialClosurePreflight(requirements, packageParentExactMaterialProvider);
172
179
  let materials = await resolveWorkspaceRequirementMaterials(requirements, workspaceRuntimeById, input.materialBindings || {});
180
+ materials = appendMissingRequirementMaterials(materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
173
181
  const dependencyClosure = await expandPointerDependencyClosure({ requirements, materials, workspaceRuntimeById, bindings: input.materialBindings || {} });
174
182
  requirements = dependencyClosure.requirements;
175
- materials = dependencyClosure.materials;
183
+ materials = appendMissingRequirementMaterials(dependencyClosure.materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
176
184
  const routeParentBoundaryClosure = expandRouteParentBoundaryClosure({ requirements, materials, workspaceMaterializations, workspaceRuntimeById, routeSpecs });
177
185
  requirements = routeParentBoundaryClosure.requirements;
178
- materials = routeParentBoundaryClosure.materials;
186
+ materials = appendMissingRequirementMaterials(routeParentBoundaryClosure.materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
179
187
  const parentBoundaryClosure = expandBoundedParentBoundaryClosure({ requirements, materials, workspaceMaterializations, workspaceRuntimeById });
180
188
  requirements = parentBoundaryClosure.requirements;
181
- materials = parentBoundaryClosure.materials;
189
+ materials = appendMissingRequirementMaterials(parentBoundaryClosure.materials, resolvePackageParentRequirementMaterials(requirements, packageParentExactMaterialProvider));
182
190
  const toolingBootstrapResult = await toolingBootstrapPromise;
183
191
  if (toolingBootstrapResult.error) throw toolingBootstrapResult.error;
184
192
  const toolingBootstrap = toolingBootstrapResult.value;
@@ -233,6 +241,7 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
233
241
  workspaceAliases: Object.freeze([...(packageParentReuse.workspaceAliases || [])].map((item) => Object.freeze({ ...item }))),
234
242
  boundary: String(packageParentReuse.boundary || '')
235
243
  }),
244
+ packageParentMaterialClosurePreflight,
236
245
  requiredContextWorkspaceSelectionPreflight,
237
246
  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.' })
238
247
  }),
@@ -241,6 +250,19 @@ export async function prepareNodeHandoffManufacturingInput(input = {}, options =
241
250
  }
242
251
 
243
252
 
253
+ function appendMissingRequirementMaterials(existing = [], additional = []) {
254
+ const out = [...(existing || [])];
255
+ const alreadyBound = new Set(out.map((item) => String(item.requirementId || '')).filter(Boolean));
256
+ for (const item of additional || []) {
257
+ const id = String(item.requirementId || '');
258
+ if (id && alreadyBound.has(id)) continue;
259
+ out.push(item);
260
+ if (id) alreadyBound.add(id);
261
+ }
262
+ return Object.freeze(out);
263
+ }
264
+
265
+
244
266
  function mergeWorkspaceTargetBindings(explicit = [], inherited = []) {
245
267
  const out = [];
246
268
  const seen = new Set();
@@ -3,6 +3,7 @@ import { inspectRecipientFacingV2Topology } from '../../handoff/recipientV2.insp
3
3
  import { parseHandoffPackageV1, RECIPIENT_V2_PACKAGE_V1_ROOT_PATH } from '../../handoff/recipientV2.packageV1.js';
4
4
  import { projectHandoffMaterialRequirements } from '../../handoff/materialClosure.requirements.js';
5
5
  import { parseWorkspaceQualifiedReference } from '../../handoff/workspaceQualifiedReference.js';
6
+ import { inspectStoredWorkspaceArchive } from '../../handoff/workspaceByteProvider.js';
6
7
 
7
8
  export function preparePackageParentWorkspaceReuse(input = {}) {
8
9
  const bundle = input.bundle || null;
@@ -77,6 +78,128 @@ export function preparePackageParentWorkspaceReuse(input = {}) {
77
78
  });
78
79
  }
79
80
 
81
+
82
+
83
+ export function preparePackageParentExactMaterialProvider(input = {}) {
84
+ const bundle = input.bundle || null;
85
+ const currentIds = new Set([...(input.currentWorkspaceIds || [])].map(normalizeId).filter(Boolean));
86
+ if (!bundle?.files?.length) return emptyExactMaterialProvider('unavailable');
87
+ const inspection = inspectRecipientFacingV2Topology(bundle);
88
+ const claims = [];
89
+ for (const cache of inspection.caches || []) {
90
+ const archivePath = String(cache.archivePath || '').trim();
91
+ const matches = (bundle.files || []).filter((file) => String(file.path || '') === archivePath);
92
+ let archive = null;
93
+ if (matches.length === 1) {
94
+ try { archive = inspectStoredWorkspaceArchive(packageFileBytes(matches[0]), { ownedBytes: true }); } catch { archive = null; }
95
+ }
96
+ const byPath = new Map((archive?.entries || []).map((entry) => [String(entry.path || ''), entry]));
97
+ for (const material of cache.materials || []) {
98
+ const referenceTarget = String(material.referenceTarget || '').trim();
99
+ if (!referenceTarget) continue;
100
+ const parsed = parseWorkspaceQualifiedReference(referenceTarget);
101
+ if (parsed && currentIds.has(normalizeId(parsed.workspaceId))) continue;
102
+ const entry = byPath.get(String(material.archiveEntry || '')) || null;
103
+ const declaredSha = String(material.sha256 || '').trim();
104
+ const declaredBytes = Number(material.bytes || 0);
105
+ const entrySha = entry ? String(entry.sha256 || sha256Hex(entry.data || new Uint8Array())) : '';
106
+ const entryBytes = entry ? Number(entry.bytes || packageFileBytes({ data: entry.data }).byteLength) : 0;
107
+ const qualified = inspection.status === 'valid' && archive?.state === 'qualified' && Boolean(entry)
108
+ && (!declaredSha || declaredSha === entrySha) && (!declaredBytes || declaredBytes === entryBytes);
109
+ claims.push(Object.freeze({
110
+ referenceTarget,
111
+ state: qualified ? 'available-qualified' : 'present-unqualified',
112
+ reason: qualified ? '' : inspection.status !== 'valid' ? 'parent-carrier-inspection-invalid' : archive?.state !== 'qualified' ? 'cache-archive-unqualified' : !entry ? 'cache-entry-unresolved' : 'cache-entry-identity-mismatch',
113
+ classification: String(material.classification || ''),
114
+ sourceRequirementId: String(material.requirementId || material.sourceRequirementId || ''),
115
+ workspaceId: String(cache.workspaceId || ''),
116
+ cacheArtifactPath: String(cache.artifactPath || ''),
117
+ cacheArchivePath: archivePath,
118
+ archiveEntry: String(material.archiveEntry || ''),
119
+ targetWorkspaceId: String(material.targetWorkspaceId || parsed?.workspaceId || ''),
120
+ targetPath: String(material.targetPath || material.originalPath || parsed?.path || ''),
121
+ bytes: entryBytes, sha256: entrySha, data: entry?.data || null
122
+ }));
123
+ }
124
+ }
125
+ const byTarget = new Map();
126
+ for (const claim of claims) {
127
+ const list = byTarget.get(claim.referenceTarget) || [];
128
+ list.push(claim); byTarget.set(claim.referenceTarget, list);
129
+ }
130
+ const entries = [];
131
+ for (const [referenceTarget, targetClaims] of byTarget.entries()) {
132
+ const qualified = targetClaims.filter((item) => item.state === 'available-qualified');
133
+ const digests = [...new Set(qualified.map((item) => item.sha256).filter(Boolean))];
134
+ if (digests.length !== 1) continue;
135
+ const same = qualified.filter((item) => item.sha256 === digests[0]);
136
+ if (!same.length) continue;
137
+ const first = same[0];
138
+ entries.push(Object.freeze({
139
+ referenceTarget, data: first.data, bytes: first.bytes, sha256: first.sha256,
140
+ providerId: 'qualified-package-parent-exact-material',
141
+ providerKind: 'qualified-package-parent-cache-material',
142
+ provenance: Object.freeze({
143
+ parentPackagePath: String(input.parentPackagePath || ''), parentPackageSha256: String(input.parentPackageSha256 || ''),
144
+ providerMode: 'qualified-package-parent-cache', cacheArtifactPath: first.cacheArtifactPath, cacheArchivePath: first.cacheArchivePath,
145
+ archiveEntry: first.archiveEntry, sourceRequirementIds: Object.freeze([...new Set(same.map((item) => item.sourceRequirementId).filter(Boolean))].sort()),
146
+ referenceTarget, workspaceId: first.targetWorkspaceId || first.workspaceId, path: first.targetPath, authority: 'none'
147
+ })
148
+ }));
149
+ }
150
+ return Object.freeze({
151
+ state: inspection.status === 'valid' ? 'qualified' : 'present-unqualified', inspectionStatus: String(inspection.status || ''),
152
+ entries: Object.freeze(entries), claims: Object.freeze(claims),
153
+ boundary: 'Exact material already present in a received qualified package cache may satisfy a newly authored return requirement only after exact declared-target and byte-identity qualification. Reuse is mechanical byte closure only: it does not select Workspace source, create semantic authority, infer delegation, or authorize repository discovery.'
154
+ });
155
+ }
156
+
157
+ export function resolvePackageParentRequirementMaterials(requirements = {}, provider = {}) {
158
+ const out = [];
159
+ const byTarget = new Map((provider.entries || []).map((entry) => [String(entry.referenceTarget || ''), entry]));
160
+ for (const requirement of allBlockingRequirements(requirements)) {
161
+ const target = String(requirement.reference?.target || requirement.materialReference || '').trim();
162
+ if (!target) continue;
163
+ const entry = byTarget.get(target);
164
+ if (!entry) continue;
165
+ out.push(Object.freeze({
166
+ requirementId: String(requirement.id || ''), referenceTarget: target, path: String(entry.provenance?.path || ''),
167
+ data: entry.data, bytes: Number(entry.bytes || 0), sha256: String(entry.sha256 || ''),
168
+ providerId: String(entry.providerId || ''), providerKind: String(entry.providerKind || ''),
169
+ provenance: Object.freeze({ ...(entry.provenance || {}), reboundRequirementId: String(requirement.id || ''), reboundClassification: String(requirement.classification || '') }),
170
+ authority: Object.freeze({ packageParentMaterialQualified: true, semanticAuthority: 'none', sourceSelectionAuthority: false })
171
+ }));
172
+ }
173
+ return Object.freeze(out);
174
+ }
175
+
176
+ export function projectPackageParentMaterialClosurePreflight(requirements = {}, provider = {}) {
177
+ const claimsByTarget = new Map();
178
+ for (const claim of provider.claims || []) { const list = claimsByTarget.get(String(claim.referenceTarget || '')) || []; list.push(claim); claimsByTarget.set(String(claim.referenceTarget || ''), list); }
179
+ const entryTargets = new Set((provider.entries || []).map((item) => String(item.referenceTarget || '')));
180
+ const projected = [];
181
+ for (const requirement of allBlockingRequirements(requirements)) {
182
+ const target = String(requirement.reference?.target || requirement.materialReference || '').trim();
183
+ if (!target) continue;
184
+ const claims = claimsByTarget.get(target) || [];
185
+ const state = entryTargets.has(target) ? 'available-qualified' : claims.length ? 'present-unqualified' : 'absent';
186
+ projected.push(Object.freeze({
187
+ requirementId: String(requirement.id || ''), classification: normalizeRequirementClass(requirement.classification), referenceTarget: target, state,
188
+ provenance: Object.freeze(claims.map((claim) => Object.freeze({ cacheArchivePath: claim.cacheArchivePath, archiveEntry: claim.archiveEntry, sha256: claim.sha256, reason: claim.reason }))),
189
+ nextAction: state === 'available-qualified' ? 'No action required; exact parent-carrier bytes are mechanically available.' : `Supply exact qualified material for ${target} through an explicit local binding, qualified Workspace provider, or qualified received-package cache surface. Tooling will not scan repositories or infer a source.`
190
+ }));
191
+ }
192
+ const blockers = projected.filter((item) => item.state !== 'available-qualified');
193
+ return Object.freeze({
194
+ state: blockers.length ? 'action-required' : 'ready', requirements: Object.freeze(projected), blockerCount: blockers.length,
195
+ boundary: 'This preflight classifies exact return-material closure only. Qualified received-package bytes may close declared material requirements, but this does not create semantic authority, select a Workspace source, establish process applicability, or authorize repository/network discovery.'
196
+ });
197
+ }
198
+
199
+ function allBlockingRequirements(requirements = {}) { return [...(requirements.required || []), ...(requirements.endpointRoles || []), ...(requirements.participantRoles || []), ...(requirements.dependencies || [])]; }
200
+ function normalizeRequirementClass(value = '') { const v = String(value || ''); return v === 'endpoint-role' || v === 'participant-role' ? v : v || 'required'; }
201
+ function emptyExactMaterialProvider(state = 'unavailable') { return Object.freeze({ state, inspectionStatus: '', entries: Object.freeze([]), claims: Object.freeze([]), boundary: 'No qualified received-package exact material provider is available; Tooling will not infer one.' }); }
202
+
80
203
  export function projectRequiredContextWorkspaceSelectionPreflight(input = {}) {
81
204
  const reuse = input.packageParentReuse || input.reuse || {};
82
205
  const currentWorkspaceIds = new Set([...(input.currentWorkspaceIds || [])].map(normalizeId).filter(Boolean));
@@ -8,15 +8,21 @@ export const PORTABLE_SHARED_AUDIT_CAPABILITY_SCHEMA_ID = 'tiinex.portable.share
8
8
  export function auditPortableRecord(record = {}, options = {}) {
9
9
  const schemaId = String(record.schemaId || record.currentSchemaId || '');
10
10
  const requireExactSchemaAuthority = options.requireExactSchemaAuthority === true;
11
- const runtimeAuthority = requireExactSchemaAuthority ? portableRuntimeValidationAuthorityForRecord(record) : null;
12
- const runtimeProjection = requireExactSchemaAuthority ? runtimeAuthority : portableRuntimeValidationContractForSchema(schemaId);
11
+ const explicitSchemaValidationAuthority = options.schemaValidationAuthority || null;
12
+ const runtimeAuthority = explicitSchemaValidationAuthority || (requireExactSchemaAuthority ? portableRuntimeValidationAuthorityForRecord(record) : null);
13
+ const runtimeProjection = explicitSchemaValidationAuthority
14
+ ? (explicitSchemaValidationAuthority.state === 'qualified' ? explicitSchemaValidationAuthority : null)
15
+ : requireExactSchemaAuthority
16
+ ? runtimeAuthority
17
+ : portableRuntimeValidationContractForSchema(schemaId);
13
18
  let result;
14
19
  try {
15
20
  result = runAudit({
16
21
  record,
17
22
  markdown: record.markdown,
18
- validationContractOverride: runtimeProjection?.state === 'qualified' ? runtimeProjection.compiledContract : null,
19
- schemaValidationAuthority: requireExactSchemaAuthority ? runtimeAuthority : null,
23
+ validationContractOverride: options.validationContractOverride || (runtimeProjection?.state === 'qualified' ? runtimeProjection.compiledContract : null),
24
+ schemaValidationAuthority: explicitSchemaValidationAuthority || (requireExactSchemaAuthority ? runtimeAuthority : null),
25
+ schemaReferenceAuthorities: options.schemaReferenceAuthorities || null,
20
26
  schemaReferenceContext: options.schemaReferenceContext || 'historical'
21
27
  });
22
28
  } catch (error) {
@@ -5,6 +5,8 @@ import { projectGroundingPlanningContext } from './grounding.planningContext.js'
5
5
  import { projectGroundingParticipantContext } from './grounding.participantContext.js';
6
6
  import { projectGroundingProcessApplicability } from './grounding.processApplicability.js';
7
7
  import { projectGroundingImplementationSourceAuthority } from './grounding.implementationSourceAuthority.js';
8
+ import { projectGroundingDelegationReadiness } from './grounding.delegationReadiness.js';
9
+ import { projectGroundingDelegationArtifactAuthority } from './grounding.delegationArtifactAuthority.js';
8
10
 
9
11
  export const PORTABLE_GROUNDING_CAPSULE_SCHEMA_ID = 'tiinex.portable.grounding-capsule.v1';
10
12
 
@@ -16,9 +18,12 @@ export function projectGroundingCapsule({ authority = null, continuation = null,
16
18
  const workProvenance = projectWorkProvenance({ records, topology });
17
19
  const participantAuthority = projectParticipantAuthority(authority);
18
20
  const participantContext = projectGroundingParticipantContext(authority);
19
- const processApplicability = projectGroundingProcessApplicability(authority);
20
- const implementationSourceAuthority = projectGroundingImplementationSourceAuthority({ authority, records, contextAudit, requiredContext });
21
21
  const sourceEvidence = projectGroundingSourceEvidence({ records, contextAudit, continuation, requiredContext });
22
+ const delegationArtifactAuthority = projectGroundingDelegationArtifactAuthority({ authority, records, topology, sourceEvidence });
23
+ const effectiveAuthority = mergeArtifactDelegationAuthority(authority, delegationArtifactAuthority);
24
+ const processApplicability = projectGroundingProcessApplicability(effectiveAuthority);
25
+ const implementationSourceAuthority = projectGroundingImplementationSourceAuthority({ authority: effectiveAuthority, records, contextAudit, requiredContext });
26
+ const delegationReadiness = projectGroundingDelegationReadiness({ authority: effectiveAuthority, processApplicability, implementationSourceAuthority });
22
27
  return Object.freeze({
23
28
  schema: PORTABLE_GROUNDING_CAPSULE_SCHEMA_ID,
24
29
  semanticReductions: Object.freeze(requiredContext.slice(0, MAX_CONTEXT).map(reduceRequiredContext)),
@@ -34,24 +39,43 @@ export function projectGroundingCapsule({ authority = null, continuation = null,
34
39
  compatibility: String(authority?.holderBinding?.recipientCompatibility || 'unresolved'),
35
40
  authorizationState: String(authority?.holderBinding?.authorization?.state || (String(authority?.holderBinding?.state || '') === 'not-applicable' ? 'not-applicable' : 'unresolved')),
36
41
  authorizationSource: String(authority?.holderBinding?.authorization?.source || ''),
42
+ assertionMode: String(authority?.holderBinding?.assertionMode || authority?.holderBinding?.authorization?.assignmentMode || ''),
43
+ authorizedModes: Object.freeze([...(authority?.holderBinding?.authorization?.authorizedModes || [])]),
44
+ authorizationBasis: String(authority?.holderBinding?.authorization?.modeAuthority?.provenance?.basis || authority?.holderBinding?.authorization?.provenance?.basis || ''),
37
45
  durableIdentityState: String(authority?.holderBinding?.durableIdentity?.state || 'not-established')
38
46
  }),
39
47
  participantAuthority,
40
48
  participantContext,
41
49
  processApplicability,
42
50
  implementationSourceAuthority,
51
+ delegationArtifactAuthority,
52
+ delegationReadiness,
43
53
  workProvenance,
44
54
  unresolved: Object.freeze([
45
55
  ...workProvenance.unresolved,
46
56
  ...participantContext.unresolved,
47
57
  ...processApplicability.unresolved,
48
58
  ...implementationSourceAuthority.unresolved,
59
+ ...delegationReadiness.blockers.map((item) => ({ code: item.code, detail: item.request })),
49
60
  ...sourceEvidence.blockers.map((item) => ({ code: item.code, detail: item.request }))
50
61
  ]),
51
62
  boundary: 'Full Required Context bodies remain selector-gated.'
52
63
  });
53
64
  }
54
65
 
66
+ function mergeArtifactDelegationAuthority(authority = null, artifact = null) {
67
+ if (!artifact || typeof artifact !== 'object') return authority || {};
68
+ const base = authority && typeof authority === 'object' ? authority : {};
69
+ return Object.freeze({
70
+ ...base,
71
+ delegateCapabilityAuthority: base.delegateCapabilityAuthority || artifact.delegateCapabilityAuthority,
72
+ processApplicability: base.processApplicability || artifact.processApplicability,
73
+ delegationTargetAuthority: base.delegationTargetAuthority || artifact.delegationTargetAuthority,
74
+ implementationSourceAuthority: base.implementationSourceAuthority || artifact.implementationSourceAuthority,
75
+ delegationReturnReconciliationExpectation: base.delegationReturnReconciliationExpectation || artifact.delegationReturnReconciliationExpectation
76
+ });
77
+ }
78
+
55
79
  function reduceRequiredContext(entry = {}) {
56
80
  const qualified = String(entry.state || '') === 'qualified';
57
81
  const markdown = qualified && typeof entry.content === 'string' ? entry.content : '';