@functional-systems/srcx 0.1.0-dev.39 → 0.1.0-dev.40

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Evaluate experimental segmented artifacts across 50 successive local versions,
6
+ including cumulative writes, retained inode allocation, ancestor cleanup and
7
+ cold/explicit-checkpoint recovery. Add bounded multi-generation managed
8
+ publication regressions for cache/journal loss, stale or incomplete candidates,
9
+ retries in each phase and immutable historical reads. Document manual local
10
+ retention; keep runtime behavior and the JSONL default unchanged.
11
+
5
12
  - Add experimental `import --artifact-storage segments` for self-contained,
6
13
  digest-verified local format-2 artifacts. Reuse unchanged per-file objects with
7
14
  hardlinks and explicit copy fallback; retain format-1 reads and the JSONL default,
package/README.md CHANGED
@@ -172,6 +172,16 @@ artifact reader to support format 2. Linked files are not tamper-proof: full che
172
172
  detect shared-object corruption. Preserve the pending artifact and journal until
173
173
  publication completes.
174
174
 
175
+ Local retention is manual: remove whole completed artifact directories, keeping
176
+ any pending artifact and its original retry journal. Unchanged hardlinked objects
177
+ remain available through surviving artifacts. Losing the latest local artifact
178
+ requires a full local rebuild unless a surviving compatible checkpoint is
179
+ explicitly selected with `--previous` during a dry-run build; checkpoint discovery
180
+ is not automatic. Import that rebuilt artifact with `--artifact`.
181
+ Local cleanup does not delete published versions or their immutable remote data.
182
+ See [cumulative history and recovery measurements](VALIDATION.md#cumulative-segmented-history-and-recovery)
183
+ for the storage/time tradeoff across 50 successive versions.
184
+
175
185
  Artifacts contain source code; keep them with the same access policy as the repo.
176
186
  Every tree entry is accounted for, including explicit exclusions for symlinks,
177
187
  submodules, LFS pointers, dependencies/build output, image assets (including SVG), binary/invalid UTF-8 data,
package/VALIDATION.md CHANGED
@@ -1044,6 +1044,106 @@ were performed for this implementation. Linux/Windows and real
1044
1044
  cross-volume/power-loss checks have not been run locally; native no-follow support
1045
1045
  is required for the experimental mode. The default JSONL path is unchanged.
1046
1046
 
1047
+ ## Cumulative segmented history and recovery
1048
+
1049
+ A follow-up at `77d871c` compares 50 successive commits in two fixed corpora:
1050
+ 120 and 1,200 TypeScript files, with 24 functions per file. Version
1051
+ 0 is the initial build; each of the next 49 commits modifies one file, deletes
1052
+ one original file and adds one new file, keeping the file count fixed. Each mode
1053
+ uses its own preceding artifact. JSONL/segments execution order alternates by
1054
+ commit. Both modes produce identical record/inventory hashes at every commit.
1055
+
1056
+ These are **single instrumented history runs**, not repeated timing medians.
1057
+ The complete `materialize()` invocation is timed; filesystem observers count
1058
+ completed record writes, descriptor writes and logical record stream bytes.
1059
+ Recovery, retention checks and Git fixture preparation are excluded from these
1060
+ build totals. Host: Node.js 24.15.0, Apple M5 Pro/macOS arm64, one process with
1061
+ filesystem caches left intact and no fsync. The first JSONL build includes parser
1062
+ initialization; later builds reuse that state. Source bodies differ from the
1063
+ preceding single-update fixture, so compare modes within this experiment.
1064
+
1065
+ | Files | JSONL cumulative writes (bytes) | Segments cumulative writes (bytes) | Write reduction | JSONL build total (s) | Segments build total (s) |
1066
+ | ----- | ------------------------------- | ---------------------------------- | --------------- | --------------------- | ------------------------ |
1067
+ | 120 | 178,788,089 | 42,963,597 | 76.0% | 9.65 | 11.80 |
1068
+ | 1,200 | 1,784,802,339 | 406,139,767 | 77.2% | 78.17 | 99.71 |
1069
+
1070
+ The totals include the initial full build and all 49 updates. At 1,200 files,
1071
+ record payload writes fall from 1,423,502,835 to 30,798,963 bytes, while descriptors
1072
+ write 361,299,504 and 375,340,804 bytes respectively. Segments make 1,298 record
1073
+ write calls versus 21,850 for JSONL, but add 58,702 hardlinks. Logical record reads
1074
+ fall from 4,213,565,967 to 2,818,534,401 bytes; every previous/new artifact is still
1075
+ fully validated. Cumulative wall time is 27.5% higher for segments (22.3% at 120
1076
+ files). This supports lower cumulative writes, not faster builds.
1077
+
1078
+ Retention observations sum `stat.blocks * 512` once per unique `(dev, ino)` over
1079
+ the retained regular files, including descriptors. Decimal MB below means
1080
+ 1,000,000 bytes. This is not `du`, logical artifact size, peak usage, an exact
1081
+ physical extent count or billed storage; directory metadata, compression,
1082
+ shared extents and filesystem snapshots are outside the observation.
1083
+
1084
+ | Files | Retention | JSONL inode allocation (MB) | Segments inode allocation (MB) | Segments reduction |
1085
+ | ----- | ------------------ | --------------------------- | ------------------------------ | ------------------ |
1086
+ | 120 | All 50 versions | 178.99 | 43.24 | 75.8% |
1087
+ | 120 | Latest 10 versions | 35.80 | 10.97 | 69.4% |
1088
+ | 1,200 | All 50 versions | 1,785.46 | 407.29 | 77.2% |
1089
+ | 1,200 | Latest 10 versions | 357.01 | 105.01 | 70.6% |
1090
+
1091
+ At 1,200 files, counting every artifact's logical references instead gives
1092
+ 1,784,802,339 bytes for JSONL and 1,798,843,639 for segments: the saving comes
1093
+ from shared retained objects, not smaller logical records. With all 50 versions,
1094
+ segments use 1,348 unique regular-file inodes, versus 100 for JSONL. Removing
1095
+ versions 0–39 reduces these counts to 1,228 and 20. An unchanged object's link
1096
+ count falls from 50 to 10. Every surviving build passes full validation and
1097
+ returns the exact historical source after ancestor deletion; no remote version
1098
+ is deleted by local cleanup. Retention remains manual, with pending artifacts
1099
+ and their original journals preserved.
1100
+
1101
+ Recovery uses a further commit, version 50, after deleting the latest segmented
1102
+ artifact (version 49). A cold segmented rebuild has no previous artifact; the
1103
+ checkpoint rebuild explicitly selects surviving version 48, two changes behind.
1104
+ There is no automatic checkpoint search.
1105
+
1106
+ | Files | Recovery | Total writes (bytes) | Record writes (bytes) | Retained links | Build time (ms) |
1107
+ | ----- | ------------------------------ | -------------------- | --------------------- | -------------- | --------------- |
1108
+ | 120 | Cold | 3,601,624 | 2,849,398 | 0 | 303.7 |
1109
+ | 120 | Explicit version-48 checkpoint | 829,178 | 71,338 | 117 | 228.5 |
1110
+ | 1,200 | Cold | 35,974,629 | 28,471,318 | 0 | 2,791.8 |
1111
+ | 1,200 | Explicit version-48 checkpoint | 7,580,263 | 71,338 | 1,197 | 1,976.6 |
1112
+
1113
+ Cold, checkpoint and independent cold JSONL controls have identical record and
1114
+ inventory hashes. The checkpoint path fully validates both artifacts and reads
1115
+ 56,942,538 record bytes at 1,200 files; cold recovery reads 28,471,318 bytes for
1116
+ the new artifact. A missing cache does not grant permission to discard a pending
1117
+ tracked-branch journal: retry ownership still requires the original journal.
1118
+
1119
+ `test/segmented-history.test.mjs` keeps maintained coverage small: seven versions
1120
+ of eight files, plus a separate non-adjacent-checkpoint recovery case. It verifies
1121
+ add/modify/delete inventories, ancestor removal, relocation of the pending
1122
+ artifact, immutable remote baseline fallback, refusal after journal loss, stale
1123
+ and incomplete candidates, full candidate revalidation on publication retry,
1124
+ waiting without replay, a lost publication ACK before branch bookkeeping,
1125
+ unchanged managed vectors without client-supplied vectors, and all historical
1126
+ exact reads. Each test owns its temporary directories and store; no process-wide
1127
+ filesystem mocks or private experiment paths enter the suite. The large histories
1128
+ and one-off observer remain local evidence, outside committed fixtures.
1129
+ Managed publication uses the existing synthetic-vector fault fixture, not a
1130
+ backend emulator or an embedding/retrieval quality model.
1131
+
1132
+ Validation passed on Node.js 24.15.0 and 22.23.4: 203 full-suite tests, nine
1133
+ installed-tarball CLI tests and typechecking on each runtime. Formatting, version
1134
+ consistency, diff checks and all five CI Python suites (17 tests) also passed.
1135
+ The two new history tests also passed together in isolation.
1136
+
1137
+ No runtime/default behavior changes in this follow-up. Git enumeration, full
1138
+ local integrity checks, descriptor construction/writes and complete candidate
1139
+ verification remain proportional to corpus size. Further local write reductions
1140
+ would need a separate descriptor/inventory design with equally explicit integrity
1141
+ and recovery rules. Reducing remote candidate validation still requires a verified
1142
+ backend completeness/preservation contract. This experiment measures neither
1143
+ LambdaDB latency/storage nor embedding performance and makes no source uploads
1144
+ or paid/live calls. Cross-volume fallback, power loss and hostile concurrent
1145
+ directory replacement were not exercised.
1146
+
1047
1147
  ## Local checks
1048
1148
 
1049
1149
  Runtime used: Node.js 24.15.0, npm 11.12.1. Dependencies are pinned in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@functional-systems/srcx",
3
- "version": "0.1.0-dev.39",
3
+ "version": "0.1.0-dev.40",
4
4
  "private": false,
5
5
  "description": "Version-aware code search on LambdaDB",
6
6
  "type": "module",
@@ -66,5 +66,5 @@
66
66
  "url": "https://github.com/lambdadb/srcx/issues"
67
67
  },
68
68
  "license": "Apache-2.0",
69
- "gitHead": "77d871c825851358d7df98774298e355e823fa9f"
69
+ "gitHead": "2dc0ccb195990d8603790ef64d01e3b84ed778b8"
70
70
  }