@shapeshift-labs/frontier-lang-parser 0.3.68 → 0.3.70

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.
@@ -0,0 +1,288 @@
1
+ export function parseGateAdmissionEvidenceBlock(block) {
2
+ const name = nameFrom(block.header);
3
+ const surface = {
4
+ kind: 'frontier.lang.authoredGateAdmissionEvidenceInput',
5
+ version: 1,
6
+ schema: 'frontier.lang.authoredGateAdmissionEvidenceInput.v1',
7
+ id: idFrom(block.header, `gate_admission_${safeId(name)}`),
8
+ name,
9
+ gates: [],
10
+ evidence: [],
11
+ admissions: [],
12
+ proofGaps: [],
13
+ parser: { status: 'authored', errors: [] },
14
+ claims: falseClaims(),
15
+ metadata: { authoredName: name, authoredBlockKind: block.kind }
16
+ };
17
+ for (const authoredLine of readAuthoredLines(block)) {
18
+ const line = authoredLine.text;
19
+ if (!line || line.startsWith('#')) continue;
20
+ const match = /^(gate|evidence|proofEvidence|admission|admissionDecision|gap|proofGap)\s+([A-Za-z_$@/.:*-][\w$./@:*+-]*)(.*)$/.exec(line);
21
+ if (!match) continue;
22
+ const [, rowKind, rowName, text] = match;
23
+ if (rowKind === 'gate') surface.gates.push(gateRecord(rowName, text, authoredLine));
24
+ else if (rowKind === 'evidence' || rowKind === 'proofEvidence') surface.evidence.push(evidenceRecord(rowName, text, authoredLine, rowKind));
25
+ else if (rowKind === 'admission' || rowKind === 'admissionDecision') surface.admissions.push(admissionRecord(rowName, text, authoredLine));
26
+ else surface.proofGaps.push(proofGapRecord(rowName, text, authoredLine));
27
+ }
28
+ surface.gateIds = ids(surface.gates);
29
+ surface.evidenceIds = ids(surface.evidence);
30
+ surface.proofEvidenceIds = surface.evidence.filter((record) => record.proof).map((record) => record.id).filter(Boolean);
31
+ surface.admissionIds = ids(surface.admissions);
32
+ surface.proofGapCodes = uniqueStrings(surface.proofGaps.map((record) => record.code));
33
+ surface.missingEvidence = uniqueStrings([
34
+ ...surface.gates.flatMap((record) => record.missingEvidence ?? []),
35
+ ...surface.admissions.flatMap((record) => record.missingEvidence ?? []),
36
+ ...surface.proofGaps.map((record) => record.code)
37
+ ]);
38
+ surface.summary = {
39
+ gateCount: surface.gates.length,
40
+ evidenceCount: surface.evidence.length,
41
+ proofEvidenceCount: surface.proofEvidenceIds.length,
42
+ admissionCount: surface.admissions.length,
43
+ proofGapCount: surface.proofGaps.length,
44
+ missingEvidenceCount: surface.missingEvidence.length,
45
+ passedGateCount: surface.gates.filter((record) => record.status === 'passed').length,
46
+ failedGateCount: surface.gates.filter((record) => record.status === 'failed').length,
47
+ blockedAdmissionCount: surface.admissions.filter((record) => /blocked|missing|failed|review/.test(record.status ?? '')).length
48
+ };
49
+ return surface;
50
+ }
51
+
52
+ export function mergeGateAdmissionEvidenceBlocks(blocks) {
53
+ const gates = uniqueRecords(blocks.flatMap((block) => block.gates ?? []));
54
+ const evidence = uniqueRecords(blocks.flatMap((block) => block.evidence ?? []));
55
+ const admissions = uniqueRecords(blocks.flatMap((block) => block.admissions ?? []));
56
+ const proofGaps = uniqueRecords(blocks.flatMap((block) => block.proofGaps ?? []));
57
+ const proofEvidenceIds = evidence.filter((record) => record.proof).map((record) => record.id).filter(Boolean);
58
+ const missingEvidence = uniqueStrings([
59
+ ...gates.flatMap((record) => record.missingEvidence ?? []),
60
+ ...admissions.flatMap((record) => record.missingEvidence ?? []),
61
+ ...proofGaps.map((record) => record.code)
62
+ ]);
63
+ return {
64
+ kind: 'frontier.lang.authoredGateAdmissionEvidenceInput',
65
+ version: 1,
66
+ schema: 'frontier.lang.authoredGateAdmissionEvidenceInput.v1',
67
+ id: blocks.length === 1 ? blocks[0].id : 'gateAdmissionEvidence:source',
68
+ blocks,
69
+ blockIds: ids(blocks),
70
+ gates,
71
+ evidence,
72
+ admissions,
73
+ proofGaps,
74
+ gateIds: ids(gates),
75
+ evidenceIds: ids(evidence),
76
+ proofEvidenceIds,
77
+ admissionIds: ids(admissions),
78
+ proofGapCodes: uniqueStrings(proofGaps.map((record) => record.code)),
79
+ missingEvidence,
80
+ summary: {
81
+ blockCount: blocks.length,
82
+ gateCount: gates.length,
83
+ evidenceCount: evidence.length,
84
+ proofEvidenceCount: proofEvidenceIds.length,
85
+ admissionCount: admissions.length,
86
+ proofGapCount: proofGaps.length,
87
+ missingEvidenceCount: missingEvidence.length,
88
+ passedGateCount: gates.filter((record) => record.status === 'passed').length,
89
+ failedGateCount: gates.filter((record) => record.status === 'failed').length,
90
+ blockedAdmissionCount: admissions.filter((record) => /blocked|missing|failed|review/.test(record.status ?? '')).length
91
+ },
92
+ claims: falseClaims(),
93
+ metadata: { authoredGateAdmissionBlockIds: ids(blocks) }
94
+ };
95
+ }
96
+
97
+ function gateRecord(name, text, authoredLine) {
98
+ const evidenceIds = readInlineList(text, 'evidence', 'evidenceIds');
99
+ return cleanRecord({
100
+ kind: 'frontier.lang.gateAdmissionEvidence.gate',
101
+ version: 1,
102
+ id: idFrom(text, `gate_${safeId(name)}`),
103
+ name,
104
+ gateKind: readInlineWord('kind', text) ?? readInlineWord('gateKind', text) ?? 'gate',
105
+ status: readInlineWord('status', text) ?? 'unknown',
106
+ required: readInlineFlag('required', text),
107
+ command: readInlineQuoted('command', text) ?? readInlineWord('command', text),
108
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
109
+ routeIds: readInlineList(text, 'routeIds'),
110
+ language: readInlineWord('language', text) ?? readInlineWord('sourceLanguage', text),
111
+ sourceLanguage: readInlineWord('sourceLanguage', text) ?? readInlineWord('language', text),
112
+ target: readInlineWord('target', text) ?? readInlineWord('targetLanguage', text),
113
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
114
+ sourceHash: readInlineWord('sourceHash', text),
115
+ outputHash: readInlineWord('outputHash', text),
116
+ telemetryHash: readInlineWord('telemetryHash', text),
117
+ subjectIds: readInlineList(text, 'subject', 'subjects', 'subjectId', 'subjectIds'),
118
+ semanticChangeIds: readInlineList(text, 'semanticChange', 'semanticChangeId', 'semanticChangeIds'),
119
+ semanticEditScriptIds: readInlineList(text, 'semanticEditScript', 'semanticEditScriptId', 'semanticEditScriptIds', 'script', 'scriptIds'),
120
+ semanticEditReplayIds: readInlineList(text, 'semanticEditReplay', 'semanticEditReplayId', 'semanticEditReplayIds', 'replay', 'replayIds'),
121
+ evidenceIds,
122
+ proofEvidenceIds: readInlineList(text, 'proofEvidence', 'proofEvidenceIds'),
123
+ missingEvidence: readInlineList(text, 'missingEvidence'),
124
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes'),
125
+ failClosed: true,
126
+ claims: falseClaims(),
127
+ sourceSpan: authoredLine.sourceSpan,
128
+ authoredSourceSpan: authoredLine.sourceSpan,
129
+ metadata: cleanRecord({ authoredName: name, summary: readInlineQuoted('summary', text), ...falseClaims() })
130
+ });
131
+ }
132
+
133
+ function evidenceRecord(name, text, authoredLine, rowKind) {
134
+ return cleanRecord({
135
+ kind: 'frontier.lang.gateAdmissionEvidence.evidence',
136
+ version: 1,
137
+ id: idFrom(text, `evidence_${safeId(name)}`),
138
+ name,
139
+ evidenceKind: readInlineWord('kind', text) ?? 'evidence',
140
+ status: readInlineWord('status', text) ?? 'unknown',
141
+ proof: rowKind === 'proofEvidence' || readInlineFlag('proof', text),
142
+ path: readInlineWord('path', text),
143
+ hash: readInlineWord('hash', text),
144
+ command: readInlineQuoted('command', text) ?? readInlineWord('command', text),
145
+ probeId: readInlineWord('probeId', text) ?? readInlineWord('probe', text),
146
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
147
+ routeIds: readInlineList(text, 'routeIds'),
148
+ language: readInlineWord('language', text) ?? readInlineWord('sourceLanguage', text),
149
+ sourceLanguage: readInlineWord('sourceLanguage', text) ?? readInlineWord('language', text),
150
+ target: readInlineWord('target', text) ?? readInlineWord('targetLanguage', text),
151
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
152
+ sourceHash: readInlineWord('sourceHash', text),
153
+ outputHash: readInlineWord('outputHash', text),
154
+ telemetryHash: readInlineWord('telemetryHash', text),
155
+ gateIds: readInlineList(text, 'gate', 'gateId', 'gateIds'),
156
+ admissionIds: readInlineList(text, 'admission', 'admissionId', 'admissionIds'),
157
+ summary: readInlineQuoted('summary', text),
158
+ failClosed: true,
159
+ autoMergeClaim: false,
160
+ semanticEquivalenceClaim: false,
161
+ runtimeEquivalenceClaim: false,
162
+ sourceSpan: authoredLine.sourceSpan,
163
+ authoredSourceSpan: authoredLine.sourceSpan,
164
+ metadata: cleanRecord({ authoredName: name, authoredRowKind: rowKind, ...falseClaims() })
165
+ });
166
+ }
167
+
168
+ function admissionRecord(name, text, authoredLine) {
169
+ const status = readInlineWord('status', text) ?? readInlineWord('admissionStatus', text) ?? 'review';
170
+ return cleanRecord({
171
+ kind: 'frontier.lang.gateAdmissionEvidence.admission',
172
+ version: 1,
173
+ id: idFrom(text, `admission_${safeId(name)}`),
174
+ name,
175
+ status,
176
+ action: readInlineWord('action', text) ?? readInlineWord('admissionAction', text) ?? 'review',
177
+ readiness: readInlineWord('readiness', text) ?? readInlineWord('admissionReadiness', text),
178
+ decision: readInlineWord('decision', text),
179
+ classification: readInlineWord('classification', text),
180
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
181
+ routeIds: readInlineList(text, 'routeIds'),
182
+ language: readInlineWord('language', text) ?? readInlineWord('sourceLanguage', text),
183
+ sourceLanguage: readInlineWord('sourceLanguage', text) ?? readInlineWord('language', text),
184
+ target: readInlineWord('target', text) ?? readInlineWord('targetLanguage', text),
185
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
186
+ baseHash: readInlineWord('baseHash', text),
187
+ targetHash: readInlineWord('targetHash', text),
188
+ gateIds: readInlineList(text, 'gate', 'gateId', 'gateIds'),
189
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
190
+ proofEvidenceIds: readInlineList(text, 'proofEvidence', 'proofEvidenceIds'),
191
+ missingEvidence: readInlineList(text, 'missingEvidence'),
192
+ conflictKeys: readInlineList(text, 'conflictKey', 'conflictKeys'),
193
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes', 'reason', 'reasons'),
194
+ semanticEditScriptIds: readInlineList(text, 'semanticEditScript', 'semanticEditScriptId', 'semanticEditScriptIds', 'script', 'scriptIds'),
195
+ semanticEditReplayIds: readInlineList(text, 'semanticEditReplay', 'semanticEditReplayId', 'semanticEditReplayIds', 'replay', 'replayIds'),
196
+ reviewRequired: true,
197
+ failClosed: true,
198
+ autoMergeClaim: false,
199
+ semanticEquivalenceClaim: false,
200
+ runtimeEquivalenceClaim: false,
201
+ sourceSpan: authoredLine.sourceSpan,
202
+ authoredSourceSpan: authoredLine.sourceSpan,
203
+ metadata: cleanRecord({ authoredName: name, summary: readInlineQuoted('summary', text), ...falseClaims() })
204
+ });
205
+ }
206
+
207
+ function proofGapRecord(name, text, authoredLine) {
208
+ const code = readInlineWord('code', text) ?? name;
209
+ return cleanRecord({
210
+ kind: 'frontier.lang.gateAdmissionEvidence.proofGap',
211
+ version: 1,
212
+ id: idFrom(text, `gate_admission_gap_${safeId(code)}`),
213
+ name,
214
+ code,
215
+ status: readInlineWord('status', text) ?? 'missing',
216
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
217
+ routeIds: readInlineList(text, 'routeIds'),
218
+ gateIds: readInlineList(text, 'gate', 'gateId', 'gateIds'),
219
+ admissionIds: readInlineList(text, 'admission', 'admissionId', 'admissionIds'),
220
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
221
+ summary: readInlineQuoted('summary', text) ?? readInlineQuoted('message', text),
222
+ failClosed: true,
223
+ ...falseClaims(),
224
+ sourceSpan: authoredLine.sourceSpan,
225
+ authoredSourceSpan: authoredLine.sourceSpan,
226
+ metadata: cleanRecord({ authoredName: name, ...falseClaims() })
227
+ });
228
+ }
229
+
230
+ function readAuthoredLines(block) {
231
+ const lines = block.body.split('\n');
232
+ const records = [];
233
+ let lineStart = block.syntax?.bodyStartOffset ?? 0;
234
+ for (const rawLine of lines) {
235
+ const rawEnd = lineStart + rawLine.length;
236
+ const leading = /^\s*/.exec(rawLine)?.[0].length ?? 0;
237
+ const trailing = /\s*$/.exec(rawLine)?.[0].length ?? 0;
238
+ const startOffset = lineStart + leading;
239
+ const endOffset = Math.max(startOffset, rawEnd - trailing);
240
+ records.push({
241
+ text: rawLine.trim(),
242
+ startOffset,
243
+ endOffset,
244
+ sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined
245
+ });
246
+ lineStart = rawEnd + 1;
247
+ }
248
+ return records;
249
+ }
250
+
251
+ function falseClaims() {
252
+ return {
253
+ autoMergeClaim: false,
254
+ semanticEquivalenceClaim: false,
255
+ runtimeEquivalenceClaim: false,
256
+ gatePassImpliesAdmissionClaim: false
257
+ };
258
+ }
259
+
260
+ function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
261
+ function uniqueRecords(records) {
262
+ const seen = new Set();
263
+ return records.filter((record) => {
264
+ const key = record?.id ?? JSON.stringify(record);
265
+ if (seen.has(key)) return false;
266
+ seen.add(key);
267
+ return true;
268
+ });
269
+ }
270
+ function uniqueStrings(values = []) { return [...new Set(values.filter(Boolean).map(String))]; }
271
+ function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
272
+ function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'GateAdmissionEvidence'; }
273
+ function safeId(value) { return String(value ?? 'record').replace(/[^A-Za-z0-9_$-]+/g, '_'); }
274
+ function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(unquotedText(text))?.[1]?.trim(); }
275
+ function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
276
+ function readInlineFlag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(unquotedText(text)) || undefined; }
277
+ function readInlineList(text, ...labels) {
278
+ const source = unquotedText(text);
279
+ for (const label of labels) {
280
+ const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(source)?.[1]?.trim();
281
+ if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
282
+ }
283
+ return undefined;
284
+ }
285
+ function unquotedText(text) { return text.replace(/"[^"]*"|'[^']*'/g, (match) => ' '.repeat(match.length)); }
286
+ function cleanRecord(record) {
287
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0) && !(value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)));
288
+ }
package/dist/index.js CHANGED
@@ -6,9 +6,11 @@ import { parseApplicationSurfaceBlock } from './application-surface.js';
6
6
  import { parseCanvasSurfaceBlock } from './canvas-surface.js';
