Create explicit, bidirectional links between:
- SPEC.md (authoritative design)
- LEGACY_NOTES.md (what to keep/replace)
- legacy/ code (the actual reference implementations)
- Package Atlas (generated site)
Deliverables:
- A crosswalk that says which legacy artifacts are still the source of truth for v2, which are reference-only, and which are obsolete.
- Link conventions + build steps so the Atlas renders clickable hops SPEC ↔ LEGACY ↔ APIs.
- Concrete text patches for SPEC/LEGACY_NOTES to install those links.
We’ll use lightweight, repo-relative tags that your Atlas builder rewrites into permalinks:
-
Code anchors (in source): add a one-line marker above each symbol you want to link:
# @anchor LEGACY:atoms.publish_part def publish_part(...): ...
The Atlas builder emits
<a id="LEGACY:atoms.publish_part">anchors and captures file/line. -
Doc links (in md): reference anchors using square-bracket tags that the builder rewrites:
[LEGACY:atoms.publish_part]→ links to the symbol anchor in the rendered code page[SPEC:identity.subset_uuid]→ links to aSPEC.mdsection id (see below)[NOTES:fs.atomic]→ links to anchors inside LEGACY_NOTES.md
-
SPEC anchors: add explicit HTML anchors to every normative section header, e.g.:
<a id="SPEC:identity.subset_uuid"></a> ### Subset UUID derivation
-
Permalink stability: the Atlas should resolve each tag to a permalink that includes the commit hash used for that build (e.g.,
/ref/<sha>/legacy/datamgr/atoms.py#LEGACY:atoms.publish_part). The latest build can also maintain a moving alias under/latest/….
Legend:
- KEEP: carry forward essentially as-is (minor naming polish OK)
- ADAPT: keep the core idea/impl but update per SPEC changes
- REPLACE: do not rely on legacy behavior for v2
- SPEC:
[SPEC:identity.subset_uuid](specials + quantization → deterministic subset_uuid) - Legacy reference:
ingest_core.stable_subset_key(REPLACE) – stringified, tolerance-rounded key. Will be superseded.ingest_core.Router.resolve_subset_uuid(REPLACE) – uses tolerance + Manifest to allocate UUIDs; v2 must compute locally from specials/quantization without DB search.manifest.get_or_create_subset(ADAPT) – DB path stays (insert if absent), but the key lookup will use the deterministicsubset_uuidfrom SPEC. Real-key tolerance logic is removed.
- SPEC:
[SPEC:parts.content_hash], hashing includes padded bytes for jagged fields + meta arrays - Legacy reference:
atoms.compute_semantic_content_hash(ADAPT) – NFC + length-prefixed, includes a schema signature. Extend to incorporate: (a) padded data and (b) jagged meta (e.g.,*_len,*_shape) exactly as SPEC defines.- DB uniqueness:
manifest.ensure_dataset_db_initializedunique index on(subset_uuid, content_hash)(KEEP) atoms.publish_partpre-check + insert-once reconcile (KEEP) – race-safe dedupe.
- SPEC:
[SPEC:storage.scheme],[SPEC:sealing.atomic_write] - Legacy reference:
atoms.StorageScheme,atoms.part_relpath(KEEP) – optional fanout via hash slices.- Atomic write path in
atoms.publish_part(KEEP) –*.tmp → fsync(file) → rename → fsync(dir)with HDF5 VFD fsync fallback. - String encoding/decoding:
atoms.h5_storage_dtype,to_h5_storage_array,from_h5_storage_array(KEEP) – serves as baseline for v2’s binary format; add AAD/encryption seam later.
- SPEC:
[SPEC:ingest.buffering],[SPEC:ingest.crash_safe],[SPEC:ingest.staging] - Legacy reference:
manager.Manager.addbuffering +_flush_subset_bufferchunking bypart_rows(KEEP)- Multi-writer flow in
affinity_ingest(ADAPT) – routing must use deterministicsubset_uuid(post-SPEC), not tolerance-basedRouter. The overall writer/queue/process orchestration is KEEP. ingest_core.Stager(KEEP/ADAPT) – staging schema and prefix-claim mechanics are sound; update to store new AAD/encryption metadata as needed.affinity_ingestcompaction loops (KEEP) – reclaim stale, claim prefix, merge, publish.
- SPEC:
[SPEC:schema.dtype_lock],[SPEC:jagged.meta_arrays] - Legacy reference:
- Canonical locking/widening:
manager.ensure_canonical_dtype(KEEP/ADAPT) – retain lock-on-first-write, but extend to record jagged meta fields; ensure widening semantics remain for text. manager.dict_to_structured(ADAPT) – enforce jagged meta rules (pad, populate*_len/*_shape), and disallow objects/complex/datetimes as legacy already does.manager.data(ADAPT) – assemble with jagged awareness; continue surfacingmissing_parts.
- Canonical locking/widening:
- SPEC:
[SPEC:catalog.ddl](datasets, subsets, parts, batches, batch_parts, merge_log) - Legacy reference:
- Existing tables/indices in
manifest.ensure_dataset_db_initialized(ADAPT) – keep subsets/parts foundations; add:batches,batch_parts, optionalmerge_logand tamper-evidence columns per SPEC. - PRAGMAs / connection factories (
atoms.default_conn_factory,manifest.catalog_conn) (KEEP)
- Existing tables/indices in
- SPEC:
[SPEC:gc.soft_delete],[SPEC:gc.fsck],[SPEC:security.tamper] - Legacy reference:
manager.soft_delete,manager.delete+manifest.gc_commit(KEEP/ADAPT) – same ops flow; extend counts/consistency checks per SPEC and incorporate tamper-evident hash chain if enabled.manifest.fsck_dataset(KEEP/ADAPT) – orphan detection remains; compute content hash from HDF5 when missing → align with updated hash rules.
- SPEC:
[SPEC:security.aead],[SPEC:security.aad_contract] - Legacy reference:
atoms.publish_part(ADAPT) – introduce hook points to build/store AAD; integrate CryptoProvider later without changing the atomicity path.- Hooks class (
atoms.Hooks) (KEEP/ADAPT) – document new callbacks covering AEAD context and sealing states.
- SPEC:
[SPEC:planner.v0],[SPEC:navigator.readonly] - Legacy reference:
manager.meta(ADAPT/RENAME) – keep the idea (single call returning typed arrays), but conform fields to SPEC (PartStats, jaggedness, costs); planner APIs will be new.
Add at the top of SPEC.md:
<!-- Link anchors used by the Atlas -->
<a id="SPEC:identity.subset_uuid"></a>
<a id="SPEC:parts.content_hash"></a>
<a id="SPEC:storage.scheme"></a>
<a id="SPEC:sealing.atomic_write"></a>
<a id="SPEC:ingest.buffering"></a>
<a id="SPEC:ingest.crash_safe"></a>
<a id="SPEC:ingest.staging"></a>
<a id="SPEC:schema.dtype_lock"></a>
<a id="SPEC:jagged.meta_arrays"></a>
<a id="SPEC:catalog.ddl"></a>
<a id="SPEC:gc.soft_delete"></a>
<a id="SPEC:gc.fsck"></a>
<a id="SPEC:security.aead"></a>
<a id="SPEC:security.aad_contract"></a>
<a id="SPEC:planner.v0"></a>
<a id="SPEC:navigator.readonly"></a>At the end of each relevant section, add a short “Legacy reference” list, e.g. for Atomic sealing:
**Legacy reference:** [LEGACY:atoms.publish_part], [LEGACY:atoms.fsync_dir], [LEGACY:atoms.makedirs_with_fsync]Add anchors at the top:
<a id="NOTES:fs.atomic"></a>
<a id="NOTES:hashing"></a>
<a id="NOTES:staging"></a>
<a id="NOTES:ddl"></a>Then update bullets to use symbol tags:
- **Keep** atomic HDF5 sealing: [LEGACY:atoms.publish_part], [LEGACY:atoms.fsync_dir].
- **Keep/extend** content hashing: [LEGACY:atoms.compute_semantic_content_hash]; extend per [SPEC:parts.content_hash] (padding + jagged meta).
- **Replace** tolerance-based identity: [LEGACY:ingest_core.Router.resolve_subset_uuid] → see [SPEC:identity.subset_uuid].
- **Keep** WAL2 pragmas/conn factories: [LEGACY:atoms.default_conn_factory], [LEGACY:manifest.catalog_conn].
- **Keep** staging & compaction: [LEGACY:ingest_core.Stager], [LEGACY:affinity_ingest.writer_loop].Add # @anchor … above these symbols:
atoms.py:fsync_dir,makedirs_with_fsync,cleanup_stale_tmps_in_dir,StorageScheme,part_relpath,compute_semantic_content_hash,publish_part,SubsetLease,DatasetLeaseingest_core.py:stable_subset_key,Router,Stagermanager.py:dict_to_structured,ensure_canonical_dtype,Manager.add,Manager.flush,Manager.meta,Manager.data,Manager.soft_delete,Manager.deletemanifest.py:ensure_dataset,ensure_dataset_db_initialized,ensure_key_columns,get_or_create_subset,find_subsets,gc_commit,fsck_dataset,lock_part_configsqlite_loader.py:sqlite3proxy,assert_compile_options
- Symbol scan: add
tools/linkmap.pyto parse Python files for# @anchor TAGand emitdocs/linkmap.json:
{
"LEGACY:atoms.publish_part": {
"file": "legacy/datamgr/atoms.py",
"line": 210,
"sha": "<commit>"
}
}- Markdown rewrite: during docs build, replace
[LEGACY:…],[SPEC:…],[NOTES:…]with proper<a href>links usinglinkmap.jsonand section ids. - Permalinks: embed the build’s commit SHA in each link; also create
latestaliases. - CI: Insert after “atlas builder” in the existing pipeline.
- Add anchors to SPEC.md sections listed above.
- Add anchors to LEGACY_NOTES.md and convert bullets to symbol-tag links.
- Insert
# @anchorlines above the listed symbols inlegacy/datamgr/*.py. - Implement
tools/linkmap.pyand markdown rewriter. - Extend hashing to handle jagged padding/meta per SPEC.
- Swap identity flow to deterministic
subset_uuid(remove tolerance search paths). Keep DB upsert semantics. - Extend DDL with
batches,batch_parts, optionalmerge_logaligned to SPEC; wire indices. - Add AAD stubs in sealing path and Hooks (no crypto yet).
- Update
meta()surface to include PartStats and jagged fields.
- Non-breaking doc work first (anchors + Atlas rewrite) so links become live right away.
- Hashing/jagged (safe to add alongside legacy parts as new versions).
- Deterministic identity (introduce side-by-side, add backfill tool, then flip default).
- DDL extensions (add tables; feature-flag readers until populated).
- Planner/Meta surface (add new entry points; keep legacy
meta()as compatibility facade until TUI is stable).
Legend:
- MUST LINK = not yet called out in SPEC/LEGACY_NOTES; important for v2 work
- ALREADY LINKED = covered by the Crosswalk above
- NICE TO LINK = helpful operational reference
- MUST LINK
DEFAULT_STALE_CLAIM_SECONDS— staging reclaim window constant (document operational default)writer_loop()— full crash‑safe path incl._attempt_compact_for_subsetand_merge_and_publishdetailsingest_with_subset_affinity()— process topology & routing; queue back‑pressure and liveness checksingest_serial()— crash‑safe serial ingest; compaction-on-shutdown loop semantics
- ALREADY LINKED
ingest()entry point (maps to ingest UX in SPEC)
- NICE TO LINK
assert_picklable()— spawn safety requirement for kwargschunk_tasks()— batching policycompute_payload()— Joblib glue
- MUST LINK
schema_signature_for_hash()— exact hash contract seed (v2 will extend with jagged meta)update_hasher_from_structured()/update_hasher_from_h5_dataset()— structured + HDF5 hashing pathscompute_semantic_content_hash()/..._from_h5()— exposed hash API used by publish/deduph5_storage_dtype()/to_h5_storage_array()/from_h5_storage_array()— Unicode↔bytes storage codecSubsetLease/subset_lock_path()— per‑subset serialization primitiveDatasetLease/dataset_lock_path()— dataset‑wide GC/FSCK exclusivitypublish_part()— atomic sealing, dedupe, and manifest txn; error‑handling branchessafe_unlink_inside()/prune_empty_dirs()— GC safety & cleanup invariantsdb_txn_immediate()/default_conn_factory()— txn/backoff and WAL2 PRAGMAs (tie to ops guidance)
- ALREADY LINKED
StorageScheme,validate_storage_scheme(),part_relpath()— layout fanoutfsync_dir()/makedirs_with_fsync()/cleanup_stale_tmps_in_dir()— atomic IO support
- NICE TO LINK
hash_utf8_lenpref_iter()— NFC + length‑prefix rationaleSUPPORTED_HASHES— validate policy surfacebatched()— generic util used in DB ops
- MUST LINK
Stagerschema & indices (created in_init_schema) — authoritative staging DDLStager.select_and_claim_prefix()— prefix selection algorithm (oversize‑row branch, claim token use)Stager.reclaim_stale()— reclaim policy (µs timestamps)_staging_conn_factory()— durable vs normal synchronous mode
- ALREADY LINKED
Router/stable_subset_key()— legacy identity (to be replaced)
- NICE TO LINK
Stager.hot_subsets()— shutdown draining heuristic
- MUST LINK
dict_to_structured()— admissible dtypes, shape logic, and error text (specify object/S/complex/datetime rejections)ensure_canonical_dtype()— lock‑on‑first‑write; text‑field widening; catalog + dataset meta syncManager.add()— buffer accounting and spill threshold selection (part_rows vs chunk_rows)Manager._flush_subset_buffer()— carry/concatenate behavior, chunking loop, and per‑slice sealingManager.meta()— numpy schema for subset/parts meta (fields, types) to guide v2 meta surfaceManager.data()— part assembly, canonical casting, andmissing_partscontractManager.soft_delete()/Manager.delete()— mark/unmark semantics and GC workflow
- ALREADY LINKED
sql_to_numpy_dtype()/ overrides — mapping rules for meta arrays
- NICE TO LINK
dtype_to_canonical_json()/dtype_from_canonical_json()/dtype_from_json_descr()— schema encodingwiden_unicode_dtype()/maybe_widen_text_fields()— widening logic detailsnormalize_numeric_dtype()— numeric normalization policy
- MUST LINK
ensure_dataset_db_initialized()— full DDL + indices (names, partial indexes, uniqueness)ensure_key_columns()— first‑write column creation & filtered indices; reserved names checkget_or_create_subset()— tolerance‑based lookup/insert (legacy contract to replace) incl. NaN handlingfind_subsets()— query semantics (ranges, NaN, marked filters, time windows) and chunked IN queriesgc_commit()— recomputetotal_rows, delete marked rows, subset deletion criterionfsck_dataset()— orphan detection; content hash recomputation from HDF5 datasetlock_part_config()— first‑lock semantics and propagation to dataset meta
- ALREADY LINKED
ensure_dataset()— catalog + dataset meta bootstrap (and MIRROR writes into datasetmeta)
- NICE TO LINK
to_epoch_us()/epoch_us_to_iso()— time parsing rules (Z/offset handling)infer_sql_type()/convert_for_sql()/safe_is_nan()— key coercion policycatalog_conn()/conn_factory_for_dataset()— PRAGMA presets
- MUST LINK
assert_compile_options()— required SQLite features checklist (JSON1/FTS5/RTREE/etc.)_ensure_wheel_ready()/_find_local_wheel()/_extract_wheel()— wheel selection & extraction contractsqlite3proxy behavior — indirection layer all DB code depends on
- NICE TO LINK
- Platform tag logic:
_py_tag(),_plat_tokens()
- Platform tag logic:
- State defaults: document
DEFAULT_STALE_CLAIM_SECONDS, PRAGMAs chosen (journal_mode=wal2, busy_timeout, cache_size, synchronous levels for durable vs non‑durable). - Exact DDL (staging + dataset): index names, filtered indices, unique constraints.
- Hashing contract subtleties: schema signature byte format; Unicode NFC + 4‑byte little‑endian length prefix; HDF5 S/U conversion.
- GC invariants: safe unlink scope checks, empty dir pruning, and when to remove subset directories.
- Time parsing: ISO8601 handling, timezone normalization, and NaN semantics for REAL queries.
- Buffering/sealing behavior: carry‑over chunks and partial spill semantics.
- Crash‑safe compaction semantics: oversize single-row claim path; reclaim window; shutdown drain order.