@tiinex/core 0.30.0 → 0.32.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.30.0",
3
+ "version": "0.32.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,
@@ -173,12 +173,12 @@
173
173
  "type": "git",
174
174
  "url": "git+https://github.com/Tiinex/core.git"
175
175
  },
176
- "gitHead": "5d51273d4c10f8a15367c32bcef8bbce11484ca8",
176
+ "gitHead": "036df699dd3a0455f849c4c4e421fee7c969e85a",
177
177
  "tiinexRelease": {
178
178
  "policy": "tiinex.master-npm-release.v1",
179
- "sourceCommit": "5d51273d4c10f8a15367c32bcef8bbce11484ca8",
180
- "sourceTree": "1372b29b40dbee5e11d2a52d9cac7731f41941a2",
179
+ "sourceCommit": "036df699dd3a0455f849c4c4e421fee7c969e85a",
180
+ "sourceTree": "540c88695f9de86c928a737e1ea2c51b5be5cd82",
181
181
  "repository": "Tiinex/core",
182
- "previousVersion": "0.29.0"
182
+ "previousVersion": "0.31.0"
183
183
  }
184
184
  }
@@ -0,0 +1,120 @@
1
+ export const SCHEMA_LINEAGE_SOURCE_AUTHORITY_QUALIFICATION_SCHEMA_ID = 'tiinex.core.schema-lineage-source-authority-qualification.v1';
2
+
3
+ export function qualifyCompiledSchemaLineageSourceAuthority(validationContract = {}) {
4
+ const lineage = Array.isArray(validationContract?.lineage) ? validationContract.lineage.map((item) => String(item || '').trim()) : [];
5
+ const projected = Array.isArray(validationContract?.lineageAuthority) ? validationContract.lineageAuthority : [];
6
+ const findings = [];
7
+ const edges = [];
8
+
9
+ if (!lineage.length || validationContract?.lineageQualification?.state !== 'valid') {
10
+ findings.push('Compiled validation lineage is unavailable or not valid.');
11
+ }
12
+ if (projected.length !== lineage.length) {
13
+ findings.push(`Compiled validation lineage source authority cardinality is ${projected.length}; expected ${lineage.length}.`);
14
+ }
15
+
16
+ const count = Math.min(projected.length, lineage.length);
17
+ for (let index = 0; index < count; index += 1) {
18
+ const entry = projected[index] || {};
19
+ const expectedSchemaId = lineage[index] || '';
20
+ const actualSchemaId = String(entry?.schemaId || '').trim();
21
+ if (!actualSchemaId || actualSchemaId !== expectedSchemaId) {
22
+ findings.push(`Compiled lineage source authority identity mismatch at index ${index}: expected ${expectedSchemaId || '(missing schema id)'} but observed ${actualSchemaId || '(missing schema id)'}.`);
23
+ }
24
+ }
25
+
26
+ for (let index = 1; index < count; index += 1) {
27
+ const parent = projected[index - 1] || {};
28
+ const child = projected[index] || {};
29
+ const parentSchemaId = String(parent?.schemaId || '').trim();
30
+ const childSchemaId = String(child?.schemaId || '').trim();
31
+ const declaredParentSchemaId = String(child?.parentSchemaId || '').trim();
32
+ const parentSource = normalizeSourceTuple(parent?.source || {});
33
+ const candidates = Object.freeze((Array.isArray(child?.parentSourceCandidates) ? child.parentSourceCandidates : []).map(normalizeSourceTuple));
34
+
35
+ if (!declaredParentSchemaId || declaredParentSchemaId !== parentSchemaId) {
36
+ findings.push(`Compiled lineage identity is incoherent across ${parentSchemaId || '(unknown parent)'} -> ${childSchemaId || '(unknown child)'}.`);
37
+ edges.push(freezeEdge({ state: 'contradictory', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'parent-schema-identity-mismatch' }));
38
+ continue;
39
+ }
40
+
41
+ if (isQualifiedLocalUnpublishedSchemaSource(parent?.source || {})) {
42
+ edges.push(freezeEdge({ state: 'qualified-local-supersession', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'qualified-local-unpublished-parent-authority' }));
43
+ continue;
44
+ }
45
+
46
+ const exactCandidates = candidates.filter(completeSourceTuple);
47
+ if (candidates.length !== 1 || exactCandidates.length !== 1) {
48
+ const reason = candidates.length > 1 ? 'ambiguous-parent-source-authority' : 'parent-source-authority-unavailable';
49
+ findings.push(candidates.length > 1
50
+ ? `Declared parent source authority is ambiguous for ${childSchemaId}: ${candidates.length} exact pinned candidates.`
51
+ : `Declared parent source authority is unavailable for ${childSchemaId} -> ${parentSchemaId}.`);
52
+ edges.push(freezeEdge({ state: 'unresolved', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason }));
53
+ continue;
54
+ }
55
+
56
+ const expected = exactCandidates[0];
57
+ if (!sameSourceTuple(parentSource, expected)) {
58
+ findings.push(`Compiled lineage substitutes source authority for ${childSchemaId} -> ${parentSchemaId}: declared ${formatSource(expected)} but compiled ${formatSource(parentSource)}.`);
59
+ edges.push(freezeEdge({ state: 'contradictory', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'compiled-parent-source-substitution' }));
60
+ continue;
61
+ }
62
+
63
+ edges.push(freezeEdge({ state: 'qualified', parentSchemaId, childSchemaId, actual: parentSource, candidates, reason: 'exact-parent-source-match' }));
64
+ }
65
+
66
+ const contradictory = edges.some((edge) => edge.state === 'contradictory') || findings.some((finding) => finding.includes('identity mismatch') || finding.includes('identity is incoherent') || finding.includes('substitutes source authority'));
67
+ const unresolved = !contradictory && (findings.length > 0 || edges.some((edge) => edge.state === 'unresolved'));
68
+ const state = contradictory ? 'contradictory' : unresolved ? 'unresolved' : 'qualified';
69
+ return deepFreeze({
70
+ schema: SCHEMA_LINEAGE_SOURCE_AUTHORITY_QUALIFICATION_SCHEMA_ID,
71
+ state,
72
+ complete: state === 'qualified',
73
+ lineage: Object.freeze([...lineage]),
74
+ edges: Object.freeze(edges),
75
+ findings: Object.freeze(findings),
76
+ boundary: 'Exact runtime validation authority requires source-coherent compiled inheritance. Qualified local unpublished Parent authority may intentionally supersede published Parent locators; all other inheritance edges require one exact declared Parent source tuple matching the compiled Parent material.'
77
+ });
78
+ }
79
+
80
+ export function isQualifiedLocalUnpublishedSchemaSource(source = {}) {
81
+ return String(source?.publicationState || '').trim().toLowerCase() === 'accepted-local-unpublished'
82
+ && String(source?.snapshotCompleteness || '').trim() === 'exact-axiom-canonical-unpublished-bounded-workspace-contract';
83
+ }
84
+
85
+ function normalizeSourceTuple(value = {}) {
86
+ return Object.freeze({
87
+ repository: String(value?.repository || '').trim(),
88
+ commit: String(value?.commit || '').trim().toLowerCase(),
89
+ path: String(value?.path || '').trim()
90
+ });
91
+ }
92
+
93
+ function completeSourceTuple(value = {}) {
94
+ return Boolean(value.repository && /^[0-9a-f]{40}$/.test(value.commit) && value.path);
95
+ }
96
+
97
+ function sameSourceTuple(left = {}, right = {}) {
98
+ return left.repository === right.repository && left.commit === right.commit && left.path === right.path;
99
+ }
100
+
101
+ function formatSource(value = {}) {
102
+ return `${value.repository || '(unknown repo)'}@${value.commit || '(unknown commit)'}/${value.path || '(unknown path)'}`;
103
+ }
104
+
105
+ function freezeEdge(value = {}) {
106
+ return Object.freeze({
107
+ state: String(value.state || 'unresolved'),
108
+ parentSchemaId: String(value.parentSchemaId || ''),
109
+ childSchemaId: String(value.childSchemaId || ''),
110
+ actual: value.actual || Object.freeze({ repository: '', commit: '', path: '' }),
111
+ candidates: value.candidates || Object.freeze([]),
112
+ reason: String(value.reason || '')
113
+ });
114
+ }
115
+
116
+ function deepFreeze(value) {
117
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
118
+ for (const child of Object.values(value)) deepFreeze(child);
119
+ return Object.freeze(value);
120
+ }
@@ -1,5 +1,6 @@
1
1
  import { sha256Hex, utf8Bytes } from '../export/package.bytes.js';
