@henols/vice-mcp 0.2.3 → 0.2.4

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/anno-symbols.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  // anno-symbols.ts -- the ONE authoritative place in this repo for the
3
3
  // PRE-SPAWN half of the symbol round trip between an annotation store and
4
- // stock VICE's symbol table (ANNO-14/ANNO-15, ARCHITECTURE.md Rule A20).
4
+ // stock VICE's symbol table (ARCHITECTURE.md Rule A20).
5
5
  //
6
- // WHAT LEFT, WHAT STAYED, AND WHERE THE ROUTE RETURNS (plan 29-10, D-01/D-14,
7
- // 2026-08-30). Read this paragraph before looking for a function that is not
6
+ // WHAT LEFT, WHAT STAYED, AND WHERE THE ROUTE RETURNS (2026-08-30). Read this
7
+ // paragraph before looking for a function that is not
8
8
  // here.
9
9
  //
10
10
  // WHAT LEFT: the ROUTE. `exportLabels()`, `importLabels()` and
@@ -46,7 +46,7 @@
46
46
  // criterion of it mentioned `export-lbl` or `import-lbl`. So the forecast
47
47
  // was wrong, and it is CORRECTED here rather than deleted, because deleting
48
48
  // a withdrawal notice erases the record that a capability went missing and
49
- // why. `.planning/PROJECT.md` carries the dated ANNO-14/ANNO-15 notice and
49
+ // why. This project's own capability record carries the dated notice and
50
50
  // says the same thing: this is a temporary loss of a capability that was
51
51
  // genuinely Validated, not a completed one being tidied away. The
52
52
  // demonstration was made end to end against genuine unpatched stock `x64sc`
@@ -67,7 +67,7 @@
67
67
  //
68
68
  // MEASURED FACTS, PAST TENSE, kept because they are the reasons for the
69
69
  // discipline above rather than instructions to anyone:
70
- // - `--export_lbl` exported USER labels only. Measured (Phase 9, and
70
+ // - `--export_lbl` exported USER labels only. Measured (and
71
71
  // re-confirmed by the round-trip test that was deleted with its subject):
72
72
  // an annotated project emitted exactly the labels a caller had set, and
73
73
  // the auto-generated `a_D011` / `a_D020` / `e_FFD2` externals were NOT