7
7
  import { parseDecisionGraphBlock } from './decision-graph.js';
8
8
  import { parseDialectRegistryBlock } from './dialect-registry.js';
9
+ import { parseGateAdmissionEvidenceBlock } from './gate-admission-evidence.js';
9
10
  import { parseInterlinguaBlock } from './interlingua.js';
10
11
  import { createParsedMetadata } from './metadata.js';
11
12
  import { parseEntityBlock, parseStateBlock, readTypeFields } from './member-records.js';
13
+ import { parseSemanticEditRecordsBlock } from './semantic-edit-records.js';
12
14
  import { parseSemanticOperationsBlock } from './operations.js';
13
15
  import { parsePackageManifestBlock } from './package-manifest.js';
14
16
  import { parseParadigmBlock } from './paradigm.js';
@@ -29,9 +31,11 @@ export function parseFrontierSource(source, options = {}) {
29
31
  const proofBlocks = [];
30
32
  const paradigmBlocks = [];
31
33
  const operationBlocks = [];
34
+ const semanticEditBlocks = [];
32
35
  const conversionBlocks = [];
33
36
  const constraintSpaceBlocks = [];
34
37
  const decisionGraphBlocks = [];
38
+ const gateAdmissionEvidenceBlocks = [];
35
39
  const dialectRegistryBlocks = [];
36
40
  const interlinguaBlocks = [];
37
41
  const resourceGraphBlocks = [];
@@ -62,9 +66,11 @@ export function parseFrontierSource(source, options = {}) {
62
66
  if (block.kind === 'proof') proofBlocks.push(parseProofBlock(block));
63
67
  if (block.kind === 'paradigm' || block.kind === 'paradigmSemantics') paradigmBlocks.push(parseParadigmBlock(block));
64
68
  if (block.kind === 'operations' || block.kind === 'semanticOperations') operationBlocks.push(parseSemanticOperationsBlock(block));
69
+ if (block.kind === 'semanticEdits' || block.kind === 'semanticEditRecords') semanticEditBlocks.push(parseSemanticEditRecordsBlock(block));
65
70
  if (block.kind === 'conversion' || block.kind === 'universalConversionPlan') conversionBlocks.push(parseConversionBlock(block));
66
71
  if (block.kind === 'constraintSpace' || block.kind === 'possibilitySpace') constraintSpaceBlocks.push(parseConstraintSpaceBlock(block));
67
72
  if (block.kind === 'decisionGraph' || block.kind === 'admissionGraph') decisionGraphBlocks.push(parseDecisionGraphBlock(block));
73
+ if (block.kind === 'gateEvidence' || block.kind === 'admissionEvidence' || block.kind === 'routeEvidence') gateAdmissionEvidenceBlocks.push(parseGateAdmissionEvidenceBlock(block));
68
74
  if (block.kind === 'dialectRegistry' || block.kind === 'universalDialectRegistry') dialectRegistryBlocks.push(parseDialectRegistryBlock(block));
69
75
  if (block.kind === 'interlingua' || block.kind === 'universalInterlingua') interlinguaBlocks.push(parseInterlinguaBlock(block));
70
76
  if (block.kind === 'resourceGraph' || block.kind === 'semanticResourceGraph') resourceGraphBlocks.push(parseResourceGraphBlock(block));
@@ -73,7 +79,7 @@ export function parseFrontierSource(source, options = {}) {
73
79
  if (block.kind === 'applicationSurface' || block.kind === 'appHost' || block.kind === 'plugin' || block.kind === 'pluginSurface' || block.kind === 'pluginContract') applicationSurfaceBlocks.push(parseApplicationSurfaceBlock(block));
74
80
  if (block.kind === 'runtimeCapabilities' || block.kind === 'runtimeCapabilityMatrix' || block.kind === 'runtimeHosts') runtimeCapabilityBlocks.push(parseRuntimeCapabilityBlock(block));
75
81
  }
76
- const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
82
+ const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, semanticEditBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, gateAdmissionEvidenceBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
77
83
  return createDocument({ id: documentId, name: documentName, nodes, ...(metadata ? { metadata } : {}) });
78
84
  }
79
85
 
package/dist/metadata.js CHANGED
@@ -3,6 +3,8 @@ import { mergeApplicationSurfaceBlocks } from './application-surface.js';
3
3
  import { mergeRuntimeCapabilityBlocks } from './runtime-capability.js';
4
4
  import { mergeTargetProjectionTargets } from './target-projection-aggregate.js';
5
5
  import { mergeConversionBlocks } from './conversion-metadata.js';
6
+ import { mergeSemanticEditBlocks } from './semantic-edit-metadata.js';
7
+ import { mergeGateAdmissionEvidenceBlocks } from './gate-admission-evidence.js';
6
8
 
7
9
  const PROOF_GROUPS = ['contracts', 'refinements', 'invariants', 'termination', 'temporal', 'obligations', 'artifacts', 'assumptions'];
8
10
  const PARADIGM_GROUPS = [
@@ -11,14 +13,16 @@ const PARADIGM_GROUPS = [
11
13
  'clockModels', 'objectModels', 'macroExpansions', 'reflectionBoundaries', 'loweringRecords'
12
14
  ];
13
15
 
14
- export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
16
+ export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], semanticEditBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], gateAdmissionEvidenceBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
15
17
  const metadata = {};