2
2
  import { qualifyGithubSchemaSourceProvider } from './schema.githubSourceTarget.js';
3
+ import { qualifyCompiledSchemaLineageSourceAuthority } from './schema.lineageAuthority.js';
3
4
 
4
5
  export const BUNDLED_SCHEMA_SOURCE_SCHEMA_ID = 'tiinex.site.bundled-schema-source.v1';
5
6
  export const SCHEMA_RUNTIME_PROJECTION_SCHEMA_ID = 'tiinex.site.schema-runtime-projection.v1';
@@ -48,6 +49,7 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
48
49
  ...(!loadedBlobSha ? ['Loaded schema Git-blob identity is unavailable from the runtime projection.'] : [])
49
50
  ])
50
51
  });
52
+ const validationLineageAuthority = qualifyCompiledSchemaLineageSourceAuthority(runtimeProjection.validationContract || {});
51
53
  const validationContract = projectionExact && runtimeProjection.validationContract?.schemaId === schemaId && runtimeProjection.validationContract?.lineageQualification?.state === 'valid'
52
54
  ? runtimeProjection.validationContract
53
55
  : null;
@@ -85,6 +87,7 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
85
87
  authority,
86
88
  bindingMaterialCoherence,
87
89
  materialIdentity,
90
+ validationLineageAuthority,
88
91
  compiledContract,