@@ -168,7 +168,7 @@ export interface ImportLabelsUnverified {
168
168
  * read `result.importedNames` and mistake "the import call returned no error"
169
169
  * for "the names are actually on disk".
170
170
  *
171
- * KEPT ACROSS THE CUT (plan 29-10). The route that produced it is gone; the
171
+ * KEPT ACROSS THE CUT. The route that produced it is gone; the
172
172
  * distinction it encodes is the whole lesson of the `--import_lbl` discard
173
173
  * measured in this module's header. Because no phase currently owns rebuilding
174
174
  * that route, this type is its only surviving contract; whenever a route IS
@@ -194,7 +194,7 @@ export interface ValidatedLabelFile {
194
194
  /**
195
195
  * THE PRE-SPAWN GATE (T-11-LBL-SIZE + T-11-NAME-INJECT, both closed) -- the
196
196
  * half of the deleted `importLabels()` that never touched a child process,
197
- * lifted out unchanged when the route around it was removed (plan 29-10).
197
+ * lifted out unchanged when the route around it was removed.
198
198
  *
199
199
  * In order, and the order matters:
200
200
  * 1. A byte-size check against `stock-symbols.ts`'s own
package/anno-types.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // The ONE place that writes down the annotation store's data-type vocabulary,
5
5
  // its range row shape, and every validator the store runs before a caller's
6
- // argument is allowed anywhere near SQL (STORE-01).
6
+ // argument is allowed anywhere near SQL.
7
7
  //
8
8
  // ---------------------------------------------------------------------------
9
9
  // WHY THIS FILE EXISTS
@@ -58,8 +58,8 @@
58
58
  // path lands outside the root once symbolic links are followed, and that
59
59
  // is a filesystem question that no string comparison can answer -- the
60
60
  // earlier pure-string version accepted a symlinked subdirectory and let a
61
- // store file be created outside the workspace root (`28-VERIFICATION.md`
62
- // gap 3 / `28-REVIEW.md` CR-03, reproduced). Every OTHER export is still
61
+ // store file be created outside the workspace root, confirmed by a live
62
+ // symlink reproduction. Every OTHER export is still
63
63
  // a pure function of its arguments and still unit-testable with no file
64
64
  // on disk. The exception is named here, in `storePathWithinWorkspace`'s
65
65
  // own doc comment, and in `anno-types.test.ts`'s mutable-state assertion
@@ -68,7 +68,7 @@
68
68
  // `parseStoreAddress()` takes an integer, a `$hex` string and a
69
69
  // `0x`/`0X` string, and refuses `"1024"`. This is a REAL, user-visible
70
70
  // divergence from `stock-address.ts:155-160`, which accepts the bare
71
- // decimal form AS DECIMAL under its own decision `D-04` and says so at
71
+ // decimal form AS DECIMAL and says so at
72
72
  // `:89-105`. The reason the store diverges: a mis-based address written
73
73
  // into the store is PERSISTENT and silently wrong -- every later reader
74
74
  // inherits it -- whereas a mis-based memory read is transient and the
@@ -92,19 +92,21 @@
92
92
  // sanitized or quoted."
93
93
  // 8. NEVER restate the eleven auto-generated-name prefixes here. They live in
94
94
  // exactly one place, `anno-coverage.ts`'s `AUTO_NAME_PREFIX_RE`, and
95
- // `EXPORT-02` names the exact failure a short reimplementation causes: a
96
- // five-prefix copy silently under-counts, which breaks the
95
+ // a short reimplementation causes the exact failure this project has
96
+ // already measured: a five-prefix copy silently under-counts, which breaks the
97
97
  // `routine-queue-walker` skill's backlog construction while every test
98
98
  // keeps passing. The store separates the two namespaces with its label
99
99
  // `kind` field, not with a name pattern.
100
100
  // 9. NEVER build a mnemonic-to-access-kind classifier here. Nothing derivable
101
101
  // is stored (see `anno-store.ts`'s `putXref`), `OpcodeEntry` carries no
102
- // access/reads/writes field at all, and `REQUIREMENTS.md` records the
103
- // analysis built on such a field as deferred with a named trigger. A
102
+ // access/reads/writes field at all, and analysis built on such a field is
103
+ // deliberately deferred until a named future consumer exists: the field
104
+ // is stored because it is free now and unrecoverable later, but no
105
+ // shipped caller reads it yet. A
104
106
  // classifier written now would have no caller and no way to be wrong
105
107
  // observably.
106
- // 10. NEVER measure comment length in code units. `String.length` counts UTF-16
107
- // code units, so a multi-byte comment passes a code-unit check and then
108
+ // 10. NEVER measure comment length in code units. `String.length` counts
109
+ // 16-bit code units, so a multi-byte comment passes a code-unit check and then
108
110
  // exceeds the byte bound on disk. `assertCommentText()` measures with a
109
111
  // `TextEncoder`.
110
112
  import { existsSync, lstatSync, readlinkSync, realpathSync } from "node:fs";
@@ -133,26 +135,26 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
133
135
  *
134
136
  * * TWO STORES IN ONE DIRECTORY SHARED ONE RING under the same
135
137
  * `r<revision>.db` filenames, so `revertTo` on one store restored the
136
- * OTHER store's whole database, silently and with no error (CR-01).
138
+ * OTHER store's whole database, silently and with no error.
137
139
  * * RENAMING THE CONTAINING DIRECTORY invalidated every persisted absolute
138
140
  * path at once, after which `retainedRevisions()` reported none and the
139
- * next accepted write's prune destroyed the entire revert history (CR-03).
141
+ * next accepted write's prune destroyed the entire revert history.
140
142
  *
141
143
  * Version 2 drops `anno_snapshot.path` -- there is no persisted string left for
142
144
  * a second namespace to disagree with -- and derives the location from the
143
145
  * handle at every read and every delete via `snapshotDirFor()`.
144
146
  *
145
147
  * A VERSION-1 STORE IS REFUSED, NOT UPGRADED, and the reason is that the
146
- * version-1 ring's OWNERSHIP is not recoverable: CR-01 means two stores may
148
+ * version-1 ring's OWNERSHIP is not recoverable: two stores may
147
149
  * both have written into `<dir>/snapshots`, and nothing recorded which file
148
150
  * belonged to which store. Any migration would have to guess, attributing one
149
- * store's history to another -- CR-01 again with a new cause and no test
150
- * watching. The legacy directory is therefore left on disk untouched: never
151
+ * store's history to another -- the same failure shape recurring with a new
152
+ * cause and no test watching. The legacy directory is therefore left on disk untouched: never
151
153
  * adopted, never migrated, never deleted, so the bytes stay recoverable by
152
154
  * hand.
153
155
  *
154
156
  * ---------------------------------------------------------------------------
155
- * VERSION 3, 2026-08-29 (D-15) -- AND THE COST IS NAMED HERE RATHER THAN LEFT
157
+ * VERSION 3, 2026-08-29 -- AND THE COST IS NAMED HERE RATHER THAN LEFT
156
158
  * IN A PLANNING DIRECTORY, because a version number whose rationale lives
157
159
  * somewhere else is a number the next reader has no way to weigh.
158
160
  *
@@ -184,7 +186,7 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
184
186
  * impossibility.
185
187
  *
186
188
  * ---------------------------------------------------------------------------
187
- * VERSION 4, 2026-09-10 (EVID-02) -- THE DECISION IS `reaffirm-refusal`, AND
189
+ * VERSION 4, 2026-09-10 -- THE DECISION IS `reaffirm-refusal`, AND
188
190
  * THE FACTUAL BASIS IS TRANSCRIBED HERE RATHER THAN LEFT IN A PLANNING
189
191
  * DIRECTORY, for the same reason VERSION 3's paragraph gives.
190
192
  *
@@ -205,7 +207,7 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
205
207
  * 1. `find / -xdev -name '*.annostore'`, with `.git` directories excluded --
206
208
  * empty. The broader `find "$HOME" -name '*.annostore'` (closing the `-xdev`
207
209
  * mount-boundary gap) found five hits, all inside a dated (2026-08-27)
208
- * scratch probe cache (`~/.cache/gsd-probe/c4/...`), with
210
+ * scratch probe cache directory, with
209
211
  * fixture-pattern names (`t-half`, `t-zero`, `t-tail-100`, `p`, `proj`)
210
212
  * and one file zero bytes -- synthetic test fixtures, not a real
211
213
  * project's store.
@@ -259,7 +261,7 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
259
261
  * refusal stays the default.
260
262
  *
261
263
  * ---------------------------------------------------------------------------
262
- * VERSION 5, 2026-09-11 (BUILD-07) -- THE DECISION IS `reaffirm-refusal`, THE
264
+ * VERSION 5, 2026-09-11 -- THE DECISION IS `reaffirm-refusal`, THE
263
265
  * SAME OPTION VERSION 4 SELECTED, AND THE FACTUAL BASIS IS TRANSCRIBED HERE
264
266
  * RATHER THAN LEFT IN A PLANNING DIRECTORY, for the same reason every prior
265
267
  * version's paragraph gives.
@@ -267,7 +269,7 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
267
269
  * WHAT THE BUMP BUYS: `anno_excluded_range`, the durable record of a
268
270
  * user-requested exclusion -- its extent AND the reason the user gave -- so
269
271
  * the export can emit the range's real bytes tagged with a visible marker
270
- * comment instead of a hole, which is `BUILD-07`'s whole invariant: an
272
+ * comment instead of a hole, which is this feature's whole invariant: an
271
273
  * exclusion is a RECORDED, VISIBLE fact, never a silent drop. See
272
274
  * `anno-store.ts`'s `DDL` and its three verbs, `addExcludedRange` /
273
275
  * `listExcludedRanges` / `removeExcludedRange`.
@@ -289,7 +291,7 @@ import { ViceError, type ViceErrorOptions } from "./vice-errors.ts";
289
291
  * NEW since VERSION 4's check: `.c64-re-tools/phase45-scratch/
290
292
  * tracer.annostore`, inside THIS repository's own gitignored scratch
291
293
  * directory, timestamped 2026-09-10 -- its path and name identify it as
292
- * Phase 45's own tracer/scratch fixture, not a real consuming project's
294
+ * this project's own tracer/scratch fixture, not a real consuming project's
293
295
  * store. Six real files, zero real stores.
294
296
  * 2. `git log --oneline --diff-filter=A -- '*.annostore'` -- still empty.
295
297
  * No `.annostore` has ever been added to this repository's tracked
@@ -343,8 +345,7 @@ export const ADDRESS_MAX = 0xffff;
343
345
  * (`anno-store.ts`'s `snapshotDirFor()` -- a sibling named after the store
344
346
  * FILE, not the fixed `<dir>/snapshots` version 1 used) may hold before the
345
347
  * oldest is pruned. Declared here because the bound is a property of the
346
- * store's format; the pruning that enforces it belongs to the revert surface
347
- * (`STORE-04`). */
348
+ * store's format; the pruning that enforces it belongs to the revert surface. */
348
349
  export const MAX_SNAPSHOT_REVISIONS = 32;
349
350
 
350
351
  /**
@@ -451,7 +452,8 @@ export type LabelKind = (typeof LABEL_KINDS)[number];
451
452
  * is written down, and its provenance needs stating precisely so a later reader
452
453
  * does not over-trust it: these four spellings are CITED from an external
453
454
  * analyser's reference documentation, flowed through this project's own research
454
- * notes, and fixed by `STORE-05`'s requirement text. They are NOT read from any
455
+ * notes, and fixed by this project's own requirement that cross-reference rows
456
+ * carry their access kind. They are NOT read from any
455
457
  * code in this repository, and no comment may present them as verified project
456
458
  * vocabulary.
457
459
  *
@@ -520,7 +522,7 @@ export interface CommentRow {
520
522
  }
521
523
 
522
524
  /**
523
- * One stored comment that a retype has just made FALSE (STORE-03).
525
+ * One stored comment that a retype has just made FALSE.
524
526
  *
525
527
  * The caller needs all four facts to act on the report without a second query:
526
528
  * WHERE the comment is, WHAT it says, WHICH grade fired, and WHICH data type
@@ -539,7 +541,7 @@ export interface ContradictedComment {
539
541
  }
540
542
 
541
543
  /**
542
- * One entry-address pairing of a split table (STORE-03, CR-10).
544
+ * One entry-address pairing of a split table.
543
545
  *
544
546
  * `pairs[i]` is the two ADDRESSES whose bytes form entry `i`, in table order:
545
547
  * the first-half address and its second-half partner. `entryCount` is
@@ -552,8 +554,8 @@ export interface SplitEntryPairs {
552
554
  }
553
555
 
554
556
  /**
555
- * One surviving fragment of a split table that a partial overwrite left behind
556
- * (CR-10). `entryPairs` is what that fragment reads NOW -- not what the addresses
557
+ * One surviving fragment of a split table that a partial overwrite left behind.
558
+ * `entryPairs` is what that fragment reads NOW -- not what the addresses
557
559
  * in it used to be paired with.
558
560
  */
559
561
  export interface SplitTableSurvivor {
@@ -565,7 +567,7 @@ export interface SplitTableSurvivor {
565
567
 
566
568
  /**
567
569
  * What one accepted partial overwrite of a split table COST, reported as data on
568
- * a successful `setDataType()` result (STORE-03, CR-10). Documented in the same
570
+ * a successful `setDataType()` result. Documented in the same
569
571
  * register as `ContradictedComment` above, and for the same reason: a caller
570
572
  * needs every fact it would otherwise have to re-query for.
571
573
  *
@@ -615,14 +617,14 @@ export interface ScopeRow {
615
617
  }
616
618
 
617
619
  /** One user-requested exclusion as the store holds it, added at
618
- * `SCHEMA_VERSION` 5 (`BUILD-07`). Both ends are INCLUSIVE, matching every
620
+ * `SCHEMA_VERSION` 5. Both ends are INCLUSIVE, matching every
619
621
  * other range-shaped row this store persists. There is no `bank` column,
620
622
  * because an exclusion is a statement about a span of the SUBJECT PROGRAM the
621
623
  * user asked to leave out of the rebuild -- not a memory view -- and there is
622
624
  * no confidence, verdict, grade or severity column, because this row holds
623
625
  * WHAT THE USER ASKED FOR and nothing the tool concluded about it. A
624
626
  * judgement column here would be the exact "tool is the decider" shape
625
- * `BUILD-05`'s 2026-09-10 rewording removed: the store answers "what did the
627
+ * this project's own 2026-09-10 requirement rewording removed: the store answers "what did the
626
628
  * user record", never "should this range be excluded". */
627
629
  export interface ExcludedRangeRow {
628
630
  id: number;
@@ -643,7 +645,7 @@ export interface ProjectEnumRow {
643
645
 
644
646
  /**
645
647
  * One enum usage as the store holds it: the association between ONE address
646
- * and ONE project enum, added at `SCHEMA_VERSION` 3 (D-15).
648
+ * and ONE project enum, added at `SCHEMA_VERSION` 3.
647
649
  *
648
650
  * `enumId` IS WHAT THE STORE PERSISTS; `enumName` is resolved through the join
649
651
  * at read time and is never a second on-disk copy of the name. A row that
@@ -674,7 +676,7 @@ export interface XrefRow {
674
676
 
675
677
  /**
676
678
  * The three memory regions `memmapshow` reports an execute observation
677
- * against, `SCHEMA_VERSION` 4 (EVID-01). This is the ONE place this
679
+ * against, `SCHEMA_VERSION` 4. This is the ONE place this
678
680
  * vocabulary is written down.
679
681
  *
680
682
  * ALL THREE ARE INCLUDED DELIBERATELY, not for symmetry: `AccessFlags`
@@ -690,7 +692,7 @@ export type EvidSourceBank = (typeof EVID_SOURCE_BANKS)[number];
690
692
 
691
693
  /**
692
694
  * The runtime evidence layer's own classification of an address, `SCHEMA_VERSION`
693
- * 4 (EVID-04). This is a TYPE-LEVEL control, not a runtime check: the union has
695
+ * 4. This is a TYPE-LEVEL control, not a runtime check: the union has
694
696
  * exactly two members and NO `"data"` member exists for a caller to return,
695
697
  * mistakenly or otherwise.
696
698
  *
@@ -713,11 +715,10 @@ export type RuntimeExecClass = "code" | "unobserved";
713
715
  /**
714
716
  * One runtime-execution observation as the store holds it (`anno_evid_exec`,
715
717
  * `SCHEMA_VERSION` 4). Keyed by the bare run-identity triple
716
- * `(imageSha256, argvDigest, seed)` plus `address` plus `sourceBank` -- the
717
- * `no-change` assumption-delta decision plan 43-01's live A/B selected
718
- * (`docs/phase43-instrumentation-perturbation-ab.md`): there is no
719
- * `run_class` discriminator column, because instrumentation was measured
720
- * `no-perturbation` at anchor hit depths 10 and 50.
718
+ * `(imageSha256, argvDigest, seed)` plus `address` plus `sourceBank` -- there is
719
+ * no `run_class` discriminator column: a live A/B measured `no-perturbation`
720
+ * from instrumentation at anchor hit depths 10 and 50, so a run-class
721
+ * distinction would encode a difference nothing observed.
721
722
  *
722
723
  * A row here asserts exactly ONE fact: this address was observed executing,
723
724
  * in this source bank, during this run. There is no `bank`-reserved column
@@ -737,8 +738,8 @@ export interface EvidExecRow {
737
738
  * One distinct run identity's accumulated observation count, as
738
739
  * `listObservedRuns()` reports it. `observationCount` is a COUNT, never a
739
740
  * percentage or rate -- see `listObservedRuns`'s own doc comment in
740
- * `anno-store.ts` for the denominator this count is a fraction of (EVID-04:
741
- * a count with no denominator invites the reading "the rest is data").
741
+ * `anno-store.ts` for the denominator this count is a fraction of (a count
742
+ * with no denominator invites the reading "the rest is data").
742
743
  */
743
744
  export interface ObservedRunRow {
744
745
  imageSha256: string;
@@ -828,7 +829,7 @@ export interface AnnoRevisionArgumentErrorOptions {
828
829
  * path is built, so nothing has been read and nothing has been written.
829
830
  *
830
831
  * WHY THIS IS NOT `AnnoStoreCorruptError`, WHICH IS THE WHOLE REASON THE CLASS
831
- * EXISTS (WR-22). Until this class existed, `revertTo(handle, "0001")` matched
832
+ * EXISTS. Until this class existed, `revertTo(handle, "0001")` matched
832
833
  * revision 1's pointer row through SQLite's INTEGER affinity on a bound TEXT
833
834
  * operand, while `snapshotPathFor` built `r0001.db` from the raw string -- so
834
835
  * the two disagreed and the caller was told its snapshot was "not a readable
@@ -1082,7 +1083,8 @@ export interface AnnoCommentGradeErrorOptions {
1082
1083
  *
1083
1084
  * It is NEVER correct to swallow the original and treat the comment as ungraded:
1084
1085
  * that would quietly exempt a malformed comment from contradiction reporting,
1085
- * which is the same silent un-documenting `STORE-03` exists to prevent.
1086
+ * which is the same silent-un-documenting failure this store's contradiction
1087
+ * reporting exists to prevent.
1086
1088
  */
1087
1089
  export class AnnoCommentGradeError extends AnnoStoreError {
1088
1090
  comment?: string;
@@ -1216,7 +1218,7 @@ const MAX_SYMLINK_HOPS = 40;
1216
1218
  * Does the path ENTRY `p` exist -- that is, does this NAME exist in its
1217
1219
  * directory?
1218
1220
  *
1219
- * THIS IS THE WHOLE OF `CR-04`, in two sentences. `existsSync` answers a
1221
+ * THE WHOLE OF THE DISTINCTION, IN TWO SENTENCES. `existsSync` answers a
1220
1222
  * different question: "does this path RESOLVE to something?", which follows
1221
1223
  * symbolic links and therefore reports `false` for a dangling one. `lstat`
1222
1224
  * answers "does this NAME exist?", which does not follow the link. The two
@@ -1226,8 +1228,7 @@ const MAX_SYMLINK_HOPS = 40;
1226
1228
  *
1227
1229
  * `throwIfNoEntry: false` makes the ABSENT case a value rather than an
1228
1230
  * exception, so the caller has one branch instead of a `try` around a
1229
- * predicate. That option suppresses `ENOENT` AND NOTHING ELSE, which is the
1230
- * whole of `WR-12`.
1231
+ * predicate. That option suppresses `ENOENT` AND NOTHING ELSE.
1231
1232
  *
1232
1233
  * REVERSED 2026-08-28, and the reversal is the record rather than a deletion
1233
1234
  * (this module's header discipline, 28-07 P3). The premise that was RIGHT and
@@ -1247,7 +1248,7 @@ const MAX_SYMLINK_HOPS = 40;
1247
1248
  * * `ELOOP` -- a symlink cycle in an ANCESTOR position, where the kernel
1248
1249
  * refuses at `lstat` before the manual hop counter below ever runs.
1249
1250
  *
1250
- * `28-REVIEW.md` WR-12 has the before/after transcript. The `try` restores the
1251
+ * The `try` restores the
1251
1252
  * family WITHOUT restoring the old blindness: the absent case is still a value
1252
1253
  * and still one branch, and everything else is a decision naming both the entry
1253
1254
  * the walk stopped on and the path being confined.
@@ -1294,8 +1295,7 @@ function pathEntryExists(p: string, resolved: string): boolean {
1294
1295
  * /tmp/annosym-XXXX/ws/p.annostore`) and `openStore` created the store file
1295
1296
  * OUTSIDE the workspace root (`A) file created OUTSIDE workspace: true`);
1296
1297
  * separately, a dangling DIRECTORY link was accepted at the predicate
1297
- * (`B dangling dir -> ACCEPTED`). `28-VERIFICATION.md` gap 2 / `28-REVIEW.md`
1298
- * CR-04. The walk now stops on `pathEntryExists`, which is `lstat` and does not
1298
+ * (`B dangling dir -> ACCEPTED`). The walk now stops on `pathEntryExists`, which is `lstat` and does not
1299
1299
  * follow the link.
1300
1300
  *
1301
1301
  * THE DANGLING STOPPING ENTRY IS RESOLVED BY HAND, because nothing else will:
@@ -1404,8 +1404,8 @@ function realpathOfNearestExisting(p: string): string {
1404
1404
  * * The PATH must be a real path, because `resolve()` normalises `..` but
1405
1405
  * does NOT follow symbolic links. The pure-string version accepted a
1406
1406
  * symlinked subdirectory inside the workspace and the store file was
1407
- * created outside the root (`28-REVIEW.md` CR-03, reproduced by the phase
1408
- * verifier). A confinement check has to compare what the filesystem will
1407
+ * created outside the root, confirmed by a live symlink reproduction.
1408
+ * A confinement check has to compare what the filesystem will
1409
1409
  * actually do.
1410
1410
  * * The ROOT must go through the SAME walk, for two independent reasons. A
1411
1411
  * workspace root that does not exist is a legitimate input -- the pinned
@@ -1454,8 +1454,7 @@ export function storePathWithinWorkspace(path: string, workspaceRoot: string): s
1454
1454
  * WHY THIS IS A SEAM RATHER THAN AN INLINE `relative()` AT ITS ONE CALL SITE.
1455
1455
  * The spelling this returns goes into a **compared** artifact: the memory
1456
1456
  * map's banner is re-rendered and diffed BYTE FOR BYTE by
1457
- * `checkRenderedMemoryMap()`. The defect it closes (`CR-01`, gap 1 in
1458
- * `.planning/phases/29-the-mcp-surface/29-VERIFICATION.md`) is that machine
1457
+ * `checkRenderedMemoryMap()`. The defect it closes is that machine
1459
1458
  * identity leaked into that content comparison: the banner recorded the
1460
1459
  * absolute realpaths, so the same store, the same sidecar and the same
1461
1460
  * rendered file reported `drifted` as soon as the checkout sat at a different
@@ -1565,7 +1564,7 @@ export function assertRunIdentityDigest(value: unknown, what: string): string {
1565
1564
  }
1566
1565
 
1567
1566
  /** A non-empty string. `seed` is not a digest and carries no shape beyond
1568
- * that -- REPRO-04's run-identity composite treats it as an opaque token. */
1567
+ * that -- this store's run-identity composite treats it as an opaque token. */
1569
1568
  export function assertRunIdentitySeed(value: unknown): string {
1570
1569
  if (typeof value === "string" && value.length > 0) {
1571
1570
  return value;
@@ -1846,7 +1845,8 @@ export function resolveSplitTargets(bytes: Uint8Array | readonly number[], dataT
1846
1845
  *
1847
1846
  * A resolver and a writer that each kept their own copy of this arithmetic could
1848
1847
  * disagree about what an entry IS, and the disagreement would be silent: both
1849
- * copies produce legal, decodable rows. That is CR-10's whole class, so the rule
1848
+ * copies produce legal, decodable rows. That is exactly the class of bug a
1849
+ * second implementation would risk, so the rule
1850
1850
  * has one home. `anno-types.test.ts`'s worked-arithmetic pin is the control --
1851
1851
  * changing the couples here to an interleaved `[2i, 2i + 1]` reddens it.
1852
1852
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@henols/vice-mcp",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "VICE emulator MCP server for C64 reverse-engineering: a stdio MCP server that proxies vice tools to a host VICE MCP server.",
5
5
  "type": "module",
6
6
  "bin": {