@shapeshift-labs/frontier-lang-parser 0.3.67 → 0.3.69
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/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { parseDialectRegistryBlock } from './dialect-registry.js';
|
|
|
9
9
|
import { parseInterlinguaBlock } from './interlingua.js';
|
|
10
10
|
import { createParsedMetadata } from './metadata.js';
|
|
11
11
|
import { parseEntityBlock, parseStateBlock, readTypeFields } from './member-records.js';
|
|
12
|
+
import { parseSemanticEditRecordsBlock } from './semantic-edit-records.js';
|
|
12
13
|
import { parseSemanticOperationsBlock } from './operations.js';
|
|
13
14
|
import { parsePackageManifestBlock } from './package-manifest.js';
|
|
14
15
|
import { parseParadigmBlock } from './paradigm.js';
|
|
@@ -29,6 +30,7 @@ export function parseFrontierSource(source, options = {}) {
|
|
|
29
30
|
const proofBlocks = [];
|
|
30
31
|
const paradigmBlocks = [];
|
|
31
32
|
const operationBlocks = [];
|
|
33
|
+
const semanticEditBlocks = [];
|
|
32
34
|
const conversionBlocks = [];
|
|
33
35
|
const constraintSpaceBlocks = [];
|
|
34
36
|
const decisionGraphBlocks = [];
|
|
@@ -62,6 +64,7 @@ export function parseFrontierSource(source, options = {}) {
|
|
|
62
64
|
if (block.kind === 'proof') proofBlocks.push(parseProofBlock(block));
|
|
63
65
|
if (block.kind === 'paradigm' || block.kind === 'paradigmSemantics') paradigmBlocks.push(parseParadigmBlock(block));
|
|
64
66
|
if (block.kind === 'operations' || block.kind === 'semanticOperations') operationBlocks.push(parseSemanticOperationsBlock(block));
|
|
67
|
+
if (block.kind === 'semanticEdits' || block.kind === 'semanticEditRecords') semanticEditBlocks.push(parseSemanticEditRecordsBlock(block));
|
|
65
68
|
if (block.kind === 'conversion' || block.kind === 'universalConversionPlan') conversionBlocks.push(parseConversionBlock(block));
|
|
66
69
|
if (block.kind === 'constraintSpace' || block.kind === 'possibilitySpace') constraintSpaceBlocks.push(parseConstraintSpaceBlock(block));
|
|
67
70
|
if (block.kind === 'decisionGraph' || block.kind === 'admissionGraph') decisionGraphBlocks.push(parseDecisionGraphBlock(block));
|
|
@@ -73,7 +76,7 @@ export function parseFrontierSource(source, options = {}) {
|
|
|
73
76
|
if (block.kind === 'applicationSurface' || block.kind === 'appHost' || block.kind === 'plugin' || block.kind === 'pluginSurface' || block.kind === 'pluginContract') applicationSurfaceBlocks.push(parseApplicationSurfaceBlock(block));
|
|
74
77
|
if (block.kind === 'runtimeCapabilities' || block.kind === 'runtimeCapabilityMatrix' || block.kind === 'runtimeHosts') runtimeCapabilityBlocks.push(parseRuntimeCapabilityBlock(block));
|
|
75
78
|
}
|
|
76
|
-
const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
|
|
79
|
+
const metadata = createParsedMetadata({ proofBlocks, paradigmBlocks, operationBlocks, semanticEditBlocks, conversionBlocks, constraintSpaceBlocks, decisionGraphBlocks, dialectRegistryBlocks, interlinguaBlocks, resourceGraphBlocks, nativeSourceBlocks, packageManifestBlocks, canvasSurfaceBlocks, applicationSurfaceBlocks, runtimeCapabilityBlocks, targetProjectionTargets });
|
|
77
80
|
return createDocument({ id: documentId, name: documentName, nodes, ...(metadata ? { metadata } : {}) });
|
|
78
81
|
}
|
|
79
82
|
|
package/dist/metadata.js
CHANGED
|
@@ -3,6 +3,7 @@ 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';
|
|
6
7
|
|
|
7
8
|
const PROOF_GROUPS = ['contracts', 'refinements', 'invariants', 'termination', 'temporal', 'obligations', 'artifacts', 'assumptions'];
|
|
8
9
|
const PARADIGM_GROUPS = [
|
|
@@ -11,11 +12,12 @@ const PARADIGM_GROUPS = [
|
|
|
11
12
|
'clockModels', 'objectModels', 'macroExpansions', 'reflectionBoundaries', 'loweringRecords'
|
|
12
13
|
];
|
|
13
14
|
|
|
14
|
-
export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
|
|
15
|
+
export function createParsedMetadata({ proofBlocks = [], paradigmBlocks = [], operationBlocks = [], semanticEditBlocks = [], conversionBlocks = [], constraintSpaceBlocks = [], decisionGraphBlocks = [], dialectRegistryBlocks = [], interlinguaBlocks = [], resourceGraphBlocks = [], nativeSourceBlocks = [], packageManifestBlocks = [], canvasSurfaceBlocks = [], applicationSurfaceBlocks = [], runtimeCapabilityBlocks = [], targetProjectionTargets = [] } = {}) {
|
|
15
16
|
const metadata = {};
|
|
16
17
|
if (proofBlocks.length) metadata.proof = mergeProofBlocks(proofBlocks);
|
|
17
18
|
if (paradigmBlocks.length) metadata.paradigmSemantics = mergeParadigmBlocks(paradigmBlocks);
|
|
18
19
|
if (operationBlocks.length) metadata.semanticOperations = mergeOperationBlocks(operationBlocks);
|
|
20
|
+
if (semanticEditBlocks.length) metadata.semanticEditRecords = mergeSemanticEditBlocks(semanticEditBlocks);
|
|
19
21
|
if (conversionBlocks.length) metadata.universalConversionPlan = mergeConversionBlocks(conversionBlocks);
|
|
20
22
|
if (constraintSpaceBlocks.length) metadata.constraintSpaces = mergeConstraintSpaceBlocks(constraintSpaceBlocks);
|
|
21
23
|
if (decisionGraphBlocks.length) metadata.decisionGraph = mergeDecisionGraphBlocks(decisionGraphBlocks);
|
package/dist/operations.js
CHANGED
|
@@ -133,16 +133,18 @@ function readAuthoredLines(block) {
|
|
|
133
133
|
|
|
134
134
|
function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
|
|
135
135
|
function nameFrom(header) { return /^([A-Za-z_$][\w$]*)/.exec(header)?.[1] ?? 'SemanticOperations'; }
|
|
136
|
-
function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
|
|
136
|
+
function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(unquotedText(text))?.[1]?.trim(); }
|
|
137
137
|
function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
|
|
138
|
-
function readInlineFlag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(text) || undefined; }
|
|
138
|
+
function readInlineFlag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(unquotedText(text)) || undefined; }
|
|
139
139
|
function readInlineList(text, ...labels) {
|
|
140
|
+
const source = unquotedText(text);
|
|
140
141
|
for (const label of labels) {
|
|
141
|
-
const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(
|
|
142
|
+
const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(source)?.[1]?.trim();
|
|
142
143
|
if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
|
|
143
144
|
}
|
|
144
145
|
return undefined;
|
|
145
146
|
}
|
|
147
|
+
function unquotedText(text) { return text.replace(/"[^"]*"|'[^']*'/g, (match) => ' '.repeat(match.length)); }
|
|
146
148
|
function cleanRecord(record) {
|
|
147
149
|
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
|
|
148
150
|
}
|
|
@@ -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
|
+
}
|
|
@@ -5,6 +5,7 @@ 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');
|
|
8
9
|
|
|
9
10
|
export const ROW_SYNTAX_CONFIG = Object.freeze({
|
|
10
11
|
interlingua: rowConfig('interlinguaRow', 'interlingua_row', interlinguaRows, normalizeInterlinguaRow),
|
|
@@ -33,6 +34,8 @@ export const ROW_SYNTAX_CONFIG = Object.freeze({
|
|
|
33
34
|
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),
|
|
34
35
|
operations: rowConfig('semanticOperationRow', 'semantic_operation_row', words('operation op'), normalizeOperationRow),
|
|
35
36
|
semanticOperations: rowConfig('semanticOperationRow', 'semantic_operation_row', words('operation op'), normalizeOperationRow),
|
|
37
|
+
semanticEdits: rowConfig('semanticEditRecordRow', 'semantic_edit_record_row', semanticEditRows, normalizeSemanticEditRow),
|
|
38
|
+
semanticEditRecords: rowConfig('semanticEditRecordRow', 'semantic_edit_record_row', semanticEditRows, normalizeSemanticEditRow),
|
|
36
39
|
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
40
|
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
41
|
proof: rowConfig('proofRow', 'proof_row', words('contract refinement invariant termination temporal obligation artifact assumption')),
|
|
@@ -118,6 +121,13 @@ function normalizeOperationRow(rowKind) {
|
|
|
118
121
|
return rowKind;
|
|
119
122
|
}
|
|
120
123
|
|
|
124
|
+
function normalizeSemanticEditRow(rowKind) {
|
|
125
|
+
if (rowKind === 'semanticEditScript') return 'script';
|
|
126
|
+
if (rowKind === 'semanticEditProjection') return 'projection';
|
|
127
|
+
if (rowKind === 'semanticEditReplay') return 'replay';
|
|
128
|
+
return rowKind;
|
|
129
|
+
}
|
|
130
|
+
|
|
121
131
|
function normalizeParadigmRow(rowKind) {
|
|
122
132
|
if (rowKind === 'ownership') return 'ownershipModel';
|
|
123
133
|
if (rowKind === 'lifetime') return 'lifetimeModel';
|