89
92
  projection: runtimeProjection,
90
93
  findings: Object.freeze([
@@ -93,7 +96,8 @@ export function defineBundledSchemaSource(binding = {}, projection = {}, options
93
96
  ...(runtimeProjection.sourceChecksum !== expectedChecksum ? ['Schema runtime projection source checksum does not match binding.'] : []),
94
97
  ...(runtimeProjection.bindingChecksum !== expectedChecksum ? ['Schema runtime projection binding checksum does not match binding.'] : []),
95
98
  ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.schemaId !== schemaId ? ['Schema runtime validation projection identity does not match binding.'] : []),
96
- ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.lineageQualification?.state !== 'valid' ? ['Schema runtime validation projection lineage is not exact/valid.'] : [])
99
+ ...(runtimeProjection.validationContract && runtimeProjection.validationContract?.lineageQualification?.state !== 'valid' ? ['Schema runtime validation projection lineage is not exact/valid.'] : []),
100
+ ...(validationLineageAuthority.state !== 'qualified' ? validationLineageAuthority.findings : [])
97
101
  ])
98
102
  });
99
103
  return cached;
@@ -30,7 +30,26 @@ export function deriveHandoffSiblingAllocation({ parentInspection = null, select
30
30
  workspaceId: String(route.workspaceId || '').trim(),
31
31
  workspaceRelativeHandoffPath: String(route.workspaceRelativeHandoffPath || '').trim()
32
32
  }));
33
- if (!routes.length) return blocked('qualified-parent-route-topology-empty');
33
+ if (!routes.length) {
34
+ const siblingIndex = 1;
35
+ if (explicit && explicit !== siblingIndex) return blocked('explicit-sibling-index-conflicts-with-qualified-pointerless-topology', { expectedSiblingIndex: siblingIndex });
36
+ return freeze({
37
+ state: 'qualified',
38
+ siblingIndex,
39
+ childDimension: parentDimension ? `${String(parentDimension).trim()}-${siblingIndex}` : '',
40
+ allocationMode: 'qualified-parent-pointerless-default',
41
+ explicitOverride: explicit ? 'matched-derived-value' : 'not-supplied',
42
+ reasonCode: '',
43
+ provenance: {
44
+ ...provenanceBase({ parentPackagePath, parentPackageSha256, parentDimension, explicitSiblingIndex: explicit }),
45
+ basis: 'qualified-parent-pointerless-default',
46
+ routeOrdinal: siblingIndex,
47
+ qualifiedRouteCount: 0,
48
+ pointerOrder: []
49
+ },
50
+ boundary: allocationBoundary()
51
+ });
52
+ }
34
53
 
