@tiinex/core 0.12.0 → 0.13.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 (34) hide show
  1. package/package.json +6 -5
  2. package/src/audit/audit.run.js +1 -1
  3. package/src/public/index.js +18 -0
  4. package/src/public/node.js +1 -0
  5. package/src/schemas/creation.contracts.js +1 -1
  6. package/src/schemas/creation.schemaReferences.js +28 -8
  7. package/src/schemas/schema.reference.js +30 -4
  8. package/src/schemas/tiinex.root.v1.schema.json +2 -1
  9. package/src/tooling/portable/adapters/cli/cli.command-input.js +5 -0
  10. package/src/tooling/portable/adapters/cli/cli.common-output.js +23 -0
  11. package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +5 -1
  12. package/src/tooling/portable/adapters/cli/cli.help.js +15 -2
  13. package/src/tooling/portable/adapters/cli/cli.run.js +1 -1
  14. package/src/tooling/portable/adapters/cli/cli.source-frontier-comparison.js +6 -6
  15. package/src/tooling/portable/adapters/cli/cli.source-frontier-reconciliation.js +18 -0
  16. package/src/tooling/portable/adapters/node/handoff.manufacture.enumeration.js +27 -8
  17. package/src/tooling/portable/adapters/node/handoff.manufacture.js +17 -0
  18. package/src/tooling/portable/adapters/node/sourceFrontierComparison.js +2 -1
  19. package/src/tooling/portable/adapters/node/sourceFrontierReconciliationProof.js +23 -0
  20. package/src/tooling/portable/adapters/node/workspaceCarrier.manufacture.js +1 -0
  21. package/src/tooling/portable/audit/audit.capability.js +2 -1
  22. package/src/tooling/portable/comparison/sourceFrontierComparison.js +54 -4
  23. package/src/tooling/portable/comparison/sourceFrontierReconciliationProof.js +569 -0
  24. package/src/tooling/portable/draft/draft.create.js +3 -0
  25. package/src/tooling/portable/draft/draft.operations.js +1 -1
  26. package/src/tooling/portable/editor/editor.assistance.js +2 -25
  27. package/src/tooling/portable/handoff/manufacture.js +15 -3
  28. package/src/tooling/portable/handoff/pointerEntrypoint.js +4 -1
  29. package/src/tooling/portable/handoff/schemaReferencePreflight.js +26 -0
  30. package/src/tooling/portable/handoff/transportEnvelopeV1.js +5 -0
  31. package/src/tooling/portable/index.js +1 -0
  32. package/src/tooling/portable/operation.catalog.js +8 -0
  33. package/src/tooling/portable/source/sourceEligibility.js +108 -0
  34. package/src/validation/validateArtifact.js +62 -6
@@ -16,7 +16,8 @@ export function auditPortableRecord(record = {}, options = {}) {
16
16
  record,
17
17
  markdown: record.markdown,
18
18
  validationContractOverride: runtimeProjection?.state === 'qualified' ? runtimeProjection.compiledContract : null,
19
- schemaValidationAuthority: requireExactSchemaAuthority ? runtimeAuthority : null
19
+ schemaValidationAuthority: requireExactSchemaAuthority ? runtimeAuthority : null,
20
+ schemaReferenceContext: options.schemaReferenceContext || 'historical'
20
21
  });
