@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.
- package/package.json +6 -5
- package/src/audit/audit.run.js +1 -1
- package/src/public/index.js +18 -0
- package/src/public/node.js +1 -0
- package/src/schemas/creation.contracts.js +1 -1
- package/src/schemas/creation.schemaReferences.js +28 -8
- package/src/schemas/schema.reference.js +30 -4
- package/src/schemas/tiinex.root.v1.schema.json +2 -1
- package/src/tooling/portable/adapters/cli/cli.command-input.js +5 -0
- package/src/tooling/portable/adapters/cli/cli.common-output.js +23 -0
- package/src/tooling/portable/adapters/cli/cli.handoff-manufacture.js +5 -1
- package/src/tooling/portable/adapters/cli/cli.help.js +15 -2
- package/src/tooling/portable/adapters/cli/cli.run.js +1 -1
- package/src/tooling/portable/adapters/cli/cli.source-frontier-comparison.js +6 -6
- package/src/tooling/portable/adapters/cli/cli.source-frontier-reconciliation.js +18 -0
- package/src/tooling/portable/adapters/node/handoff.manufacture.enumeration.js +27 -8
- package/src/tooling/portable/adapters/node/handoff.manufacture.js +17 -0
- package/src/tooling/portable/adapters/node/sourceFrontierComparison.js +2 -1
- package/src/tooling/portable/adapters/node/sourceFrontierReconciliationProof.js +23 -0
- package/src/tooling/portable/adapters/node/workspaceCarrier.manufacture.js +1 -0
- package/src/tooling/portable/audit/audit.capability.js +2 -1
- package/src/tooling/portable/comparison/sourceFrontierComparison.js +54 -4
- package/src/tooling/portable/comparison/sourceFrontierReconciliationProof.js +569 -0
- package/src/tooling/portable/draft/draft.create.js +3 -0
- package/src/tooling/portable/draft/draft.operations.js +1 -1
- package/src/tooling/portable/editor/editor.assistance.js +2 -25
- package/src/tooling/portable/handoff/manufacture.js +15 -3
- package/src/tooling/portable/handoff/pointerEntrypoint.js +4 -1
- package/src/tooling/portable/handoff/schemaReferencePreflight.js +26 -0
- package/src/tooling/portable/handoff/transportEnvelopeV1.js +5 -0
- package/src/tooling/portable/index.js +1 -0
- package/src/tooling/portable/operation.catalog.js +8 -0
- package/src/tooling/portable/source/sourceEligibility.js +108 -0
- 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 || '
|
|
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
|
|
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(
|
|
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
|
|
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) {
|