35
54
  const qualified = [];
36
55
  const seenDimensions = new Set();
@@ -2,6 +2,7 @@ import { parseArtifactMarkdown } from '../../../artifacts/artifact.parse.js';
2
2
  import { auditPortableRecord } from '../audit/audit.capability.js';
3
3
  import { classifyParentRecoveryReference } from '../../../lineage/parentRecoveryReference.js';
4
4
  import { buildArtifactCreationContract } from '../../../schemas/creation.contracts.js';
5
+ import { canonicalC14nV2SelfState } from '../../../integrity/integrity.c14nV2.js';
5
6
 
6
7
  export const PORTABLE_AUTHORING_PARENT_SCHEMA_ID = 'tiinex.portable.authoring-parent.v1';
7
8
 
@@ -12,8 +13,15 @@ export function projectPortableAuthoringParent(input = {}) {
12
13
  let parsed;
13
14
  try { parsed = parseArtifactMarkdown(record.markdown); }
14
15
  catch { return freeze({ schema: PORTABLE_AUTHORING_PARENT_SCHEMA_ID, status: 'blocked', parentRecord: null, findings: [{ severity: 'error', code: 'portable.authoring-parent.parse-failed', message: 'Selected Parent bytes are not a readable Tiinex artifact.' }], operationBoundary: boundary() }); }
15
- const audit = auditPortableRecord({ ...record, title: parsed.title, schemaId: parsed.envelope?.current?.schema?.id, currentSchemaId: parsed.envelope?.current?.schema?.id, parent: parsed.envelope?.parent });
16
- if (audit.status !== 'readable' || audit.qualification?.exact !== true || (audit.findings || []).some((item) => item.severity === 'error')) return freeze({ schema: PORTABLE_AUTHORING_PARENT_SCHEMA_ID, status: 'blocked', parentRecord: null, findings: [{ severity: 'error', code: 'portable.authoring-parent.unqualified', message: 'Selected Parent must pass exact shared audit before it can be used for native authoring.' }], operationBoundary: boundary() });
16
+ const audit = auditPortableRecord({ ...record, title: parsed.title, schemaId: parsed.envelope?.current?.schema?.id, currentSchemaId: parsed.envelope?.current?.schema?.id, parent: parsed.envelope?.parent }, { requireExactSchemaAuthority: true });
17
+ const auditErrors = (audit.findings || []).filter((item) => item.severity === 'error');
18
+ const historicalParentRecoveryDebt = auditErrors.length > 0 && auditErrors.every((item) => String(item.code || '') === 'root.parent.recovery.workspace-qualified.malformed');
19
+ const selfIntegrity = canonicalC14nV2SelfState(record.markdown || '');
20
+ const directParentUsableWithHistoricalDebt = historicalParentRecoveryDebt
21
+ && audit.qualification?.exact === true
22
+ && audit.schemaValidationAuthority?.state === 'qualified'
23
+ && selfIntegrity.state === 'verified';
24
+ if ((audit.status !== 'readable' && !directParentUsableWithHistoricalDebt) || audit.qualification?.exact !== true || (auditErrors.length && !directParentUsableWithHistoricalDebt)) return freeze({ schema: PORTABLE_AUTHORING_PARENT_SCHEMA_ID, status: 'blocked', parentRecord: null, findings: [{ severity: 'error', code: 'portable.authoring-parent.unqualified', message: 'Selected Parent must pass exact shared audit before it can be used for native authoring.' }], operationBoundary: boundary() });
17
25
  const schemaId = String(parsed.envelope?.current?.schema?.id || audit.schemaId || '');
18
26
  const schemaTarget = String(parsed.envelope?.current?.schema?.target || '');
19
27
  const createdAt = String(parsed.envelope?.current?.createdAt || audit.artifact?.createdAt || '');
@@ -36,9 +44,11 @@ export function projectPortableAuthoringParent(input = {}) {
36
44
  markdown: record.markdown, sourceMode: String(record.sourceMode || 'portable-node-local'),
37
45
  schemaReferenceAuthority
38
46
  },
39
- findings: [],
47
+ findings: directParentUsableWithHistoricalDebt ? [{ severity: 'warning', code: 'portable.authoring-parent.historical-ancestor-recovery-debt', message: 'Selected Parent has historical malformed Workspace-qualified recovery references to its own ancestor. Direct child authoring is allowed from the Parent exact current bytes and verified self integrity; that ancestor debt is not repaired, inherited, or upgraded.' }] : [],
40
48
  operationBoundary: boundary(),
41
- boundary: 'Projects exact supplied Parent bytes and declared current schema locator into shared draft-authoring input. A declared schema locator remains unresolved and is not upgraded to publication or canonical reference authority.'
49
+ boundary: directParentUsableWithHistoricalDebt
50
+ ? 'Projects exact supplied Parent current bytes for direct continuation while preserving unresolved historical ancestor-recovery debt on the Parent itself. The child does not inherit or repair that ancestor locator.'
51
+ : 'Projects exact supplied Parent bytes and declared current schema locator into shared draft-authoring input. A declared schema locator remains unresolved and is not upgraded to publication or canonical reference authority.'
42
52
  });
