@ldclabs/kip-lang 2.0.2 → 2.2.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/dist/parser.js CHANGED
@@ -63,13 +63,8 @@ class Parser {
63
63
  case TokenType.Ensure:
64
64
  case TokenType.Assert:
65
65
  case TokenType.Update:
66
- case TokenType.Retract:
67
- case TokenType.Supersede:
68
- case TokenType.Correct:
69
66
  case TokenType.Transition:
70
67
  case TokenType.Set:
71
- case TokenType.Archive:
72
- case TokenType.Tombstone:
73
68
  case TokenType.Purge:
74
69
  case TokenType.Merge:
75
70
  return this.parseMutationClause();
@@ -90,8 +85,6 @@ class Parser {
90
85
  return this.parseHistoryStatement();
91
86
  case TokenType.Changes:
92
87
  return this.parseChangesStatement();
93
- case TokenType.Snapshot:
94
- return this.parseSnapshotStatement();
95
88
  case TokenType.Export:
96
89
  return this.parseExportCapsuleStatement();
97
90
  default:
@@ -113,20 +106,10 @@ class Parser {
113
106
  return this.parseAssertStatement();
114
107
  case TokenType.Update:
115
108
  return this.parseUpdateStatement();
116
- case TokenType.Retract:
117
- return this.parseRetractAssertion();
118
- case TokenType.Supersede:
119
- return this.parseSupersedeAssertion();
120
- case TokenType.Correct:
121
- return this.parseCorrectEvidence();
122
109
  case TokenType.Transition:
123
- return this.parseTransitionActivity();
110
+ return this.parseTransitionStatement();
124
111
  case TokenType.Set:
125
112
  return this.parseSetRetention();
126
- case TokenType.Archive:
127
- return this.parseArchiveStatement();
128
- case TokenType.Tombstone:
129
- return this.parseTombstoneStatement();
130
113
  case TokenType.Purge:
131
114
  return this.parsePurgeStatement();
132
115
  case TokenType.Merge:
@@ -225,24 +208,15 @@ class Parser {
225
208
  const start = this.currentPos();
226
209
  const first = this.expect(TokenType.As);
227
210
  this.expectSecondWord(TokenType.Of, first);
228
- let basis;
229
- if (this.match(TokenType.Seq)) {
230
- basis = 'SEQ';
231
- }
232
- else if (this.match(TokenType.Tx)) {
233
- basis = 'TX';
234
- }
235
- else if (this.match(TokenType.Time)) {
236
- basis = 'TIME';
237
- }
238
- else {
239
- this.error(`Expected SEQ, TX or TIME after AS OF but got '${this.current().value}'`, this.current());
240
- basis = 'SEQ';
211
+ // Cognitive time is a sequence coordinate. A transaction id or an instant
212
+ // is resolved to one first (DESCRIBE TRANSACTION / DESCRIBE SNAPSHOT AT
213
+ // TIME), so the read names the sequence it actually ran against.
214
+ if (!this.match(TokenType.Seq)) {
215
+ this.error(`Expected SEQ after AS OF but got '${this.current().value}'`, this.current());
241
216
  }
242
217
  const value = this.parseScalarValue();
243
218
  return {
244
219
  kind: 'AsOfClause',
245
- basis,
246
220
  value,
247
221
  range: { start, end: this.endPos() }
248
222
  };
@@ -992,6 +966,7 @@ class Parser {
992
966
  handle,
993
967
  setFacets: [],
994
968
  unsetFacets: [],
969
+ expectVersions: [],
995
970
  range: { start, end: start },
996
971
  leadingComments: leadingComments.length ? leadingComments : undefined
997
972
  };
@@ -1006,10 +981,6 @@ class Parser {
1006
981
  this.rejectRepeat(stmt.match, 'MATCH', tok);
1007
982
  stmt.match = this.parseMatchClause();
1008
983
  break;
1009
- case TokenType.Expect:
1010
- this.rejectRepeat(stmt.expectVersion, 'EXPECT VERSION', tok);
1011
- stmt.expectVersion = this.parseExpectVersionClause();
1012
- break;
1013
984
  case TokenType.Set: {
1014
985
  const clause = this.parseSetClause();
1015
986
  if (clause.kind === 'SetFieldsClause') {
@@ -1055,6 +1026,9 @@ class Parser {
1055
1026
  break;
1056
1027
  }
1057
1028
  this.expect(TokenType.RBrace);
1029
+ // Preconditions trail the body, in the one tail order every mutation
1030
+ // shares: [WHERE] [LIMIT] {EXPECT VERSION} (Spec §52.8).
1031
+ stmt.expectVersions = this.parseExpectVersions();
1058
1032
  stmt.range = { start, end: this.endPos() };
1059
1033
  return stmt;
1060
1034
  }
@@ -1068,14 +1042,12 @@ class Parser {
1068
1042
  : undefined;
1069
1043
  this.dialect = 'raw';
1070
1044
  const tuple = this.parsePropositionTuple();
1071
- const expectVersion = this.check(TokenType.Expect)
1072
- ? this.parseExpectVersionClause()
1073
- : undefined;
1045
+ const expectVersions = this.parseExpectVersions();
1074
1046
  return {
1075
1047
  kind: 'EnsurePropositionStatement',
1076
1048
  handle,
1077
1049
  tuple,
1078
- expectVersion,
1050
+ expectVersions,
1079
1051
  range: { start, end: this.endPos() },
1080
1052
  leadingComments: leadingComments.length ? leadingComments : undefined
1081
1053
  };
@@ -1314,22 +1286,47 @@ class Parser {
1314
1286
  const expect = this.expect(TokenType.Expect);
1315
1287
  this.expectSecondWord(TokenType.Version, expect);
1316
1288
  const value = this.parseScalarValue();
1289
+ // `OF <plane>` guards one plane's own version instead of the element's
1290
+ // (Spec §35.1): a verdict guarded on ATTRIBUTES is not spoiled by a
1291
+ // metabolism sweep that touched a Facet.
1292
+ let plane;
1293
+ if (this.match(TokenType.Of)) {
1294
+ const tok = this.current();
1295
+ switch (tok.type) {
1296
+ case TokenType.Attributes:
1297
+ this.advance();
1298
+ plane = { kind: 'ATTRIBUTES' };
1299
+ break;
1300
+ case TokenType.Structural:
1301
+ this.advance();
1302
+ plane = { kind: 'STRUCTURAL' };
1303
+ break;
1304
+ case TokenType.Retention:
1305
+ this.advance();
1306
+ plane = { kind: 'RETENTION' };
1307
+ break;
1308
+ case TokenType.Facet:
1309
+ this.advance();
1310
+ plane = { kind: 'FACET', facet: this.parseSchemaSymbol() };
1311
+ break;
1312
+ default:
1313
+ this.error(`Expected ATTRIBUTES, STRUCTURAL, RETENTION or FACET after OF but got '${tok.value}'`, tok);
1314
+ }
1315
+ }
1317
1316
  return {
1318
1317
  kind: 'ExpectVersionClause',
1319
1318
  value,
1319
+ plane,
1320
1320
  range: { start, end: this.endPos() }
1321
1321
  };
1322
1322
  }
1323
- parseExpectStateClause() {
1324
- const start = this.currentPos();
1325
- const expect = this.expect(TokenType.Expect);
1326
- this.expectSecondWord(TokenType.State, expect);
1327
- const value = this.parseScalarValue();
1328
- return {
1329
- kind: 'ExpectStateClause',
1330
- value,
1331
- range: { start, end: this.endPos() }
1332
- };
1323
+ /** `{ expect_version_clause }` — the trailing precondition list. */
1324
+ parseExpectVersions() {
1325
+ const clauses = [];
1326
+ while (this.check(TokenType.Expect)) {
1327
+ clauses.push(this.parseExpectVersionClause());
1328
+ }
1329
+ return clauses;
1333
1330
  }
1334
1331
  // ────────────────────────────────────────────────────────────────────
1335
1332
  // KML — UPDATE
@@ -1339,9 +1336,6 @@ class Parser {
1339
1336
  const start = this.currentPos();
1340
1337
  this.expectKeywordWithSpace(TokenType.Update);
1341
1338
  const target = this.parseTargetRef();
1342
- const expectVersion = this.check(TokenType.Expect)
1343
- ? this.parseExpectVersionClause()
1344
- : undefined;
1345
1339
  const actions = [];
1346
1340
  for (;;) {
1347
1341
  if (this.check(TokenType.Set)) {
@@ -1363,9 +1357,9 @@ class Parser {
1363
1357
  this.error('UPDATE requires at least one SET or UNSET action', this.current());
1364
1358
  }
1365
1359
  // WHERE binds a ?variable target; a direct :id / "id" target already names
1366
- // the element and may omit it, exactly as ARCHIVE / TOMBSTONE / PURGE /
1367
- // SET RETENTION / RETRACT ASSERTION do (Spec §58). Whether a bare
1368
- // ?variable is bound is semantic — inside MUTATE it may be a local handle.
1360
+ // the element and may omit it, exactly as TRANSITION / PURGE /
1361
+ // SET RETENTION do (Spec §58). Whether a bare ?variable is bound is
1362
+ // semantic — inside MUTATE it may be a local handle.
1369
1363
  let where;
1370
1364
  if (this.check(TokenType.Where)) {
1371
1365
  this.expectKeywordWithSpace(TokenType.Where);
@@ -1373,96 +1367,35 @@ class Parser {
1373
1367
  where = this.parseWhereClause();
1374
1368
  }
1375
1369
  const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1370
+ const expectVersions = this.parseExpectVersions();
1376
1371
  return {
1377
1372
  kind: 'UpdateStatement',
1378
1373
  target,
1379
- expectVersion,
1380
1374
  actions,
1381
1375
  where,
1382
1376
  limit,
1377
+ expectVersions,
1383
1378
  range: { start, end: this.endPos() },
1384
1379
  leadingComments: leadingComments.length ? leadingComments : undefined
1385
1380
  };
1386
1381
  }
1387
1382
  // ────────────────────────────────────────────────────────────────────
1388
- // KML — lifecycle and correction
1383
+ // KML — TRANSITION (the one lifecycle statement, Spec §52.5)
1389
1384
  // ────────────────────────────────────────────────────────────────────
1390
- parseRetractAssertion() {
1385
+ parseTransitionStatement() {
1391
1386
  const leadingComments = this.collectLeadingComments();
1392
1387
  const start = this.currentPos();
1393
- const retract = this.expectKeywordWithSpace(TokenType.Retract);
1394
- this.expectSecondWord(TokenType.Assertion, retract);
1395
- const target = this.parseTargetRef();
1396
- let where;
1397
- if (this.check(TokenType.Where)) {
1398
- this.expectKeywordWithSpace(TokenType.Where);
1399
- this.dialect = 'raw';
1400
- where = this.parseWhereClause();
1401
- }
1402
- const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1403
- const expectState = this.check(TokenType.Expect)
1404
- ? this.parseExpectStateClause()
1405
- : undefined;
1406
- return {
1407
- kind: 'RetractAssertionStatement',
1408
- target,
1409
- where,
1410
- limit,
1411
- expectState,
1412
- range: { start, end: this.endPos() },
1413
- leadingComments: leadingComments.length ? leadingComments : undefined
1414
- };
1415
- }
1416
- parseSupersedeAssertion() {
1417
- const leadingComments = this.collectLeadingComments();
1418
- const start = this.currentPos();
1419
- const supersede = this.expectKeywordWithSpace(TokenType.Supersede);
1420
- this.expectSecondWord(TokenType.Assertion, supersede);
1421
- const target = this.parseTargetRef();
1422
- this.expect(TokenType.By);
1423
- const by = this.parseTargetRef();
1424
- const expectState = this.check(TokenType.Expect)
1425
- ? this.parseExpectStateClause()
1426
- : undefined;
1427
- return {
1428
- kind: 'SupersedeAssertionStatement',
1429
- target,
1430
- by,
1431
- expectState,
1432
- range: { start, end: this.endPos() },
1433
- leadingComments: leadingComments.length ? leadingComments : undefined
1434
- };
1435
- }
1436
- parseCorrectEvidence() {
1437
- const leadingComments = this.collectLeadingComments();
1438
- const start = this.currentPos();
1439
- const correct = this.expectKeywordWithSpace(TokenType.Correct);
1440
- this.expectSecondWord(TokenType.Evidence, correct);
1441
- const target = this.parseTargetRef();
1442
- this.expect(TokenType.By);
1443
- const by = this.parseTargetRef();
1444
- const expectState = this.check(TokenType.Expect)
1445
- ? this.parseExpectStateClause()
1446
- : undefined;
1447
- return {
1448
- kind: 'CorrectEvidenceStatement',
1449
- target,
1450
- by,
1451
- expectState,
1452
- range: { start, end: this.endPos() },
1453
- leadingComments: leadingComments.length ? leadingComments : undefined
1454
- };
1455
- }
1456
- parseTransitionActivity() {
1457
- const leadingComments = this.collectLeadingComments();
1458
- const start = this.currentPos();
1459
- const transition = this.expectKeywordWithSpace(TokenType.Transition);
1460
- this.expectSecondWord(TokenType.Activity, transition);
1388
+ this.expectKeywordWithSpace(TokenType.Transition);
1461
1389
  const target = this.parseTargetRef();
1462
1390
  this.expect(TokenType.To);
1463
1391
  const to = this.parseScalarValue();
1464
- // Terminal outputs and ended_at may be finalized in the same statement
1465
- // that moves the Activity to its terminal state.
1392
+ // `BY` names the replacing element for "superseded" / "corrected".
1393
+ let by;
1394
+ if (this.match(TokenType.By)) {
1395
+ by = this.parseTargetRef();
1396
+ }
1397
+ // A pending Activity finalizes terminal fields and topology in the same
1398
+ // statement that moves it (Spec §17.5, §52.5).
1466
1399
  const finalize = [];
1467
1400
  while (this.check(TokenType.Set)) {
1468
1401
  const clause = this.parseSetClause();
@@ -1470,19 +1403,27 @@ class Parser {
1470
1403
  finalize.push(clause);
1471
1404
  }
1472
1405
  else {
1473
- this.error('TRANSITION ACTIVITY accepts only SET FIELDS and SET STRUCTURAL', this.current());
1406
+ this.error('TRANSITION accepts only SET FIELDS and SET STRUCTURAL', this.current());
1474
1407
  break;
1475
1408
  }
1476
1409
  }
1477
- const expectState = this.check(TokenType.Expect)
1478
- ? this.parseExpectStateClause()
1479
- : undefined;
1410
+ let where;
1411
+ if (this.check(TokenType.Where)) {
1412
+ this.expectKeywordWithSpace(TokenType.Where);
1413
+ this.dialect = 'raw';
1414
+ where = this.parseWhereClause();
1415
+ }
1416
+ const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1417
+ const expectVersions = this.parseExpectVersions();
1480
1418
  return {
1481
- kind: 'TransitionActivityStatement',
1419
+ kind: 'TransitionStatement',
1482
1420
  target,
1483
1421
  to,
1422
+ by,
1484
1423
  finalize,
1485
- expectState,
1424
+ where,
1425
+ limit,
1426
+ expectVersions,
1486
1427
  range: { start, end: this.endPos() },
1487
1428
  leadingComments: leadingComments.length ? leadingComments : undefined
1488
1429
  };
@@ -1504,73 +1445,25 @@ class Parser {
1504
1445
  where = this.parseWhereClause();
1505
1446
  }
1506
1447
  const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1507
- const expectVersion = this.check(TokenType.Expect)
1508
- ? this.parseExpectVersionClause()
1509
- : undefined;
1448
+ const expectVersions = this.parseExpectVersions();
1510
1449
  return {
1511
1450
  kind: 'SetRetentionStatement',
1512
1451
  target,
1513
1452
  assignments,
1514
1453
  where,
1515
1454
  limit,
1516
- expectVersion,
1455
+ expectVersions,
1517
1456
  range: { start, end: this.endPos() },
1518
1457
  leadingComments: leadingComments.length ? leadingComments : undefined
1519
1458
  };
1520
1459
  }
1521
- parseArchiveStatement() {
1522
- const { start, target, where, limit, expectState, leadingComments } = this.parseRemovalBody(TokenType.Archive);
1523
- return {
1524
- kind: 'ArchiveStatement',
1525
- target,
1526
- where,
1527
- limit,
1528
- expectState,
1529
- range: { start, end: this.endPos() },
1530
- leadingComments
1531
- };
1532
- }
1533
- parseTombstoneStatement() {
1534
- const { start, target, where, limit, expectState, leadingComments } = this.parseRemovalBody(TokenType.Tombstone);
1535
- return {
1536
- kind: 'TombstoneStatement',
1537
- target,
1538
- where,
1539
- limit,
1540
- expectState,
1541
- range: { start, end: this.endPos() },
1542
- leadingComments
1543
- };
1544
- }
1545
- /** ARCHIVE and TOMBSTONE share one shape; PURGE adds its confirmation. */
1546
- parseRemovalBody(keyword) {
1547
- const comments = this.collectLeadingComments();
1548
- const start = this.currentPos();
1549
- this.expectKeywordWithSpace(keyword);
1550
- const target = this.parseTargetRef();
1551
- let where;
1552
- if (this.check(TokenType.Where)) {
1553
- this.expectKeywordWithSpace(TokenType.Where);
1554
- this.dialect = 'raw';
1555
- where = this.parseWhereClause();
1556
- }
1557
- const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1558
- const expectState = this.check(TokenType.Expect)
1559
- ? this.parseExpectStateClause()
1560
- : undefined;
1561
- return {
1562
- start,
1563
- target,
1564
- where,
1565
- limit,
1566
- expectState,
1567
- leadingComments: comments.length ? comments : undefined
1568
- };
1569
- }
1570
1460
  parsePurgeStatement() {
1571
1461
  const leadingComments = this.collectLeadingComments();
1572
1462
  const start = this.currentPos();
1573
- this.expectKeywordWithSpace(TokenType.Purge);
1463
+ const purge = this.expectKeywordWithSpace(TokenType.Purge);
1464
+ if (this.check(TokenType.Payload)) {
1465
+ return this.parsePurgePayloadTail(start, purge, leadingComments);
1466
+ }
1574
1467
  const target = this.parseTargetRef();
1575
1468
  let where;
1576
1469
  if (this.check(TokenType.Where)) {
@@ -1579,6 +1472,7 @@ class Parser {
1579
1472
  where = this.parseWhereClause();
1580
1473
  }
1581
1474
  const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1475
+ const expectVersions = this.parseExpectVersions();
1582
1476
  let referencePolicy;
1583
1477
  if (this.check(TokenType.Reference)) {
1584
1478
  const reference = this.expect(TokenType.Reference);
@@ -1599,12 +1493,46 @@ class Parser {
1599
1493
  target,
1600
1494
  where,
1601
1495
  limit,
1496
+ expectVersions,
1602
1497
  referencePolicy,
1603
1498
  confirm,
1604
1499
  range: { start, end: this.endPos() },
1605
1500
  leadingComments: leadingComments.length ? leadingComments : undefined
1606
1501
  };
1607
1502
  }
1503
+ /**
1504
+ * `PURGE PAYLOAD` erases Evidence bytes while the element survives
1505
+ * (Spec §60.6), so there is no REFERENCE POLICY clause; the confirmation
1506
+ * literal is the same as element purge.
1507
+ */
1508
+ parsePurgePayloadTail(start, purge, leadingComments) {
1509
+ this.expectSecondWord(TokenType.Payload, purge);
1510
+ const target = this.parseTargetRef();
1511
+ let where;
1512
+ if (this.check(TokenType.Where)) {
1513
+ this.expectKeywordWithSpace(TokenType.Where);
1514
+ this.dialect = 'raw';
1515
+ where = this.parseWhereClause();
1516
+ }
1517
+ const limit = this.check(TokenType.Limit) ? this.parseLimitClause() : undefined;
1518
+ const expectVersions = this.parseExpectVersions();
1519
+ this.expect(TokenType.Confirm);
1520
+ const confirmTok = this.current();
1521
+ const confirm = this.parseStringLiteral();
1522
+ if (confirm.parsed !== 'PURGE') {
1523
+ this.error(`PURGE PAYLOAD must be confirmed with the exact literal "PURGE", got ${confirmTok.value}`, confirmTok);
1524
+ }
1525
+ return {
1526
+ kind: 'PurgePayloadStatement',
1527
+ target,
1528
+ where,
1529
+ limit,
1530
+ expectVersions,
1531
+ confirm,
1532
+ range: { start, end: this.endPos() },
1533
+ leadingComments: leadingComments.length ? leadingComments : undefined
1534
+ };
1535
+ }
1608
1536
  parseMergeConcept() {
1609
1537
  const leadingComments = this.collectLeadingComments();
1610
1538
  const start = this.currentPos();
@@ -1619,15 +1547,13 @@ class Parser {
1619
1547
  this.dialect = 'raw';
1620
1548
  where = this.parseWhereClause();
1621
1549
  }
1622
- const expectVersion = this.check(TokenType.Expect)
1623
- ? this.parseExpectVersionClause()
1624
- : undefined;
1550
+ const expectVersions = this.parseExpectVersions();
1625
1551
  return {
1626
1552
  kind: 'MergeConceptStatement',
1627
1553
  source,
1628
1554
  into,
1629
1555
  where,
1630
- expectVersion,
1556
+ expectVersions,
1631
1557
  range: { start, end: this.endPos() },
1632
1558
  leadingComments: leadingComments.length ? leadingComments : undefined
1633
1559
  };
@@ -1658,11 +1584,6 @@ class Parser {
1658
1584
  case TokenType.Protocol:
1659
1585
  this.expectSecondWord(TokenType.Protocol, describe);
1660
1586
  return stmt('PROTOCOL');
1661
- case TokenType.Execution: {
1662
- const exec = this.expectSecondWord(TokenType.Execution, describe);
1663
- this.expectSecondWord(TokenType.Context, exec);
1664
- return stmt('EXECUTION_CONTEXT');
1665
- }
1666
1587
  case TokenType.Capabilities:
1667
1588
  this.expectSecondWord(TokenType.Capabilities, describe);
1668
1589
  return stmt('CAPABILITIES');
@@ -1719,8 +1640,19 @@ class Parser {
1719
1640
  }
1720
1641
  case TokenType.Snapshot: {
1721
1642
  this.expectSecondWord(TokenType.Snapshot, describe);
1722
- const asOf = this.check(TokenType.As) ? this.parseAsOfClause() : undefined;
1723
- return stmt('SNAPSHOT', { asOf });
1643
+ // A snapshot is addressed by sequence, or resolved from an instant:
1644
+ // the one place wall-clock time enters cognitive-time addressing.
1645
+ let asOf;
1646
+ let atTime;
1647
+ if (this.check(TokenType.As)) {
1648
+ asOf = this.parseAsOfClause();
1649
+ }
1650
+ else if (this.check(TokenType.At)) {
1651
+ const at = this.expect(TokenType.At);
1652
+ this.expectSecondWord(TokenType.Time, at);
1653
+ atTime = this.parseScalarValue();
1654
+ }
1655
+ return stmt('SNAPSHOT', { asOf, atTime });
1724
1656
  }
1725
1657
  case TokenType.Capsule:
1726
1658
  this.expectSecondWord(TokenType.Capsule, describe);
@@ -1731,11 +1663,6 @@ class Parser {
1731
1663
  const value = this.isMetaValueStart() ? this.parseScalarValue() : undefined;
1732
1664
  return stmt('EPISTEMIC_POLICY', { value });
1733
1665
  }
1734
- case TokenType.Projection: {
1735
- const projection = this.expectSecondWord(TokenType.Projection, describe);
1736
- this.expectSecondWord(TokenType.Capability, projection);
1737
- return stmt('PROJECTION_CAPABILITY');
1738
- }
1739
1666
  case TokenType.Trust: {
1740
1667
  this.expectSecondWord(TokenType.Trust, describe);
1741
1668
  const value = this.isMetaValueStart() ? this.parseScalarValue() : undefined;
@@ -1763,6 +1690,8 @@ class Parser {
1763
1690
  const tok = this.current();
1764
1691
  let target;
1765
1692
  let status;
1693
+ let element;
1694
+ let depth;
1766
1695
  switch (tok.type) {
1767
1696
  case TokenType.Spaces:
1768
1697
  this.expectSecondWord(TokenType.Spaces, list);
@@ -1800,6 +1729,15 @@ class Parser {
1800
1729
  target = 'EPISTEMIC_POLICIES';
1801
1730
  break;
1802
1731
  }
1732
+ case TokenType.Dependents:
1733
+ // Bounded reverse provenance closure (Spec §63.5): the operand is
1734
+ // required, the DEPTH bound is optional and defaults engine-side to 1.
1735
+ this.expectSecondWord(TokenType.Dependents, list);
1736
+ target = 'DEPENDENTS';
1737
+ element = this.parseScalarValue();
1738
+ if (this.match(TokenType.Depth))
1739
+ depth = this.parseScalarValue();
1740
+ break;
1803
1741
  default:
1804
1742
  this.error(`Unknown LIST target '${tok.value}'`, tok);
1805
1743
  throw new ParseAbort();
@@ -1812,6 +1750,8 @@ class Parser {
1812
1750
  kind: 'ListStatement',
1813
1751
  target,
1814
1752
  status,
1753
+ element,
1754
+ depth,
1815
1755
  limit,
1816
1756
  cursor,
1817
1757
  range: { start, end: this.endPos() },
@@ -2030,7 +1970,7 @@ class Parser {
2030
1970
  throw new ParseAbort();
2031
1971
  }
2032
1972
  // ────────────────────────────────────────────────────────────────────
2033
- // META — HISTORY / CHANGES / SNAPSHOT
1973
+ // META — HISTORY / CHANGES
2034
1974
  // ────────────────────────────────────────────────────────────────────
2035
1975
  parseHistoryStatement() {
2036
1976
  const leadingComments = this.collectLeadingComments();
@@ -2109,18 +2049,6 @@ class Parser {
2109
2049
  leadingComments: leadingComments.length ? leadingComments : undefined
2110
2050
  };
2111
2051
  }
2112
- parseSnapshotStatement() {
2113
- const leadingComments = this.collectLeadingComments();
2114
- const start = this.currentPos();
2115
- this.expect(TokenType.Snapshot);
2116
- const asOf = this.check(TokenType.As) ? this.parseAsOfClause() : undefined;
2117
- return {
2118
- kind: 'SnapshotStatement',
2119
- asOf,
2120
- range: { start, end: this.endPos() },
2121
- leadingComments: leadingComments.length ? leadingComments : undefined
2122
- };
2123
- }
2124
2052
  // ────────────────────────────────────────────────────────────────────
2125
2053
  // META — EXPORT CAPSULE
2126
2054
  // ────────────────────────────────────────────────────────────────────
@@ -2949,13 +2877,8 @@ class Parser {
2949
2877
  TokenType.Ensure,
2950
2878
  TokenType.Assert,
2951
2879
  TokenType.Update,
2952
- TokenType.Retract,
2953
- TokenType.Supersede,
2954
- TokenType.Correct,
2955
2880
  TokenType.Transition,
2956
2881
  TokenType.Set,
2957
- TokenType.Archive,
2958
- TokenType.Tombstone,
2959
2882
  TokenType.Purge,
2960
2883
  TokenType.Merge,
2961
2884
  TokenType.Describe,
@@ -2966,7 +2889,6 @@ class Parser {
2966
2889
  TokenType.Preview,
2967
2890
  TokenType.History,
2968
2891
  TokenType.Changes,
2969
- TokenType.Snapshot,
2970
2892
  TokenType.Export,
2971
2893
  TokenType.EOF
2972
2894
  ]);