21
22
  } catch (error) {
22
23
  const finding = portableFinding('error', 'portable.audit.exception', error?.message || 'Audit failed.', {
@@ -1,5 +1,6 @@
1
1
  import { sha256Hex, utf8Bytes } from '../../../export/package.bytes.js';
2
2
  import { portableFinding, summarizePortableFindings } from '../findings.js';
3
+ import { portableSourceEligibilityPolicy, qualifyPortableSourcePath } from '../source/sourceEligibility.js';
3
4
 
4
5
  export const PORTABLE_SOURCE_FRONTIER_SCHEMA_ID = 'tiinex.portable.source-frontier.v1';
5
6
  export const PORTABLE_SOURCE_FRONTIER_COMPARISON_SCHEMA_ID = 'tiinex.portable.source-frontier-comparison.v1';
@@ -45,16 +46,34 @@ export function createPortableSourceFrontier(input = {}) {
45
46
  workspaces: Object.freeze(workspaces),
46
47
  findings: normalizedFindings,
47
48
  findingSummary: summarizePortableFindings(normalizedFindings),
48
- boundary: String(input.boundary || 'Exact source-byte frontier only. Workspace/path equality does not establish semantic equivalence, authority, acceptance, or merge disposition.')
49
+ boundary: String(input.boundary || 'Eligible durable source-byte frontier only. Source-ineligible transport/runtime/cache bytes are outside frontier identity; Workspace/path equality does not establish semantic equivalence, authority, acceptance, deletion, or merge disposition.')
49
50
  });
50
51
  }
51
52
 
52
53
  export function createPortableWorkspaceSnapshot(entries = [], evidence = {}) {
53
54
  const findings = [];
54
- const normalized = normalizeEntries(entries, findings);
55
+ const selection = normalizeEntries(entries, findings);
55
56
  if (findings.length) return deepFreeze({ state: 'qualification-error', entries: Object.freeze([]), findings: Object.freeze(findings) });
57
+ const normalized = selection.entries;
56
58
  const totalBytes = normalized.reduce((sum, entry) => sum + entry.bytes, 0);
57
59
  const fingerprint = snapshotFingerprint(normalized);
60
+ const inheritedEvidence = serializableObject(evidence);
61
+ const priorEligibility = inheritedEvidence?.sourceEligibility && typeof inheritedEvidence.sourceEligibility === 'object'
62
+ ? inheritedEvidence.sourceEligibility
63
+ : null;
64
+ const upstreamSelection = priorEligibility?.upstreamSelection || (priorEligibility && Number(priorEligibility.excludedEntryCount || 0) > 0 ? portableSourceSelectionReceipt(priorEligibility) : null);
65
+ const sourceEligibility = Object.freeze({
66
+ schema: selection.policy.schema,
67
+ inputEntryCount: selection.inputEntryCount,
68
+ eligibleEntryCount: normalized.length,
69
+ excludedEntryCount: selection.excludedEntryCount,
70
+ excludedByReason: Object.freeze({ ...selection.excludedByReason }),
71
+ excludedDirectories: selection.policy.excludedDirectories,
72
+ excludedRelativePaths: selection.policy.excludedRelativePaths,
73
+ excludedFileSuffixes: selection.policy.excludedFileSuffixes,
74
+ ...(upstreamSelection ? { upstreamSelection: Object.freeze(upstreamSelection) } : {}),
75
+ boundary: selection.policy.boundary
76
+ });
58
77
  return deepFreeze({
59
78
  state: QUALIFIED,
60
79
  entryCount: normalized.length,
@@ -62,7 +81,7 @@ export function createPortableWorkspaceSnapshot(entries = [], evidence = {}) {
62
81
  fingerprint,
63
82
  fingerprintMethod: 'sha256-path-bytes-sha256-v1',
64
83
  entries: Object.freeze(normalized),
65
- evidence: Object.freeze(serializableObject(evidence)),
84
+ evidence: Object.freeze({ ...inheritedEvidence, sourceEligibility }),
66
85
  findings: Object.freeze([])
67
86
  });
68
87
  }
@@ -181,13 +200,28 @@ function normalizeWorkspace(raw, workspaceId, findings) {
181
200
  function normalizeEntries(entries, findings) {
182
201
  const out = [];
183
202
  const seen = new Set();
203
+ const policy = portableSourceEligibilityPolicy();
204
+ const excludedByReason = {};
205
+ let inputEntryCount = 0;
206
+ let excludedEntryCount = 0;
184
207
  for (const raw of entries || []) {
208
+ inputEntryCount += 1;
185
209
  const rawPath = String(raw?.path || raw?.innerPath || '').trim();
186
210
  const path = normalizePath(rawPath);
187
211
  if (unsafeRawPath(rawPath) || !path || unsafePath(path)) {
188
212
  findings.push(portableFinding('error', 'portable.source-frontier.entry.path-invalid', 'Comparable source entry has an unsafe or empty Workspace-relative path.', { path: rawPath }));
189
213
  continue;
190
214
  }
215
+ const eligibility = qualifyPortableSourcePath(path, {
216
+ excludeDirectories: policy.excludedDirectories,
217
+ excludeRelativePaths: policy.excludedRelativePaths,
218
+ entryKind: 'file'
219
+ });
220
+ if (!eligibility.eligible) {
221
+ excludedEntryCount += 1;
222
+ excludedByReason[eligibility.reason] = Number(excludedByReason[eligibility.reason] || 0) + 1;
223
+ continue;
224
+ }
191
225
  if (seen.has(path)) {
192
226
  findings.push(portableFinding('error', 'portable.source-frontier.entry.path-duplicate', 'Comparable source snapshot contains a duplicate normalized path.', { path }));
193
227
  continue;
@@ -202,7 +236,23 @@ function normalizeEntries(entries, findings) {
202
236
  out.push(Object.freeze({ path, bytes, sha256 }));
203
237
  }
204
238
  out.sort((a, b) => a.path.localeCompare(b.path));
205
- return out;
239
+ return Object.freeze({
240
+ entries: Object.freeze(out),
241
+ policy,
242
+ inputEntryCount,
243
+ excludedEntryCount,
244
+ excludedByReason: Object.freeze(Object.fromEntries(Object.entries(excludedByReason).sort(([a], [b]) => a.localeCompare(b))))
245
+ });
246
+ }
247
+
248
+ function portableSourceSelectionReceipt(value = {}) {
249
+ return {
250
+ schema: String(value.schema || ''),
251
+ inputEntryCount: Number(value.inputEntryCount || 0),
252
+ eligibleEntryCount: Number(value.eligibleEntryCount || 0),
253
+ excludedEntryCount: Number(value.excludedEntryCount || 0),
254
+ excludedByReason: Object.freeze({ ...serializableObject(value.excludedByReason || {}) })
255
+ };
206
256
  }
207
257
 
208
258
  function compareWorkspaceUnion(left, right) {