43
53
  }
44
54
 
@@ -5,6 +5,7 @@ import { integrityMethodReferenceAuthorityForCreation } from '../../../integrity
5
5
  import { inspectPortableLineageIntegrity } from '../lineage/lineage.integrity.plan.js';
6
6
  import { portableFinding } from '../findings.js';
7
7
  import { qualifyTiinexRouteArtifact } from '../handoff/routeArtifactConformance.js';
8
+ import { classifyParentRecoveryReference } from '../../../lineage/parentRecoveryReference.js';
8
9
 
9
10
  export const PORTABLE_EDITOR_ASSISTANCE_SCHEMA_ID = 'tiinex.portable.editor-assistance.v1';
10
11
 
@@ -49,6 +50,28 @@ function projectDocument(record = {}, records = [], lineageInspection = null) {
49
50
  diagnosticCodes: workspacePackagingRepair.diagnosticCodes,
50
51
  boundary: 'Repairs only a tiinex.workspace.v1 artifact whose replacement independently qualifies through the same exact registered Workspace contract and c14n-v2 self-integrity requirements used by Handoff package manufacture. Existing resolver-capable Current Schema references are preserved; permalink refresh is a separate resolution operation and must not be inferred from integrity repair.'
51
52
  }));
53
+ const referenceRepair = deterministicReferenceHygieneRepair(record, audit, markdown);
54
+ const referenceQualification = referenceRepair.state === 'ready'
55
+ ? qualifyReplacementAgainstSharedGuardrails(record, records, referenceRepair.markdown, {
56
+ allowQualifiedExternalParentUnresolved: true,
57
+ allowExistingWarningCodes: (audit.findings || []).filter((item) => item.severity === 'warning').map((item) => String(item.code || ''))
58
+ })
59
+ : { state: 'unavailable' };
60
+ if (referenceRepair.state === 'ready' && referenceRepair.markdown !== markdown && referenceQualification.state === 'qualified') actions.push(freeze({
61
+ id: 'repair-qualified-references-and-self-integrity',
62
+ title: referenceRepair.parentReferenceChanged && referenceRepair.schemaReferenceChanged
63
+ ? 'Repair Tiinex Parent/schema references and self integrity'
64
+ : referenceRepair.parentReferenceChanged
65
+ ? 'Repair Tiinex Parent references and self integrity'
66
+ : 'Repair Tiinex schema reference and self integrity',
67
+ kind: 'replace-document',
68
+ qualification: 'deterministic-shared-core',
69
+ sourceSha256: sha256Hex(new TextEncoder().encode(markdown)),
70
+ replacementMarkdown: referenceRepair.markdown,
71
+ diagnosticCodes: referenceRepair.diagnosticCodes,
72
+ boundary: 'Repairs only deterministically malformed Workspace-qualified Parent recovery locators and/or a bare Current Schema id when exact qualified current-schema source authority exists; reseals self integrity and exposes the replacement only after shared audit and loaded-descendant guardrails re-qualify it. External Parent availability is not invented.'
73
+ }));
74
+
52
75
  const integrityRepair = deterministicIntegrityHygieneRepair(markdown, audit.findings || []);
