@tiinex/core 0.10.0 → 0.11.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiinex/core",
3
- "version": "0.10.0",
3
+ "version": "0.11.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,
@@ -167,12 +167,12 @@
167
167
  "type": "git",
168
168
  "url": "git+https://github.com/Tiinex/core.git"
169
169
  },
170
- "gitHead": "3a1efbac38c1cabc1a0d85746ccaab8149d6162e",
170
+ "gitHead": "d9fce40b1ec63fb0e4dc0a673161650d1661a25c",
171
171
  "tiinexRelease": {
172
172
  "policy": "tiinex.master-npm-release.v1",
173
- "sourceCommit": "3a1efbac38c1cabc1a0d85746ccaab8149d6162e",
174
- "sourceTree": "8c1449869841737fb7b120b69d00b4854cfff334",
173
+ "sourceCommit": "d9fce40b1ec63fb0e4dc0a673161650d1661a25c",
174
+ "sourceTree": "1827ddd3975215d019cb809f2d477de6ebc4b300",
175
175
  "repository": "Tiinex/core",
176
- "previousVersion": "0.9.0"
176
+ "previousVersion": "0.10.0"
177
177
  }
178
178
  }
@@ -8,6 +8,7 @@ import { sha256Hex, utf8Bytes } from '../../../../export/package.bytes.js';
8
8
  import { resolveSchemaModule } from '../../../../schemas/resolver.js';
9
9
  import { loadNodePortableInput } from '../../input/node.input.js';
10
10
  import { runPortableOperation } from '../../operation.catalog.js';
11
+ import { markPortableBootstrapCanonicalSource } from '../../providers/schema.bootstrap.provenance.js';
11
12
  import { allocateContinuationPath, allocateDirectoryArtifactPath } from '../../../../transitions/record.transitions.js';
12
13
  import { classifyParentRecoveryReference } from '../../../../lineage/parentRecoveryReference.js';
13
14
 