16
18
  if (proofBlocks.length) metadata.proof = mergeProofBlocks(proofBlocks);
17
19
  if (paradigmBlocks.length) metadata.paradigmSemantics = mergeParadigmBlocks(paradigmBlocks);
18
20
  if (operationBlocks.length) metadata.semanticOperations = mergeOperationBlocks(operationBlocks);
21
+ if (semanticEditBlocks.length) metadata.semanticEditRecords = mergeSemanticEditBlocks(semanticEditBlocks);
19
22
  if (conversionBlocks.length) metadata.universalConversionPlan = mergeConversionBlocks(conversionBlocks);
20
23
  if (constraintSpaceBlocks.length) metadata.constraintSpaces = mergeConstraintSpaceBlocks(constraintSpaceBlocks);
21
24
  if (decisionGraphBlocks.length) metadata.decisionGraph = mergeDecisionGraphBlocks(decisionGraphBlocks);
25
+ if (gateAdmissionEvidenceBlocks.length) metadata.gateAdmissionEvidence = mergeGateAdmissionEvidenceBlocks(gateAdmissionEvidenceBlocks);
22
26
  if (dialectRegistryBlocks.length) metadata.dialects = mergeDialectRegistryBlocks(dialectRegistryBlocks);
23
27
  if (interlinguaBlocks.length) metadata.universalInterlingua = mergeInterlinguaBlocks(interlinguaBlocks);