53
76
  const repairQualification = integrityRepair.state === 'ready'
54
77
  ? qualifyReplacementAgainstSharedGuardrails(record, records, integrityRepair.markdown)
@@ -117,25 +140,119 @@ function deterministicWorkspacePackagingRepair(record = {}, audit = {}, markdown
117
140
  return freeze({ state: 'ready', markdown: candidate, schemaReferenceChanged, diagnosticCodes });
118
141
  }
119
142
 
120
- function qualifyReplacementAgainstSharedGuardrails(record = {}, records = [], replacementMarkdown = '') {
143
+ function qualifyReplacementAgainstSharedGuardrails(record = {}, records = [], replacementMarkdown = '', options = {}) {
121
144
  const focusPath = norm(record.path || record.id || '');
122
145
  if (!focusPath || !replacementMarkdown) return freeze({ state: 'unavailable', reason: 'replacement-or-focus-unavailable' });
123
146
  const replacedRecords = records.map((item) => norm(item.path || item.id || '') === focusPath ? { ...item, markdown: replacementMarkdown } : item);
124
147
  const replacementRecord = replacedRecords.find((item) => norm(item.path || item.id || '') === focusPath);
125
148
  if (!replacementRecord) return freeze({ state: 'unavailable', reason: 'focused-record-unavailable' });
126
149
  const replacementAudit = auditPortableRecord(replacementRecord, { requireExactSchemaAuthority: true });
127
- const auditBlockers = [...(replacementAudit.findings || [])].filter((item) => item.severity === 'error' || item.severity === 'warning');
150
+ const allowedWarnings = new Set((options.allowExistingWarningCodes || []).map((item) => String(item || '')));
151
+ const auditBlockers = [...(replacementAudit.findings || [])].filter((item) => {
152
+ if (item.severity === 'error') return true;
153
+ if (item.severity !== 'warning') return false;
154
+ return !allowedWarnings.has(String(item.code || ''));
155
+ });
128
156
  if (auditBlockers.length) return freeze({ state: 'blocked', reason: 'replacement-shared-audit-not-clean', blockerCodes: auditBlockers.map((item) => String(item.code || '')) });
129
157
 
130
158
  const before = inspectPortableLineageIntegrity({ records });
131
159
  const after = inspectPortableLineageIntegrity({ records: replacedRecords });
132
160
  const beforeFocus = (before.artifacts || []).find((item) => norm(item.path || '') === focusPath);
133
161
  const affectedPaths = new Set([focusPath, ...((beforeFocus?.downstreamDescendants || []).map((item) => norm(item.path || '')).filter(Boolean))]);
134
- const lineageBlockers = (after.artifacts || []).filter((item) => affectedPaths.has(norm(item.path || '')) && item.state !== 'healthy');
162
+ const lineageBlockers = (after.artifacts || []).filter((item) => {
163
+ if (!affectedPaths.has(norm(item.path || '')) || item.state === 'healthy') return false;
164
+ if (options.allowQualifiedExternalParentUnresolved === true && norm(item.path || '') === focusPath && item.state === 'parent-unresolved' && hasQualifiedWorkspaceParentReference(replacementMarkdown)) return false;
165
+ return true;
166
+ });
135
167
  if (lineageBlockers.length) return freeze({ state: 'blocked', reason: 'replacement-shared-lineage-not-clean', blockers: lineageBlockers.map((item) => ({ path: item.path, state: item.state })) });
136
168
  return freeze({ state: 'qualified', affectedPaths: [...affectedPaths] });
137
169
  }
138
170
 
171
+ function deterministicReferenceHygieneRepair(record = {}, audit = {}, markdown = '') {
172
+ const source = String(markdown || '');
173
+ if (!source) return freeze({ state: 'unavailable' });
174
+ let candidate = source;
175
+ let parentReferenceChanged = false;
176
+ let schemaReferenceChanged = false;
177
+ const diagnosticCodes = [];
178
+
179
+ const lines = candidate.replace(/\r\n?/g, '\n').split('\n');
180
+ const parentStart = lines.findIndex((line) => /^\s*-\s+Parent\s*$/.test(line));
181
+ if (parentStart >= 0) {
182
+ let parentEnd = lines.length;
183
+ for (let index = parentStart + 1; index < lines.length; index += 1) {
184
+ if (/^-\s+\S/.test(lines[index])) { parentEnd = index; break; }
185
+ }
186
+ for (let index = parentStart + 1; index < parentEnd; index += 1) {
187
+ lines[index] = lines[index].replace(/\]\(([^)]+::[^)]+)\)/g, (whole, target) => {
188
+ const normalized = normalizeMalformedWorkspaceQualifiedTarget(target);
189
+ if (!normalized || normalized === target) return whole;
190
+ parentReferenceChanged = true;
191
+ return `](${normalized})`;
192
+ });
193
+ }
194
+ }
195
+ if (parentReferenceChanged) {
196
+ candidate = lines.join('\n');
197
+ const integrityLines = candidate.replace(/\r\n?/g, '\n').split('\n');
198
+ const integrityStart = integrityLines.findIndex((line) => line.trim() === '# Continuity Integrity');
199
+ if (integrityStart >= 0) {
200
+ for (let index = integrityStart + 1; index < integrityLines.length; index += 1) {
201
+ integrityLines[index] = integrityLines[index].replace(/\]\(([^)]+::[^)]+)\)/g, (whole, target) => {
202
+ const normalized = normalizeMalformedWorkspaceQualifiedTarget(target);
203
+ return normalized && normalized !== target ? `](${normalized})` : whole;
204
+ });
205
+ }
206
+ candidate = integrityLines.join('\n');
207
+ }
208
+ diagnosticCodes.push('root.parent.recovery.workspace-qualified.malformed', 'portable.lineage-integrity.parent-unresolved');
209
+ }
210
+
211
+ const exactTarget = String(audit?.schemaValidationAuthority?.currentReference?.target || '').trim();
212
+ const schemaId = String(audit?.schemaId || '').trim();
213
+ const schemaWarning = (audit?.findings || []).some((item) => String(item?.code || '') === 'schema.reference.exact-target-omitted');
214
+ if (schemaWarning && schemaId && exactTarget && audit?.schemaValidationAuthority?.currentReference?.state === 'qualified') {
215
+ const schemaLines = candidate.replace(/\r\n?/g, '\n').split('\n');
216
+ const index = schemaLines.findIndex((line) => /^\s*-\s+Current Schema:\s*/.test(line));
217
+ if (index >= 0) {
218
+ const match = schemaLines[index].match(/^(\s*-\s+Current Schema:\s*)([^\s].*)$/);
219
+ const raw = String(match?.[2] || '').trim();
220
+ if (match && raw === schemaId) {
221
+ schemaLines[index] = `${match[1]}[${schemaId}](${exactTarget})`;
222
+ candidate = schemaLines.join('\n');
223
+ schemaReferenceChanged = true;
224
+ diagnosticCodes.push('schema.reference.exact-target-omitted');
225
+ }
226
+ }
227
+ }
228
+
229
+ if (!parentReferenceChanged && !schemaReferenceChanged) return freeze({ state: 'unavailable' });
230
+ const sealed = sealC14nV2Self(candidate);
231
+ if (sealed.state !== 'sealed' && sealed.state !== 'unchanged') return freeze({ state: 'unavailable' });
232
+ return freeze({ state: 'ready', markdown: String(sealed.markdown || candidate), parentReferenceChanged, schemaReferenceChanged, diagnosticCodes: [...new Set(diagnosticCodes)] });
233
+ }
234
+
235
+ function normalizeMalformedWorkspaceQualifiedTarget(value = '') {
236
+ const raw = String(value || '').trim();
237
+ if (classifyParentRecoveryReference(raw).kind !== 'malformed-workspace-qualified') return raw;
238
+ const stripped = raw.replace(/^(?:\.\.\/)+/, '').replace(/^\.\//, '');
239
+ return classifyParentRecoveryReference(stripped).kind === 'workspace-qualified' ? stripped : raw;
240
+ }
241
+
242
+ function hasQualifiedWorkspaceParentReference(markdown = '') {
243
+ const source = String(markdown || '');
244
+ const parentStart = source.split(/\r?\n/).findIndex((line) => /^\s*-\s+Parent\s*$/.test(line));
245
+ if (parentStart < 0) return false;
246
+ const lines = source.split(/\r?\n/);
247
+ let parentEnd = lines.length;
248
+ for (let index = parentStart + 1; index < lines.length; index += 1) if (/^-\s+\S/.test(lines[index])) { parentEnd = index; break; }
249
+ const targets = [];
250
+ for (let index = parentStart + 1; index < parentEnd; index += 1) {
251
+ for (const match of lines[index].matchAll(/\]\(([^)]+)\)/g)) targets.push(String(match[1] || ''));
252
+ }
253
+ return targets.some((target) => classifyParentRecoveryReference(target).kind === 'workspace-qualified');
254
+ }
255
+
139
256
  function projectDiagnostic(finding = {}, markdown = '') {
140
257
  const located = locateFindingLine(finding, markdown);
141
258
  return freeze({
@@ -13,10 +13,19 @@ export function portableRuntimeValidationContractForSchema(schemaId = '', resolu
13
13
  const resolution = resolutionInput || resolveSchemaModule({ schemaId });
14
14
  if (resolution?.fallbackUsed || !resolution?.module) return unavailable('registered-schema-resolution-unavailable', { resolution });
15
15
  const qualification = typeof resolution.module.schemaSource?.qualify === 'function' ? resolution.module.schemaSource.qualify() : null;
16
+ const lineageAuthority = qualification?.validationLineageAuthority || null;
17
+ if (qualification?.state === 'qualified' && lineageAuthority && lineageAuthority.state !== 'qualified') {
18
+ return unavailable('compiled-validation-lineage-source-authority-unqualified', {
19
+ resolution,
20
+ findings: Object.freeze([...(lineageAuthority.findings || [])]),
21
+ lineageAuthority,
22
+ baseQualificationState: String(qualification?.state || 'unavailable')
23
+ });
24
+ }
16
25
  const baseContract = qualification?.state === 'qualified' ? qualification?.compiledContract?.validationContract || null : null;
17
- if (!baseContract) return unavailable(qualification?.state === 'qualified' ? 'compiled-validation-contract-unavailable' : 'schema-source-unqualified', { resolution });
26
+ if (!baseContract) return unavailable(qualification?.state === 'qualified' ? 'compiled-validation-contract-unavailable' : 'schema-source-unqualified', { resolution, findings: Object.freeze([...(qualification?.findings || [])]), baseQualificationState: String(qualification?.state || 'unavailable') });
18
27
  const projected = projectPortableValidationContractWithQualifiedLocalRoot(baseContract);
19
- return deepFreeze({ ...projected, resolution, baseQualificationState: String(qualification?.state || 'unavailable') });
28
+ return deepFreeze({ ...projected, resolution, lineageAuthority, baseQualificationState: String(qualification?.state || 'unavailable') });
20
29
  }
21
30
 
22
31
  export function portableRuntimeValidationAuthorityForRecord(record = {}) {
@@ -26,7 +35,10 @@ export function portableRuntimeValidationAuthorityForRecord(record = {}) {
26
35
  const schemaId = String(declaredSchema.id || record?.schemaId || record?.currentSchemaId || '').trim();
27
36
  const runtime = portableRuntimeValidationContractForSchema(schemaId);
28
37
  if (runtime.state !== 'qualified' || !runtime.compiledContract) {
29
- return unavailableAuthority(schemaId, runtime, ['Registered compiled validation authority is unavailable for the declared Current Schema.']);
38
+ const runtimeFindings = Array.isArray(runtime?.findings) && runtime.findings.length
39
+ ? runtime.findings
40
+ : ['Registered compiled validation authority is unavailable for the declared Current Schema.'];
41
+ return unavailableAuthority(schemaId, runtime, runtimeFindings);
30
42
  }
31
43
 
32
44
  const findings = [];