@@ -36,7 +37,7 @@ export async function runCommonAuthorCli(parsed = {}, runtime = {}) {
36
37
  const parentPath = parentReference ? (parentSource ? path.resolve(parentSource) : safeWorkspaceTarget(workspaceRoot, parentReference)) : '';
37
38
  const artifactRelativePath = requestedArtifactRelativePath || await allocateArtifactRelativePath({ workspaceRoot, targetDirectory, parentRelativePath: parentReference, schemaId, title });
38
39
  const artifactPath = safeWorkspaceTarget(workspaceRoot, artifactRelativePath);
39
- const parentRecord = parentPath ? await parentRecordFromArtifact(parentPath, parentReference, { workspaceRoot, childRelativePath: artifactRelativePath }) : {};
40
+ const parentRecord = parentPath ? await parentRecordFromArtifact(parentPath, parentReference, { workspaceRoot, childRelativePath: artifactRelativePath, runtime }) : {};
40
41
  const transitionType = String(flags.transition || defaultTransition(schemaId, Boolean(parentPath))).trim();
41
42
  const contract = buildArtifactCreationContract({ schemaId, transitionType });
42
43
  const summary = String(flags.summary || title).trim();
@@ -128,7 +129,7 @@ async function parentRecordFromArtifact(parentPath, parentRelativePath, context
128
129
  if (self.state !== 'verified') throw new Error(`portable.cli.author.parent.integrity.${self.reason || self.state}`);
129
130
  const schemaReferenceAuthority = schemaTarget
130
131
  ? exactDeclaredSchemaReferenceAuthority(schemaId, schemaTarget)
131
- : await recoverQualifiedLocalSchemaReferenceAuthority(schemaId, context);
132
+ : await recoverQualifiedRuntimeSchemaReferenceAuthority(schemaId, context.runtime || {});
132
133
  if (!schemaReferenceAuthority) throw new Error('portable.cli.author.parent.schema-authority.required');
133
134
  return Object.freeze({
134
135
  id: parentRelativePath,
@@ -159,48 +160,115 @@ function exactDeclaredSchemaReferenceAuthority(schemaId, schemaTarget) {
159
160
  });
160
161
  }
161
162
 
162
- async function recoverQualifiedLocalSchemaReferenceAuthority(schemaId, context = {}) {
163
- const workspaceRoot = path.resolve(String(context.workspaceRoot || '.'));
164
- const childRelativePath = normalizeWorkspaceRelativePath(context.childRelativePath || '');
163
+ export async function recoverQualifiedRuntimeSchemaReferenceAuthority(schemaId, runtime = {}) {
165
164
  const resolution = resolveSchemaModule({ schemaId });
166
165
  const module = resolution?.fallbackUsed ? null : resolution?.module || null;
167
166
  const source = module?.schemaSource || null;
168
167
  const qualification = typeof source?.qualify === 'function' ? source.qualify() : null;
169
168
  const materialIdentity = qualification?.materialIdentity || {};
170
- const bundledPath = normalizeWorkspaceRelativePath(source?.bundledPath || '');
171
169
  const expectedSha256 = String(materialIdentity.sha256 || qualification?.checksum || '').trim().toLowerCase();
172
170
  if (!module || String(module.id || '') !== schemaId) return null;
173
171
  if (qualification?.state !== 'qualified' || materialIdentity?.state !== 'qualified' || String(materialIdentity.schemaId || '') !== schemaId) return null;
174
- if (!bundledPath || !childRelativePath || !expectedSha256) return null;
172
+ if (!expectedSha256) return null;
175
173
 
176
- let localMarkdown;
177
- try { localMarkdown = await readFile(safeWorkspaceTarget(workspaceRoot, bundledPath), 'utf8'); }
178
- catch { return null; }
179
- if (sha256Hex(utf8Bytes(localMarkdown)).toLowerCase() !== expectedSha256) return null;
174
+ const runtimeMaterial = await loadQualifiedRuntimeSchemaMaterial(schemaId, runtime);
175
+ if (!runtimeMaterial) return null;
176
+ const markdown = String(runtimeMaterial.markdown || '');
177
+ const observedSha256 = markdown ? sha256Hex(utf8Bytes(markdown)).toLowerCase() : '';
178
+ const observedBytes = markdown ? utf8Bytes(markdown).byteLength : 0;
179
+ if (!observedSha256 || observedSha256 !== expectedSha256) return null;
180
+ if (Number(materialIdentity.bytes || 0) > 0 && observedBytes !== Number(materialIdentity.bytes)) return null;
181
+ if (!exactRuntimeSchemaSourceIdentity(runtimeMaterial.source || {}, materialIdentity)) return null;
180
182
 
181
- let localParsed;
182
- try { localParsed = parseArtifactMarkdown(localMarkdown); }
183
- catch { return null; }
184
- if (String(localParsed.envelope?.current?.schema?.id || '').trim() !== schemaId) return null;
185
-
186
- const childDir = path.posix.dirname(childRelativePath);
187
- const preferredTarget = path.posix.relative(childDir === '.' ? '' : childDir, bundledPath);
188
- if (!preferredTarget || path.posix.isAbsolute(preferredTarget)) return null;
183
+ const preferredTarget = durableRuntimeSchemaTarget(runtimeMaterial.source || {}, materialIdentity, runtime.defaultSchemaSource || {});
184
+ if (!preferredTarget) return null;
189
185
  return Object.freeze({
190
186
  schemaId,
191
187
  exactTargets: Object.freeze([preferredTarget]),
192
188
  preferredTarget,
193
189
  resolutionState: 'qualified',
194
- targetAuthority: 'qualified-local-bundled-schema-material',
190
+ targetAuthority: 'qualified-runtime-canonical-schema-material',
195
191
  resolutionEvidence: Object.freeze({
196
192
  state: 'qualified',
197
- kind: 'workspace-bundled-schema-byte-match',
198
- workspacePath: bundledPath,
199
- sha256: expectedSha256
193
+ kind: 'runtime-canonical-schema-byte-match',
194
+ target: preferredTarget,
195
+ materialIdentity: Object.freeze({
196
+ state: 'qualified',
197
+ schemaId,
198
+ sha256: observedSha256,
199
+ bytes: observedBytes,
200
+ sourceRepository: String(materialIdentity.sourceRepository || ''),
201
+ sourceCommit: String(materialIdentity.sourceCommit || ''),
202
+ sourcePath: String(materialIdentity.sourcePath || ''),
203
+ sourceBlobSha: String(materialIdentity.sourceBlobSha || '')
204
+ })
200
205
  })
201
206
  });
202
207
  }
203
208
 
209
+ async function loadQualifiedRuntimeSchemaMaterial(schemaId, runtime = {}) {
210
+ const targets = normalizeRuntimePaths(runtime.defaultSchemaMaterialPaths);
211
+ if (!targets.length) return null;
212
+ const loaded = await loadNodePortableInput(targets);
213
+ if ((loaded.findings || []).some((finding) => finding?.severity === 'error')) return null;
214
+ const decorated = decorateRuntimeSchemaMaterial(loaded, runtime.defaultSchemaSource || {});
215
+ const resolved = await runPortableOperation('resolve-schema-material', { ...decorated, schemaId }, {});
216
+ if (resolved?.status !== 'resolved' || !resolved?.material) return null;
217
+ const material = resolved.material;
218
+ if (String(material.schemaId || '') !== schemaId) return null;
219
+ if (material.qualification?.sourceQualified !== true || material.qualification?.representationIntegrity !== 'verified') return null;
220
+ return material;
221
+ }
222
+
223
+ function decorateRuntimeSchemaMaterial(material = {}, source = {}) {
224
+ const repository = String(source.repository || '');
225
+ const commit = String(source.commit || source.ref || '');
226
+ const sourcePathPrefix = String(source.sourcePathPrefix || '.topics/.schemas').replace(/\/$/, '');
227
+ if (!repository || !commit || !sourcePathPrefix) return material;
228
+ return Object.freeze({
229
+ ...material,
230
+ files: Object.freeze((material.files || []).map((file) => Object.freeze({
231
+ ...file,
232
+ sourceMode: 'portable-bootstrap-canonical-schema',
233
+ source: markPortableBootstrapCanonicalSource({
234
+ providerId: 'bootstrap-canonical-schema-pack',
235
+ repository,
236
+ ref: commit,
237
+ commit,
238
+ path: `${sourcePathPrefix}/${file.path}`,
239
+ authority: 'canonical-core',
240
+ qualification: 'bundled-byte-bound-canonical-snapshot',
241
+ remoteFetch: false,
242
+ cached: false
243
+ })
244
+ })))
245
+ });
246
+ }
247
+
248
+ function exactRuntimeSchemaSourceIdentity(source = {}, materialIdentity = {}) {
249
+ const expected = {
250
+ repository: String(materialIdentity.sourceRepository || ''),
251
+ commit: String(materialIdentity.sourceCommit || ''),
252
+ path: String(materialIdentity.sourcePath || '')
253
+ };
254
+ const observed = {
255
+ repository: String(source.repository || ''),
256
+ commit: String(source.commit || source.ref || ''),
257
+ path: String(source.path || '')
258
+ };
259
+ if (!expected.repository || !expected.commit || !expected.path) return false;
260
+ return expected.repository === observed.repository && expected.commit === observed.commit && normalizeWorkspaceRelativePath(expected.path) === normalizeWorkspaceRelativePath(observed.path);
261
+ }
262
+
263
+ function durableRuntimeSchemaTarget(source = {}, materialIdentity = {}, runtimeSource = {}) {
264
+ const explicitTarget = String(runtimeSource.referenceTarget || '').trim();
265
+ if (explicitTarget) return explicitTarget;
266
+ const workspaceId = String(runtimeSource.workspaceId || '').trim();
267
+ const sourcePath = normalizeWorkspaceRelativePath(materialIdentity.sourcePath || source.path || '');
268
+ if (workspaceId && /^[A-Za-z0-9._-]+$/.test(workspaceId) && sourcePath) return `${workspaceId}::${sourcePath}`;
269
+ return '';
270
+ }
271
+
204
272
  async function allocateArtifactRelativePath({ workspaceRoot, targetDirectory, parentRelativePath, schemaId, title } = {}) {
205
273
  const directory = normalizeWorkspaceRelativePath(targetDirectory || (parentRelativePath ? path.posix.dirname(parentRelativePath) : '.topics')) || '.topics';
206
274
  const existingPaths = await directoryArtifactPaths(workspaceRoot, directory);
@@ -6,6 +6,7 @@ export const PORTABLE_CANONICAL_BOOTSTRAP_ROOT = fileURLToPath(new URL(`./docs-$
6
6
  export const portableCanonicalBootstrapRuntime = Object.freeze({
7
7
  defaultSchemaMaterialPaths: Object.freeze([PORTABLE_CANONICAL_BOOTSTRAP_ROOT]),
8
8
  defaultSchemaSource: Object.freeze({
9
+ workspaceId: 'docs',
9
10
  repository: 'Tiinex/docs',
10
11
  commit: PORTABLE_CANONICAL_BOOTSTRAP_DOCS_COMMIT,
11
12
  sourcePathPrefix: '.topics/.schemas'