24
28
  if (resourceGraphBlocks.length) metadata.semanticResourceGraphs = mergeResourceGraphBlocks(resourceGraphBlocks);
@@ -0,0 +1,51 @@
1
+ export function mergeSemanticEditBlocks(blocks) {
2
+ const scripts = blocks.flatMap((block) => block.scripts ?? []);
3
+ const projections = blocks.flatMap((block) => block.projections ?? []);
4
+ const replays = blocks.flatMap((block) => block.replays ?? []);
5
+ return {
6
+ id: blocks.length === 1 ? blocks[0].id : 'semanticEditRecords:source',
7
+ scripts,
8
+ projections,
9
+ replays,
10
+ scriptIds: ids(scripts),
11
+ projectionIds: ids(projections),
12
+ replayIds: ids(replays),
13
+ evidenceIds: uniqueStrings([
14
+ ...scripts.flatMap((record) => record.evidenceIds ?? []),
15
+ ...projections.flatMap((record) => record.evidenceIds ?? []),
16
+ ...replays.flatMap((record) => record.evidenceIds ?? [])
17
+ ]),
18
+ operationIds: uniqueStrings([
19
+ ...scripts.flatMap((record) => (record.operations ?? []).map((operation) => operation.id)),
20
+ ...projections.flatMap((record) => (record.edits ?? []).map((edit) => edit.operationId)),
21
+ ...replays.flatMap((record) => (record.edits ?? []).map((edit) => edit.operationId)),
22
+ ...replays.flatMap((record) => record.appliedOperations ?? []),
23
+ ...replays.flatMap((record) => record.skippedOperations ?? [])
24
+ ]),
25
+ sourceMapIds: uniqueStrings([
26
+ ...scripts.flatMap((record) => record.sourceMapIds ?? []),
27
+ ...projections.flatMap((record) => record.sourceMapIds ?? [])
28
+ ]),
29
+ sourceMapLinkIds: uniqueStrings([
30
+ ...scripts.flatMap((record) => record.sourceMapLinkIds ?? []),
31
+ ...projections.flatMap((record) => record.sourceMapLinkIds ?? [])
32
+ ]),
33
+ sourceMapMappingIds: uniqueStrings([
34
+ ...scripts.flatMap((record) => record.sourceMapMappingIds ?? []),
35
+ ...projections.flatMap((record) => record.sourceMapMappingIds ?? [])
36
+ ]),
37
+ summary: {
38
+ scriptCount: scripts.length,
39
+ projectionCount: projections.length,
40
+ replayCount: replays.length,
41
+ operationCount: scripts.reduce((sum, record) => sum + (record.operations?.length ?? 0), 0),
42
+ projectionEditCount: projections.reduce((sum, record) => sum + (record.edits?.length ?? 0), 0),
43
+ replayEditCount: replays.reduce((sum, record) => sum + (record.edits?.length ?? 0), 0)
44
+ },
45
+ claims: { autoMergeClaim: false, semanticEquivalenceClaim: false },
46
+ metadata: { authoredSemanticEditBlockIds: blocks.map((block) => block.id) }
47
+ };
48
+ }
49
+
50
+ function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
51
+ function uniqueStrings(values = []) { return [...new Set(values.filter(Boolean).map(String))]; }
@@ -0,0 +1,320 @@
1
+ export function parseSemanticEditRecordsBlock(block) {
2
+ const name = nameFrom(block.header);
3
+ const recordSet = {
4
+ id: idFrom(block.header, `semanticEditRecords_${name}`),
5
+ scripts: [],
6
+ projections: [],
7
+ replays: [],
8
+ metadata: { name }
9
+ };
10
+ for (const authoredLine of readAuthoredLines(block)) {
11
+ const line = authoredLine.text;
12
+ if (!line || line.startsWith('#')) continue;
13
+ const match = /^(script|semanticEditScript|projection|semanticEditProjection|replay|semanticEditReplay)\s+([A-Za-z_$][\w$-]*)(.*)$/.exec(line);
14
+ if (!match) continue;
15
+ const [, kind, rowName, text] = match;
16
+ if (kind === 'script' || kind === 'semanticEditScript') {
17
+ recordSet.scripts.push(parseSemanticEditScript(rowName, text, authoredLine));
18
+ } else if (kind === 'projection' || kind === 'semanticEditProjection') {
19
+ recordSet.projections.push(parseSemanticEditProjection(rowName, text, authoredLine));
20
+ } else {
21
+ recordSet.replays.push(parseSemanticEditReplay(rowName, text, authoredLine));
22
+ }
23
+ }
24
+ return recordSet;
25
+ }
26
+
27
+ function parseSemanticEditScript(name, text, authoredLine) {
28
+ const operation = semanticEditOperationRecord(text, authoredLine);
29
+ const status = readInlineWord('status', text) ?? readInlineWord('admissionStatus', text) ?? 'evidence-only';
30
+ const sourceBackprojectionMode = readInlineWord('sourceBackprojection', text) ?? readInlineWord('sourceBackprojectionMode', text);
31
+ const evidenceIds = readInlineList(text, 'evidence', 'evidenceIds');
32
+ return cleanRecord({
33
+ kind: 'frontier.lang.semanticEditScript',
34
+ version: 1,
35
+ schema: 'frontier.lang.semanticEditScript.v1',
36
+ id: idFrom(text, `semantic_edit_script_${name}`),
37
+ stableId: readInlineWord('stableId', text),
38
+ hash: readInlineWord('hash', text) ?? readInlineWord('editScriptHash', text) ?? readInlineWord('scriptHash', text),
39
+ name,
40
+ language: readInlineWord('language', text),
41
+ target: readInlineWord('target', text),
42
+ targetLanguage: readInlineWord('targetLanguage', text),
43
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
44
+ targetPath: readInlineWord('targetPath', text),
45
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
46
+ routeIds: readInlineList(text, 'routeIds'),
47
+ baseHash: readInlineWord('baseHash', text),
48
+ workerHash: readInlineWord('workerHash', text),
49
+ headHash: readInlineWord('headHash', text),
50
+ workerChangeSetId: readInlineWord('workerChangeSet', text) ?? readInlineWord('workerChangeSetId', text),
51
+ headChangeSetId: readInlineWord('headChangeSet', text) ?? readInlineWord('headChangeSetId', text),
52
+ lineageInferenceId: readInlineWord('lineageInference', text) ?? readInlineWord('lineageInferenceId', text),
53
+ operations: operation ? [operation] : [],
54
+ summary: cleanRecord({ operations: operation ? 1 : 0, status }),
55
+ admission: semanticEditAdmission(status, readInlineWord('action', text) ?? readInlineWord('admissionAction', text), text, evidenceIds),
56
+ evidence: evidenceIds?.map((id) => ({ id })),
57
+ evidenceIds,
58
+ sourceMapIds: readInlineList(text, 'sourceMap', 'sourceMaps', 'sourceMapIds'),
59
+ sourceMapLinkIds: readInlineList(text, 'sourceMapLink', 'sourceMapLinks', 'sourceMapLinkIds'),
60
+ sourceMapMappingIds: readInlineList(text, 'sourceMapMapping', 'sourceMapMappings', 'sourceMapMappingIds'),
61
+ sourceSpan: authoredLine.sourceSpan,
62
+ authoredSourceSpan: authoredLine.sourceSpan,
63
+ metadata: cleanRecord({
64
+ autoMergeClaim: false,
65
+ semanticEquivalenceClaim: false,
66
+ sourceBackprojectionMode,
67
+ sourceBackprojection: sourceBackprojectionMode ? { mode: sourceBackprojectionMode } : undefined,
68
+ authoredSourceSpan: authoredLine.sourceSpan,
69
+ summary: readInlineQuoted('summary', text)
70
+ })
71
+ });
72
+ }
73
+
74
+ function parseSemanticEditProjection(name, text, authoredLine) {
75
+ const edit = semanticEditProjectionEditRecord(text, authoredLine);
76
+ const status = readInlineWord('status', text) ?? 'blocked';
77
+ const evidenceIds = readInlineList(text, 'evidence', 'evidenceIds');
78
+ return cleanRecord({
79
+ kind: 'frontier.lang.semanticEditProjection',
80
+ version: 1,
81
+ schema: 'frontier.lang.semanticEditProjection.v1',
82
+ id: idFrom(text, `semantic_edit_projection_${name}`),
83
+ hash: readInlineWord('hash', text) ?? readInlineWord('projectionHash', text),
84
+ name,
85
+ scriptId: readInlineWord('script', text) ?? readInlineWord('scriptId', text) ?? readInlineWord('semanticEditScript', text) ?? readInlineWord('semanticEditScriptId', text),
86
+ language: readInlineWord('language', text),
87
+ target: readInlineWord('target', text),
88
+ targetLanguage: readInlineWord('targetLanguage', text),
89
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
90
+ targetPath: readInlineWord('targetPath', text),
91
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
92
+ routeIds: readInlineList(text, 'routeIds'),
93
+ status,
94
+ baseHash: readInlineWord('baseHash', text),
95
+ workerHash: readInlineWord('workerHash', text),
96
+ headHash: readInlineWord('headHash', text),
97
+ projectedHash: readInlineWord('projectedHash', text) ?? readInlineWord('targetHash', text),
98
+ appliedOperations: edit?.operationId ? [edit.operationId] : [],
99
+ skippedOperations: [],
100
+ edits: edit ? [edit] : [],
101
+ admission: {
102
+ status: readInlineWord('admissionStatus', text) ?? (status === 'projected' ? 'auto-merge-candidate' : 'blocked'),
103
+ autoMergeClaim: false,
104
+ semanticEquivalenceClaim: false,
105
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes') ?? []
106
+ },
107
+ evidenceIds,
108
+ sourceMapIds: readInlineList(text, 'sourceMap', 'sourceMaps', 'sourceMapIds'),
109
+ sourceMapLinkIds: readInlineList(text, 'sourceMapLink', 'sourceMapLinks', 'sourceMapLinkIds'),
110
+ sourceMapMappingIds: readInlineList(text, 'sourceMapMapping', 'sourceMapMappings', 'sourceMapMappingIds'),
111
+ sourceSpan: authoredLine.sourceSpan,
112
+ authoredSourceSpan: authoredLine.sourceSpan,
113
+ metadata: cleanRecord({
114
+ autoMergeClaim: false,
115
+ semanticEquivalenceClaim: false,
116
+ sourceBackprojectionMode: readInlineWord('sourceBackprojection', text) ?? readInlineWord('sourceBackprojectionMode', text),
117
+ authoredSourceSpan: authoredLine.sourceSpan,
118
+ summary: readInlineQuoted('summary', text)
119
+ })
120
+ });
121
+ }
122
+
123
+ function parseSemanticEditReplay(name, text, authoredLine) {
124
+ const edit = semanticEditReplayEditRecord(text, authoredLine);
125
+ const status = readInlineWord('status', text) ?? readInlineWord('replayStatus', text) ?? 'blocked';
126
+ const action = readInlineWord('action', text) ?? readInlineWord('replayAction', text) ?? readInlineWord('admissionAction', text) ?? 'human-review';
127
+ const reasonCodes = readInlineList(text, 'reasonCode', 'reasonCodes') ?? [];
128
+ const evidenceIds = readInlineList(text, 'evidence', 'evidenceIds');
129
+ const applied = edit && (status === 'accepted-clean' || status === 'already-applied' || action === 'apply') ? [edit.operationId].filter(Boolean) : [];
130
+ const skipped = edit && !applied.length ? [edit.operationId].filter(Boolean) : [];
131
+ return cleanRecord({
132
+ kind: 'frontier.lang.semanticEditReplay',
133
+ version: 1,
134
+ schema: 'frontier.lang.semanticEditReplay.v1',
135
+ id: idFrom(text, `semantic_edit_replay_${name}`),
136
+ hash: readInlineWord('hash', text) ?? readInlineWord('replayHash', text),
137
+ name,
138
+ projectionId: readInlineWord('projection', text) ?? readInlineWord('projectionId', text) ?? readInlineWord('semanticEditProjection', text) ?? readInlineWord('semanticEditProjectionId', text),
139
+ scriptId: readInlineWord('script', text) ?? readInlineWord('scriptId', text) ?? readInlineWord('semanticEditScript', text) ?? readInlineWord('semanticEditScriptId', text),
140
+ language: readInlineWord('language', text),
141
+ target: readInlineWord('target', text),
142
+ targetLanguage: readInlineWord('targetLanguage', text),
143
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
144
+ targetPath: readInlineWord('targetPath', text),
145
+ routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
146
+ routeIds: readInlineList(text, 'routeIds'),
147
+ currentHash: readInlineWord('currentHash', text) ?? readInlineWord('replayCurrentHash', text),
148
+ projectedHash: readInlineWord('projectedHash', text) ?? readInlineWord('targetHash', text),
149
+ outputHash: readInlineWord('outputHash', text) ?? readInlineWord('replayOutputHash', text),
150
+ status,
151
+ edits: edit ? [edit] : [],
152
+ appliedOperations: applied,
153
+ skippedOperations: skipped,
154
+ admission: {
155
+ status,
156
+ action,
157
+ reviewRequired: true,
158
+ autoApplyCandidate: false,
159
+ autoMergeClaim: false,
160
+ semanticEquivalenceClaim: false,
161
+ reasonCodes
162
+ },
163
+ summary: replaySummary(edit, status, reasonCodes),
164
+ evidenceIds,
165
+ sourceSpan: authoredLine.sourceSpan,
166
+ authoredSourceSpan: authoredLine.sourceSpan,
167
+ metadata: cleanRecord({
168
+ autoMergeClaim: false,
169
+ semanticEquivalenceClaim: false,
170
+ sourceBackprojectionMode: readInlineWord('sourceBackprojection', text) ?? readInlineWord('sourceBackprojectionMode', text),
171
+ authoredSourceSpan: authoredLine.sourceSpan,
172
+ summary: readInlineQuoted('summary', text)
173
+ })
174
+ });
175
+ }
176
+
177
+ function semanticEditOperationRecord(text, authoredLine) {
178
+ const operationId = readInlineWord('operation', text) ?? readInlineWord('operationId', text) ?? readInlineWord('op', text);
179
+ if (!operationId) return undefined;
180
+ const sourceBackprojectionMode = readInlineWord('sourceBackprojection', text) ?? readInlineWord('sourceBackprojectionMode', text);
181
+ return cleanRecord({
182
+ id: operationId,
183
+ kind: readInlineWord('operationKind', text) ?? readInlineWord('kind', text),
184
+ changeKind: readInlineWord('changeKind', text),
185
+ semanticKey: readInlineWord('semanticKey', text),
186
+ semanticIdentityHash: readInlineWord('semanticIdentityHash', text),
187
+ sourceIdentityHash: readInlineWord('sourceIdentityHash', text),
188
+ operationContentHash: readInlineWord('operationContentHash', text),
189
+ editContentHash: readInlineWord('editContentHash', text),
190
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
191
+ symbolId: readInlineWord('symbolId', text),
192
+ symbolName: readInlineWord('symbolName', text),
193
+ symbolKind: readInlineWord('symbolKind', text),
194
+ anchor: cleanRecord({
195
+ key: readInlineWord('anchorKey', text) ?? readInlineWord('ownerKey', text) ?? readInlineWord('ownershipKey', text) ?? readInlineWord('semanticKey', text),
196
+ conflictKey: readInlineWord('conflictKey', text),
197
+ regionId: readInlineWord('region', text) ?? readInlineWord('regionId', text),
198
+ regionKind: readInlineWord('regionKind', text),
199
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
200
+ symbolId: readInlineWord('symbolId', text),
201
+ symbolName: readInlineWord('symbolName', text),
202
+ symbolKind: readInlineWord('symbolKind', text)
203
+ }),
204
+ evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
205
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes'),
206
+ sourceSpan: authoredLine.sourceSpan,
207
+ authoredSourceSpan: authoredLine.sourceSpan,
208
+ metadata: cleanRecord({
209
+ autoMergeClaim: false,
210
+ semanticEquivalenceClaim: false,
211
+ sourceBackprojection: sourceBackprojectionMode ? { mode: sourceBackprojectionMode } : undefined
212
+ })
213
+ });
214
+ }
215
+
216
+ function semanticEditProjectionEditRecord(text, authoredLine) {
217
+ const operationId = readInlineWord('edit', text) ?? readInlineWord('operation', text) ?? readInlineWord('operationId', text);
218
+ if (!operationId) return undefined;
219
+ return cleanRecord({
220
+ operationId,
221
+ status: readInlineWord('editStatus', text) ?? 'applied',
222
+ kind: readInlineWord('kind', text),
223
+ editKind: readInlineWord('editKind', text),
224
+ changeKind: readInlineWord('changeKind', text),
225
+ anchorKey: readInlineWord('anchorKey', text) ?? readInlineWord('ownerKey', text) ?? readInlineWord('semanticKey', text),
226
+ conflictKey: readInlineWord('conflictKey', text),
227
+ regionId: readInlineWord('region', text) ?? readInlineWord('regionId', text),
228
+ regionKind: readInlineWord('regionKind', text),
229
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
230
+ targetSourcePath: readInlineWord('targetPath', text),
231
+ symbolId: readInlineWord('symbolId', text),
232
+ symbolName: readInlineWord('symbolName', text),
233
+ symbolKind: readInlineWord('symbolKind', text),
234
+ semanticKey: readInlineWord('semanticKey', text),
235
+ semanticIdentityHash: readInlineWord('semanticIdentityHash', text),
236
+ sourceIdentityHash: readInlineWord('sourceIdentityHash', text),
237
+ operationContentHash: readInlineWord('operationContentHash', text),
238
+ editContentHash: readInlineWord('editContentHash', text),
239
+ sourceSpan: authoredLine.sourceSpan,
240
+ authoredSourceSpan: authoredLine.sourceSpan,
241
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes')
242
+ });
243
+ }
244
+
245
+ function semanticEditReplayEditRecord(text, authoredLine) {
246
+ const operationId = readInlineWord('edit', text) ?? readInlineWord('operation', text) ?? readInlineWord('operationId', text);
247
+ if (!operationId) return undefined;
248
+ return cleanRecord({
249
+ operationId,
250
+ status: readInlineWord('editStatus', text) ?? readInlineWord('status', text) ?? 'blocked',
251
+ semanticKey: readInlineWord('semanticKey', text),
252
+ semanticIdentityHash: readInlineWord('semanticIdentityHash', text),
253
+ sourceIdentityHash: readInlineWord('sourceIdentityHash', text),
254
+ operationContentHash: readInlineWord('operationContentHash', text),
255
+ editContentHash: readInlineWord('editContentHash', text),
256
+ editKind: readInlineWord('editKind', text),
257
+ sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
258
+ symbolName: readInlineWord('symbolName', text),
259
+ symbolKind: readInlineWord('symbolKind', text),
260
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes') ?? [],
261
+ sourceSpan: authoredLine.sourceSpan,
262
+ authoredSourceSpan: authoredLine.sourceSpan
263
+ });
264
+ }
265
+
266
+ function semanticEditAdmission(status, action, text, evidenceIds = []) {
267
+ return {
268
+ status,
269
+ action: action ?? 'record-evidence',
270
+ reviewRequired: true,
271
+ autoApplyCandidate: false,
272
+ autoMergeClaim: false,
273
+ semanticEquivalenceClaim: false,
274
+ reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes') ?? [],
275
+ conflictKeys: readInlineList(text, 'conflictKey', 'conflictKeys') ?? [],
276
+ evidenceIds
277
+ };
278
+ }
279
+
280
+ function replaySummary(edit, status, reasonCodes) {
281
+ return { edits: edit ? 1 : 0, applied: status === 'accepted-clean' ? 1 : 0, alreadyApplied: status === 'already-applied' ? 1 : 0, conflicts: status === 'conflict' ? 1 : 0, stale: status === 'stale' ? 1 : 0, blocked: status === 'blocked' ? 1 : 0, reasonCodes };
282
+ }
283
+
284
+ function readAuthoredLines(block) {
285
+ const lines = block.body.split('\n');
286
+ const records = [];
287
+ let lineStart = block.syntax?.bodyStartOffset ?? 0;
288
+ for (const rawLine of lines) {
289
+ const rawEnd = lineStart + rawLine.length;
290
+ const leading = /^\s*/.exec(rawLine)?.[0].length ?? 0;
291
+ const trailing = /\s*$/.exec(rawLine)?.[0].length ?? 0;
292
+ const startOffset = lineStart + leading;
293
+ const endOffset = Math.max(startOffset, rawEnd - trailing);
294
+ records.push({
295
+ text: rawLine.trim(),
296
+ startOffset,
297
+ endOffset,
298
+ sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined
299
+ });
300
+ lineStart = rawEnd + 1;
301
+ }
302
+ return records;
303
+ }
304
+
305
+ function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
306
+ function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'SemanticEditRecords'; }
307
+ function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(unquotedText(text))?.[1]?.trim(); }
308
+ function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
309
+ function readInlineList(text, ...labels) {
310
+ const source = unquotedText(text);
311
+ for (const label of labels) {
312
+ const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(source)?.[1]?.trim();
313
+ if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
314
+ }
315
+ return undefined;
316
+ }
317
+ function unquotedText(text) { return text.replace(/"[^"]*"|'[^']*'/g, (match) => ' '.repeat(match.length)); }
318
+ function cleanRecord(record) {
319
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0) && !(value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)));
320
+ }
@@ -16,12 +16,17 @@ export const FrontierSourceBlockKinds = Object.freeze([
16
16
  'paradigmSemantics',
17
17
  'operations',
18
18
  'semanticOperations',
19
+ 'semanticEdits',
20
+ 'semanticEditRecords',
19
21
  'conversion',
20
22
  'universalConversionPlan',
21
23
  'constraintSpace',
22
24
  'possibilitySpace',
23
25
  'decisionGraph',
24
26
  'admissionGraph',
27
+ 'gateEvidence',
28
+ 'admissionEvidence',
29
+ 'routeEvidence',
25
30
  'dialectRegistry',
26
31
  'universalDialectRegistry',
27
32
  'interlingua',
@@ -5,6 +5,8 @@ const dialectRows = words('dialect record extern');
5
5
  const interlinguaRows = words('layer constraint edge obligation proofObligation proof lowering lower source sourceLift lift evidence');
6
6
  const packageRows = words('metadata dependency script export gap proofGap evidence proofEvidence');
7
7
  const runtimeRows = words('host runtimeHost hostProfile sourceHost targetHost capability hostCapability hostBinding binding requirement runtimeRequirement requiredRuntime evidence proofEvidence gap proofGap');
8
+ const semanticEditRows = words('script semanticEditScript projection semanticEditProjection replay semanticEditReplay');
9
+ const gateAdmissionRows = words('gate evidence proofEvidence admission admissionDecision gap proofGap');
8
10
 
9
11
  export const ROW_SYNTAX_CONFIG = Object.freeze({
10
12
  interlingua: rowConfig('interlinguaRow', 'interlingua_row', interlinguaRows, normalizeInterlinguaRow),
@@ -31,8 +33,13 @@ export const ROW_SYNTAX_CONFIG = Object.freeze({
31
33
  possibilitySpace: rowConfig('constraintSpaceRow', 'constraint_space_row', constraintRows, normalizeConstraintSpaceRow),
32
34
  decisionGraph: rowConfig('decisionGraphRow', 'decision_graph_row', words('node edge chunk gate evidence semanticChange change patchEvent patch admissionDecision admission candidateDecision candidate mergeDecision merge replay tournament tournamentCandidate panelProjection panel rsiLoop improvementFeedback feedback'), normalizeDecisionGraphRow),
33
35
  admissionGraph: rowConfig('decisionGraphRow', 'decision_graph_row', words('node edge chunk gate evidence semanticChange change patchEvent patch admissionDecision admission candidateDecision candidate mergeDecision merge replay tournament tournamentCandidate panelProjection panel rsiLoop improvementFeedback feedback'), normalizeDecisionGraphRow),
36
+ gateEvidence: rowConfig('gateAdmissionEvidenceRow', 'gate_admission_evidence_row', gateAdmissionRows, normalizeGateAdmissionRow),
37
+ admissionEvidence: rowConfig('gateAdmissionEvidenceRow', 'gate_admission_evidence_row', gateAdmissionRows, normalizeGateAdmissionRow),
38
+ routeEvidence: rowConfig('gateAdmissionEvidenceRow', 'gate_admission_evidence_row', gateAdmissionRows, normalizeGateAdmissionRow),
34
39
  operations: rowConfig('semanticOperationRow', 'semantic_operation_row', words('operation op'), normalizeOperationRow),
35
40
  semanticOperations: rowConfig('semanticOperationRow', 'semantic_operation_row', words('operation op'), normalizeOperationRow),
41
+ semanticEdits: rowConfig('semanticEditRecordRow', 'semantic_edit_record_row', semanticEditRows, normalizeSemanticEditRow),
42
+ semanticEditRecords: rowConfig('semanticEditRecordRow', 'semantic_edit_record_row', semanticEditRows, normalizeSemanticEditRow),
36
43
  paradigm: rowConfig('paradigmRow', 'paradigm_row', words('valueSemantics mutationModel effectModel ownership ownershipModel lifetime lifetimeModel bindingScope binding dispatch typeModel moduleModel concurrency errorModel memoryModel evaluation metaprogramming interop lowering'), normalizeParadigmRow),
37
44
  paradigmSemantics: rowConfig('paradigmRow', 'paradigm_row', words('valueSemantics mutationModel effectModel ownership ownershipModel lifetime lifetimeModel bindingScope binding dispatch typeModel moduleModel concurrency errorModel memoryModel evaluation metaprogramming interop lowering'), normalizeParadigmRow),
38
45
  proof: rowConfig('proofRow', 'proof_row', words('contract refinement invariant termination temporal obligation artifact assumption')),
@@ -118,6 +125,20 @@ function normalizeOperationRow(rowKind) {
118
125
  return rowKind;
119
126
  }
120
127
 
128
+ function normalizeSemanticEditRow(rowKind) {
129
+ if (rowKind === 'semanticEditScript') return 'script';
130
+ if (rowKind === 'semanticEditProjection') return 'projection';
131
+ if (rowKind === 'semanticEditReplay') return 'replay';
132
+ return rowKind;
133
+ }
134
+
135
+ function normalizeGateAdmissionRow(rowKind) {
136
+ if (rowKind === 'proofEvidence') return 'evidence';
137
+ if (rowKind === 'admissionDecision') return 'admission';
138
+ if (rowKind === 'gap') return 'proofGap';
139
+ return rowKind;
140
+ }
141
+
121
142
  function normalizeParadigmRow(rowKind) {
122
143
  if (rowKind === 'ownership') return 'ownershipModel';
123
144
  if (rowKind === 'lifetime') return 'lifetimeModel';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-parser",
3
- "version": "0.3.68",
3
+ "version": "0.3.70",
4
4
  "description": "Parser for the first Frontier Lang .frontier syntax slice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",