Uh oh!
There was an error while loading. Please reload this page.
docs(rfc): RFC-0003 — dataset storage & offboard hygiene (draft) - #366
Conversation
Commits the drafted RFC-0003 into cli/docs/rfcs/ alongside 0001/0002. Concept-only design doc covering two user-visible problems that share one root cause: offboard should leave a true clean slate, and ingested datasets are stored as world-readable host files bind-mounted into the cluster (engineered to survive cluster deletion), which sits awkwardly against "your data stays within the secure environment". Storage options + open decisions (section 7) pending Lukas + Asad. Companion to backend#1151. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saadqbal
commented
Jul 21, 2026
§7 decisions — Asad's positionTalked this through and confirmed a couple of things against the current 7.2 — Local storage: Option C (node-local). This is the one that actually matches the goal. Data lives in the k3d node's own storage (k3s local-path), so The objection to C was "loses survive-delete+recreate." I checked: the installer reuses an existing cluster on re-run ( 7.3 — Drop 7.1 — Scoped verified wipe + installer leftover-guard: keep the guard, the wipe mostly falls out of C. The leftover-guard (detect non-empty data → stop and ask reuse/wipe/new-dir) is still worth it as a safety net and doubles as the migration prompt (see 7.5). The elaborate scoped-path wipe becomes largely redundant under C — keep 7.5 — Migration: none needed as a data-copy tool. With reuse-on-upgrade, existing installs keep running on their current 7.4 — Messaging. C lets us keep the stronger "within the secure environment" wording more honestly, but let's be precise internally: node-local gets us not-host-visible + dies-with-cluster, not cryptographically secure. Anyone with Docker access can still Summary: 7.2 = C, 7.3 = yes, 7.1 = guard yes, heavy wipe no, 7.5 = guard only, no copier, 7.4 = keep wording, encryption is phase 2. Implementation is mostly in |
saadqbal
commented
Jul 22, 2026
@LukasWodka — I dug into RFC-0003 and think we're ready to lock the §7 calls. Prototyped and validated Option C end-to-end on a real dev install; posted the full evidence in the §7 comment above and on client#368. Short version of where I land:
Two things I need from you:
Minor: the RFC §9 evidence line numbers are stale (the installer's been refactored since) — worth a refresh before we call it decided. |
saadqbal
commented
Jul 22, 2026
Two pieces of feedback came in on this RFC. Both are good, but they're different in kind — one sharpens what's already here, the other is a new concern the RFC doesn't cover. First, the framing that shapes both: On a machine the customer owns, we can't make data inaccessible or un-tamperable absolutely — the owner has root, Docker, and the disk. The honest goals are "no other service casually touches it" and "tampering is detectable", not "impossible". A design promising absolute prevention on the customer's own box would be the same overclaim §4.2 was written to avoid. 1. "Data only accessible by the tracebloc cluster, not other services"Three layers, different answers:
Verdict: good, and in-scope — it's a sharpening of Problem B. It moves §7.2 from "C" toward "C now + D/host-FDE at rest + a follow-up for in-cluster PVC scoping". Note the phrasing is slippery: the point of tracebloc is that vendor models do process the data in-cluster, so it's "no service outside the sanctioned training flow", not "no service". Worth pinning the exact layer with whoever raised it. 2. "Data should be tamper-free so scores stay valid"The real ask: the test/scoring dataset must be fixed and verifiable, so leaderboard scores are reproducible and comparable across competitors — a tampered re-run mustn't silently produce a new score. Achievable version is tamper-evidence, not tamper-proofing:
Verdict: good and genuinely important for a benchmark product — but orthogonal to this RFC. Its root cause (verifiable, versioned scoring data) is unrelated to the storage-location root cause here; Option C barely touches it. Caveats: we can't stop the owner tampering, only detect it; the threat model is really "fairness for competing vendors + reproducibility"; and legitimate updates mean this is versioning + integrity, not blanket immutability. It spans ingestor + jobs-manager scoring + backend leaderboard — bigger than this doc. Recommendation
|
…ent boundary - §7 decision menu -> §10 decision log (D1-D14): Option C node-local, leftover-guard, no data-copier, 777 dies with C, encryption phase 2 - New §1-2: secure-environment definition (3-in/1-out channel list) + threat model with honest ceilings (owner-root, data-derived weights) - New §6: model IP protection — watermarking + audit now, envelope encryption + crypto-shredding for at-rest weights (keys in memory, not weight files), TEE as phase 2, HE/MPC rejected - New §7: in-cluster walls — dataset-scoped mounts, per-experiment DB grants, spawned-pod hardening completion - New §8: egress-lockdown flip dependency, seal check, per-substrate guarantee matrix, verify k3d enforcement - §3/§13 evidence corrected + refreshed (777 scoping, cluster reuse, stale line numbers) - Open items: O1 default-flip, O2 retention, O3 key custody, O4 watermark Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LukasWodka
commented
Jul 22, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit afe9cd1. Configure here.
… D15 - §3.1/§6.4: verified against tracebloc-client + client-runtime + averaging-service — weights do NOT rest durably in the environment (per-cycle backend download -> pod-scoped scratch -> upload back); durable store is the platform-side averaging share - D8 re-aimed: edge = lifecycle hygiene only; envelope encryption + crypto-shredding applies to the platform-side store (backend/averaging ticket, outside the environment boundary) - O1 decided -> D15: node-local becomes the default for local installs after one green training run on node-local - O3 dissolved by architecture; O2 re-scoped to platform-side retention - Evidence appendix: added weight-lifecycle code anchors Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LukasWodka
commented
Jul 22, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit a936323. Configure here.
LukasWodka
commented
Jul 22, 2026
Signed off — and thanks for the prototype + validation, that's what settled it. Everything is recorded in the doc, now at v2.1:
Go ahead on the leftover-guard and the flip. Execution tickets for the rest are being filed under backend#1151 — links will follow here. When you get a chance, review v2.1 so we can merge this. |
…/§12 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LukasWodka
commented
Jul 22, 2026
bugbot run |
LukasWodka
commented
Jul 22, 2026
As promised — execution tickets are filed; the doc is now v2.2 (DECIDED) with everything cross-linked in §10/§12. Epic: backend#1151. P1: client-runtime#199 (egress-lockdown flip, D6) · client#376 (leftover-guard, D3 — yours) · backend#1180 (dev 401 — gates the D15 training run) · client#367 (now carries the D15 default-flip checklist — yours) P2: client-runtime#200 (job TTL, D8-edge) · client-runtime#201 (legacy carve-out, D11) · client-runtime#202 (SA-token + securityContext floor, D11) · client-runtime#203 (dataset-scoped mounts, D9) · backend#1181 (per-experiment DB grants, D10) · backend#1182 (platform weight-store encryption + crypto-shred, D8/O2) · backend#1183 (watermarking + delivery audit, D7/O4) · backend#1184 (seal check + guarantee matrix, D12) · cli#393 (CLI seal-status surfacing) · backend#1185 (integrity RFC draft, D13) · backend#1186 (messaging alignment, §9) Work starts in parallel on the non-yours lanes now; PRs will reference the tickets. Review of v2.2 whenever you're ready → then Lukas merges this. |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 7c6bccf. Configure here.
…389) * fix(delete): verify the host-data wipe before printing ✔ removeHostDataDir did os.RemoveAll and returned nil without confirming the tree was actually gone; the caller then printed "✔ Removed local tracebloc data and config". A nil RemoveAll is not proof of absence (racing writer, mount, masked partial failure), so offboard could claim a clean slate it didn't achieve — the RFC-0003 offboard-hygiene gap. Now removeHostDataDir stats the dir after RemoveAll and treats "still present" (or an unexpected stat error) as a failure, so the caller prints the warn + manual-rm hint instead of ✔. Adds an osStat seam + a test proving delete does NOT claim success on an unverified wipe. Closes#388. Refs tracebloc/client#367, backend#1151, #366. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(delete): regenerate copy-catalog golden for the two verify strings The wipe-verify error messages are user-visible (surfaced via the "Couldn't remove local data (%v)" warn), so zz-all-strings.golden picks them up. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…olation; split composition to data-spaces RFC Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
LukasWodka
commented
Jul 23, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0909bce. Configure here.
…g-gated) (#368) * feat(installer): node-local storage prototype (RFC-0003 Option C, flag-gated) TB_STORAGE_MODE=node-local (default: hostpath, unchanged) switches the local k3d install to store datasets on k3s's built-in local-path provisioner INSIDE the node instead of bind-mounting ~/.tracebloc. Data then dies with `cluster delete`, is not a browsable host folder, and needs no chmod 777 — the RFC-0003 goal for the local install. - common.sh: TB_STORAGE_MODE flag + validation; C1 forces AGENTS=0 (single-node) since local-path is RWO/WaitForFirstConsumer and the shared data PVC is mounted by jobs-manager-spawned Jobs. - cluster.sh: node-local drops the -v ~/.tracebloc:/tracebloc@all bind-mount, KEEPS k3s local-storage (removes --disable=local-storage), and skips the world-writable host-dir pre-create. - install-client-helm.sh: node-local emits storageClass.create=false + name=local-path, hostPath.enabled=false; skips _ensure_release_dirs. - cluster.bats: cover both modes. Default (hostpath) path is byte-for-byte unchanged; existing installs on --reuse-values do not migrate. Refs #367, backend#1151, tracebloc/cli#366. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(installer): gate the second _ensure_tracebloc_dirs call for node-local install_client_helm() calls _ensure_tracebloc_dirs independently of create_cluster; the first gate missed it, so node-local installs still created empty world-writable ~/.tracebloc/{data,logs,mysql} dirs. Now node-local only ensures the base dir exists (for values.yaml + the install log) and skips the 777 data subdirs. Verified on a real tb-nodelocal install. Refs #367. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(installer): document TB_STORAGE_MODE in install-k8s.sh usage header The node-local storage flag (RFC-0003 Option C) was undocumented in the env-var overrides list. Add it alongside HOST_DATA_DIR with a one-line note on what node-local does (k3s local-path, no host dirs, AGENTS=0). Regenerated manifest.sha256 (install-k8s.sh is manifest-covered). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(installer): guard node-local storage mismatches (Bugbot #368) Two silent-misroute footguns Bugbot flagged on the node-local path: 1. node-local + HOST_DATASET_DIR: node-local forces hostPath.enabled=false, so a HOST_DATASET_DIR network export was accepted but ignored — datasets would land on ephemeral local-path storage (gone on 'cluster delete'). Combining the two is a documented follow-up (backend#743 + RFC-0003); validate_config now rejects the combo instead of misrouting. 2. Reusing a cluster built for the other storage topology: storage mode is baked in at create time (hostpath bind-mounts /tracebloc + disables k3s local-storage; node-local does neither). A node-local install onto a hostpath cluster requests a local-path StorageClass that was disabled (PVCs Pending); a hostpath install onto a node-local cluster points hostPath PVs at an unmounted /tracebloc (ephemeral). New _check_existing_cluster_storage_mode fails fast both ways, mirroring _check_existing_cluster_dataset_mount. The /tracebloc bind mount is the discriminator: present <=> hostpath cluster. Tests: cluster.bats 35/35 (5 new storage-mode cases), common.bats +1 (node-local + HOST_DATASET_DIR rejected). shellcheck: no new findings. Regenerated manifest.sha256 (cluster.sh + common.sh are manifest-covered). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(installer): node-local must force SERVERS=1 too, not just AGENTS=0 (Bugbot #368) The C1 single-node guarantee only forced AGENTS=0. But k3s server nodes are schedulable (unlike a full k8s control plane), so TB_STORAGE_MODE=node-local with SERVERS>1 still produced multiple nodes — the RWO local-path data PVC binds on one while jobs-manager Jobs land on another and stay Pending, the exact failure C1 exists to prevent. Now clamps both AGENTS=0 and SERVERS=1. Tests: common.bats +2 (node-local clamps both; hostpath leaves them untouched). shellcheck: no new findings. Regenerated manifest.sha256. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…GENTS=0 §5 C1 and the appendix said node-local forces AGENTS=0; the prototype (client#368) had to force SERVERS=1 too — k3s server nodes are schedulable, so SERVERS>1 still yields multiple nodes a Job could land on away from the local-path volume. Match the doc to the shipped code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Repo rename: the training-client code is now in `tracebloc-engine`, not `tracebloc-client` (§7bis, O6, appendix). Verified the cited paths exist there: core/utils/database.py:243 (get_sql_query_and_params), core/utils/general.py:21-33 (get_experiment_path), core/weights/base.py. - D19 line drift: the ingestor reuse/append branch spans 275-357, not 309-357 — the old range started after the "return existing table if already created" reuse check (line 275) that D19 actually removes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
shujaatTracebloc
commented
Jul 24, 2026
Review — RFC-0003Doc-only; all builds + fixtures-drift + Bugbot green, and it's already had heavy co-review (Lukas + Asad, v1→v2.3). Reviewed it as a design doc + verified the load-bearing §7bis code citations against the actual repos. Net: strong, unusually honest RFC — good to merge once the status line is reconciled. What stands out
Fix items
Design points (not blockers)
— @shujaatTracebloc (reviewed with Claude) |
Lands the drafted RFC-0003 — Dataset storage & offboard hygiene in
cli/docs/rfcs/(alongside 0001 and 0002), so it's version-controlled and reviewable.tb deleteshould leave a true clean slate (Problem A), and "your data stays within the secure environment" should be literally true — today datasets are world-readable host files bind-mounted into k3d, engineered to survive cluster deletion (Problem B).This PR just commits the doc; the decisions it raises are tracked in backend#1151.
Note
Low Risk
Documentation-only RFC; no runtime or deployment behavior changes in this PR.
Overview
Adds
docs/rfcs/0003-storage-and-offboard-hygiene.mdas the decided RFC-0003 (v2.3), versioned next to RFC-0001/0002. The PR is documentation only; execution is tracked on backend#1151 and linked tickets in §10/§12.The doc locks decisions D1–D20 (status DECIDED, not an open §7 menu): node-local storage (Option C) for local installs, offboard leftover-guard and verify-before-✔ (no heavy multi-path wipe), no data-copier migration, egress lockdown flip as a gate for the “golden box” claim, in-cluster scoping (mounts, per-experiment DB grants, pod hardening), and model-IP stance (watermark/audit, edge lifecycle hygiene, platform-side envelope encryption; TEE phase 2).
v2.3 introduces §7bis and D16–D20: per-ingestion immutable
ds_<ingestor_id>tables, no append/reuse in the ingestor, correction by drop + re-ingest, isolation via grant-scoped definer views (notWHERE ingestor_id), grandfathering existing shared tables; multi-org data spaces are explicitly split to a separate RFC inbackend.v2.1 errata in the same file corrects weight lifecycle: no durable in-environment weight store (D8/O1→D15 node-local default after one green training run).
Reviewed by Cursor Bugbot for commit 3a56fcc. Bugbot is set up for automated code reviews on this repo. Configure here.
Update 2026-07-22 — v2 pushed (
afe9cd1). See §10 decision log.