Uh oh!
There was an error while loading. Please reload this page.
feat(installer): default TB_STORAGE_MODE to node-local (client#456) - #808
Conversation
RFC-0003 D15: flip the local (k3s) installer default from hostpath to node-local so a fresh install gets the "delete means gone" storage model — datasets on k3s local-path inside the node, no ~/.tracebloc host dirs, wiped on `cluster delete`. Scoped to the Linux/macOS bash core; the Windows installer (install-k8s.ps1) stays hostpath (no node-local path yet — Linux/Windows scope is @saadqbal's D15 call, see the PR). - common.sh: canonical default -> node-local (still forces AGENTS=0/SERVERS=1) - cluster.sh, summary.sh, install-client-helm.sh: fallback defaults -> node-local - install-k8s.sh + docs/INSTALL.md: help/docs; hostpath is now the opt-out - manifest.sha256: regenerated for the changed installer scripts - tests: pin hostpath where hostpath-only features are exercised; add default->node-local assertions (C1 clamp, cluster create, values render) Closes#456 Epic: tracebloc/backend#1151 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ode-node-local-default # Conflicts: # scripts/manifest.sha256
Uh oh!
There was an error while loading. Please reload this page.
saadqbal
left a comment
There was a problem hiding this comment.
Reviewed the code properly; the mechanics are careful. Not approving, for three separate reasons — one
of them yours to decide, and none of them a criticism of the implementation.
The flip itself is clean. Every ${TB_STORAGE_MODE:-hostpath} fallback became :-node-local with
none missed — I checked all five files on the head. install-k8s.ps1 is untouched and stays
hostpath-only, and the k3s-components-agreement.sh tripwire noted at :3618-3626 still means a
Windows node-local path cannot land quietly. Forcing both AGENTS=0andSERVERS=1 with the C1
reasoning written down — k3s servers are schedulable, so SERVERS>1 still strands an RWO PVC — is the
kind of thing that would have been an incident if only agents had been forced.
I also went looking for the case that worried me most: an existing hostpath cluster silently switching
and orphaning ~/.tracebloc. It cannot — _check_existing_cluster_storage_mode detects the topology
from the server container's mounts and refuses. Fails closed, correctly. And you caught that theHOST_DATASET_DIR error could no longer say "the default hostpath mode".
Blocker 1 — Bugbot's High is right and I confirmed it. The flip changes who reaches that refusal:
it used to fire only for someone who explicitly asked for node-local, and now fires on an unmodified
re-run of every existing Linux/macOS install. For that population the only remedy the text offers is
recreating a working cluster; TB_STORAGE_MODE=hostpath is never mentioned. And :955 phrases it as
the operator's setting when it came from the new default. Detail on the thread.
Blocker 2 — Gate 1 has no evidence attached. The PR names it a merge-blocker and I agree; nothing
here or in CI covers a green node-local training run on a fresh dev install.
Blocker 3 — Gate 2 is a decision, and I am not going to make it by approving. I have put the
trade-off in front of Saadi. Your recommendation of Option 1 is reasonable and matches the issue, but
"a deliberate, documented OS default split" is a product call, not a review one.
One small thing the flip falsifies, outside the diff: install-k8s.ps1:2852 and :3619 both describe
node-local as a "Linux/k3s prototype". After this it is the shipped default on that platform. The
"no Windows path" half stays true; "prototype" does not. Worth a line in the same PR, per the
repo's own rule about statements a change makes false.
saqlainsyed007
commented
Aug 24, 2026
Local node-local verification (macOS, real k3d install) — storage/topology half of the D15 gate Ran a real
Not covered here: a green training run — macOS has no GPU passthrough, so that half of the gate (issue #456) still needs a dev Linux+GPU host. This verifies the storage model + single-node topology change only. |
aptracebloc
left a comment
There was a problem hiding this comment.
Reviewed the flip — the mechanical default change is clean and consistent (the common.sh canonical default plus every ${TB_STORAGE_MODE:-hostpath} fallback in install-client-helm.sh moved to :-node-local, and the HOST_DATASET_DIR error now spells out the TB_STORAGE_MODE=hostpath opt-out). But I'm holding, for three reasons beyond your own two D15 merge-gates:
1. The open Bugbot finding is valid and important — I verified it (High)._check_existing_cluster_storage_mode (cluster.sh) now hits its want==node-local && cluster_is_hostpath branch for every existing install — hostpath was the old default, so essentially every current cluster is hostpath. That branch offers only the recreate remedy (k3d cluster delete → re-run as node-local) and then hard-errors; it never surfaces the non-destructive TB_STORAGE_MODE=hostpath path that keeps the working cluster. So the flip steers existing users toward destroying a good cluster. The warning also prints TB_STORAGE_MODE=node-local when the var was unset and only the new default applied. Please add the "set TB_STORAGE_MODE=hostpath to keep this cluster" remedy to that branch and stop implying the var was explicitly set. This is the one I'd fix before the flip ships.
2. A comment is ahead of reality. In common.sh the new comment states "the green node-local dev training run closed the gate that #367 shipped this behind" — but Gate 1 in the description says that run hasn't happened yet ("evidence must be attached before un-drafting"). Keep the comment in sync with the gate: it shouldn't assert the run occurred until it has.
3. Your two explicit gates — the green node-local dev training run (Gate 1) and Saadi's Linux-vs-Windows scope call (Gate 2) — are the stated merge-blockers, so I'm not approving over them.
The flip itself is the right direction and the code is otherwise solid. Happy to approve once the Bugbot remedy is fixed, the comment matches the gate, and your two gates close.
— drafted with Claude Code
…default (client#456) Addresses the Bugbot High + @saadqbal review on #808. After the node-local default flip, _check_existing_cluster_storage_mode fires on an unmodified re-run of every pre-existing hostpath install, not just operators who chose node-local. The old text offered only "recreate as node-local" and phrased the mode as the operator's setting. - common.sh: record TB_STORAGE_MODE_SOURCE (explicit vs default). - cluster.sh: the node-local-onto-hostpath branch now leads with the keep-your-cluster remedy (re-run with TB_STORAGE_MODE=hostpath, no recreate), keeps the recreate-for-node-local path, and names the source — "node-local is the default now" vs "TB_STORAGE_MODE=node-local". - install-k8s.ps1: node-local is no longer a "prototype" — it's the Linux/k3s default since D15; the "no Windows path" half stays true (per the repo rule to fix statements a change makes false). - cluster.bats: assert the hostpath opt-out is offered + the default-source wording. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saqlainsyed007
commented
Aug 24, 2026
Thanks @saadqbal — thorough review, and the confirmations on the flip mechanics (all five files, the Addressing each point: Blocker 1 (Bugbot High) — fixed in c2ab1c9. The Doc-falsifies note — fixed, same commit. Blocker 2 (Gate 1 — training run) — agreed, still open. No code fix; it's the live gate. I ran and posted a storage-side verification on a real node-local install (single-node topology, Blocker 3 (Gate 2 — scope) — agreed, it's a product call. Option 1 is implemented as the proposed default and matches the issue, but it's yours/Saadi's to decide, not something to settle by approving. The PR stays unmerged pending that decision. CI + a fresh Bugbot pass triggered on c2ab1c9. |
saqlainsyed007
commented
Aug 24, 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 c2ab1c9. Configure here.
…ode-node-local-default # Conflicts: # scripts/manifest.sha256
aptracebloc
left a comment
There was a problem hiding this comment.
Re-reviewed — thanks for the fix.
Addressed (the important one): the Bugbot High is fixed correctly. _check_existing_cluster_storage_mode now leads with the keep-your-cluster remedy ("re-run with the old mode — no recreate needed") instead of steering existing hostpath installs toward a destructive recreate, and the warning distinguishes the explicit-node-local case from "node-local is the default now," so it no longer implies the var was set when only the default applied. Bugbot thread resolved. Good.
Still open:
- The
common.shcomment (point 2) is unchanged — it still states "the green node-local dev training run closed the gate," while Gate 1 in the description says that run hasn't been done yet. Please keep the comment in sync with the gate (soften it until the run's evidence is attached, or attach it). - The PR is now CONFLICTING against develop (
mergeStateStatus=DIRTY) — needs a develop merge. - Your two D15 merge-gates (Gate 1 dev training run, Gate 2 Saadi's Linux-vs-Windows scope call) are still the stated blockers.
I'll approve once the comment matches the gate, the conflict is resolved, and your two gates close.
— drafted with Claude Code
saadqbal
left a comment
There was a problem hiding this comment.
The Bugbot High is properly fixed, and the mechanism is right where it would have been easy to get wrong: TB_STORAGE_MODE_SOURCE is computed at common.sh:874, before the default is applied on the next line. Computed after, it would read "explicit" every time — and the wording branch depends entirely on it. Both arms have bats coverage.
The remedy text is now the right way round too: it leads with "re-run with TB_STORAGE_MODE=hostpath, no recreate needed", which is what an operator on an unmodified re-run of a pre-existing hostpath install actually wants, and the error line names both options rather than only the recreate. Updating the ps1's "prototype" wording in the same PR is the repo rule applied without being asked.
Two things still stand, and neither is mine to close.
Windows stays hostpath-only, so the PR as it sits implements Option 1 — bash core flips to node-local, Windows unchanged — which was your recommendation. That's the call I flagged as the team's rather than the reviewer's, and I'm not ratifying it in a review; flagging that the code has settled on it so the decision is being made explicitly rather than by default. The k3s-components-agreement.sh guard still means a Windows node-local path can't land quietly later, which is what makes Option 1 safe to take now.
And the dev-environment training run is still uncovered — CI exercises install and templating, not a real training cycle against the flipped default, and that gap is the same as it was.
Holding on CI regardless: 32 checks still running (the scan's rollup read SUCCESS, which was stale).
…n gate is closed (client#456) @aptracebloc review: the storage-model comment stated "the green node-local dev training run closed the gate", but that run hasn't happened — Gate 1 is still open in the PR. Soften to describe node-local as the D15 default superseding the #367 prototype, and point the training-run sign-off at client#456 rather than asserting it here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saqlainsyed007
commented
Aug 24, 2026
Thanks @aptracebloc — both of the items in my control are now cleared:
That leaves exactly your remaining two — Gate 1 (green node-local dev training run) and Gate 2 (Saadi's Linux-vs-Windows scope call) — both human, both still open, and both the stated conditions for approval. Auto-merge stays paused until they close. |
Uh oh!
There was an error while loading. Please reload this page.
…#2448) @saadqbal's sequencing flag on #819. He raised it as a note rather than an ask, but it is cheaper to remove the hazard than to coordinate around it. The paragraph said "In **hostpath** mode (the installer default)". client#808 (RFC-0003 D15) flips that default to node-local on the bash path -- so whichever of the two lands second silently makes the other's parenthetical false, and this one is in the README rather than a comment, i.e. the copy customers read. Reworded to describe both modes' data behaviour and name the knob that selects them (TB_STORAGE_MODE) without claiming which way it points. True under either merge order, so #808 needs no coordination with this PR at all. Deliberately did NOT write "the installer prints the mode": it only `log`s it to the install log (cluster.sh:681), so that would have been a new false claim in place of the old one. Verified: cluster.bats 138/138 (including the derived README-vs-hint guard), drift 18/18, check-style clean, manifest regenerated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…#817 probe under the flip Merges origin/develop (#809/#817). #817 adds _verify_nodes_see_host_data (a hostpath-only host-mount probe) to both installers. Review/Bugbot fixes on top: - cluster.sh guard_leftover_data: the "a fresh install would silently adopt it" warning is hostpath-only. Under node-local (the default) a fresh install does NOT adopt host data — it's stranded — so the lead line contradicted the very next node-local line. Make the lead mode-aware (Bugbot Medium, client#456). - cluster.sh:78: flip the one _verify_nodes_see_host_data fallback #817 added after the sweep — ${TB_STORAGE_MODE:-hostpath} -> :-node-local — so the whole tree carries a single default value again. - cluster.bats: pin TB_STORAGE_MODE=hostpath in #817's 17 probe tests (they exercise the hostpath-only probe; the sourced default is now node-local, which correctly skips it) and add two leftover-guard tests for the contradiction fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saqlainsyed007
commented
Aug 24, 2026
bugbot run |
saadqbal
left a comment
There was a problem hiding this comment.
Merge looks right, and the two things it had to get right, it got right.
The :-hostpath → :-node-local flip on the fallback #817 added at cluster.sh:78 closes the merge-order hazard cleanly — I checked and there's now no :-hostpath left outside the tests, so the tree carries a single default value again rather than two that agree by accident.
More importantly: pinning TB_STORAGE_MODE=hostpath in #817's probe tests was not optional, and I verified it's complete rather than taking the commit message for it. Every one of the 15 tests that actually invokes_verify_nodes_see_host_data pins hostpath; the 3 that don't are the deliberate node-local skip cases. Without that, all of them would have hit the early return and passed while exercising nothing — the probe's whole test suite going vacuous the moment the default flipped, silently. Worth noting the two the file mentions without calling (the grep-based wiring test and a fail-cgroupv1 case) genuinely don't need it.
Bugbot's leftover-guard Medium is fixed properly too: the lead no longer claims a fresh install would adopt the data when node-local means it would be stranded, so it stops contradicting the line beneath it.
Unchanged from before, and still not mine to close: the dev-environment training run CI doesn't cover, and Option 1 (Windows stays hostpath) as the team's call rather than a reviewer's. Holding on CI — five checks running.
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 9599fe6. Configure here.
saadqbal
left a comment
There was a problem hiding this comment.
Green, no open threads, and everything I raised across the passes is addressed — approving the code.
Two things this approval explicitly does not cover, because neither is a reviewer's to sign off:
The rollout shape. Windows stays hostpath, so this is Option 1 rather than Option 2. That's your recommendation and it's deliberate — the k3s-components-agreement.sh guard means a Windows node-local path can't land quietly later, which is what makes taking Option 1 now safe rather than a deferral. But it's a rollout decision for you and Asad, not something I'm ratifying by approving; I'm approving that the code implements it correctly.
The dev-environment training run. CI covers install, templating and the guards; it does not run a training cycle against the flipped default. That gap is unchanged and unclosable from here — worth doing before this lands, and it needs a human.
On the code itself, the things I checked and would own: the flip forces AGENTS=0/SERVERS=1 so an RWO PVC can't be stranded across schedulable servers; TB_STORAGE_MODE_SOURCE is computed before the default is applied, which is the only order that works and the whole wording branch depends on it; the mismatch guard leads with the keep-your-cluster remedy rather than a recreate nobody asked for; the leftover-guard lead is mode-aware so it no longer claims adoption where the data would be stranded; the :-hostpath sweep is complete so the tree carries one default value; and every probe test that actually invokes #817's guard pins hostpath, so the suite didn't go vacuous when the default moved.
…8) (#819) * feat(installer): move the Kubernetes pin to v1.36.3-k3s1 (backend#2448) We pinned v1.29.4-k3s1, ~18 months past EOL (1.29 EOL 2025-02-28). Only 1.33-1.36 are supported today. And the fleet was already drifting past the pin on its own -- install-k8s.ps1 records a customer running k3s v1.35.5 against it -- so this is not "hold the line", it is "the line was already gone and untested". Lifecycle, not features. Do not read this as unlocking in-place pod resize: that has no actor today (training pods have automountServiceAccountToken: false, the NetworkPolicy blocks the apiserver, and jobs-manager has no pods/resize RBAC), and Kueue conflicts with it upstream (#5257). TARGET 1.36.3 DIRECTLY, no 1.34 stepping stone: a freshly created cluster is exempt from the no-skip-minor rule, so two rebuilds buy nothing. Spike backend#2422 answered all six questions on a real cluster -- k3d v5.9.0 creates a working v1.36.3+k3s1 cluster (node Ready, CoreDNS up, pod schedulable), the containerd 2.x config path holds, and k3d's registries.yaml translation still works. No newer k3d needed; this was never "wait for upstream". THE TAG IS v1.36.3-k3s1 WITH A HYPHEN. The k3s RELEASE is v1.36.3+k3s1, but Docker tags cannot contain `+`, so rancher publishes the hyphen form. Verified against registry-1.docker.io: `v1.36.3-k3s1` -> 200, `v1.36.3+k3s1` -> 404. The ticket text quotes the release string; the pin has to be the image tag. DERIVED, NOT RESTATED. scripts/spec/facts.env is the single source of truth and `check-facts.sh --write` stamps it into every consumer, so the version itself is a one-line change reaching 7 consumers. What needed work was the places that were NOT derived: * The HELP TEXT default is now its own check-facts consumer row in both installers. It was a restate the script could not see: the pin would move in code while `--help` went on advertising the old version, with only a golden-file diff to notice. Two new rows (common.sh:K8S_VERSION-help, install-k8s.ps1:K8S_VERSION-help), mutation-proved by reverting one of them. * check-facts.bats seeded its fixture consumers from LITERALS -- a second copy of every pin. This bump turned the whole suite red because the fixture disagreed with the spec it had just copied. It now derives the seed values from that copied spec, and is proven pin-agnostic: the suite stays green with the pin set to 1.29.4, 1.33.9 and 9.9.9. * cluster.bats had a test named "NOT passed on the currently pinned k3s (1.29.4 predates the flag)" that hardcoded 1.29.4 -- so it sailed through this migration still green while NOTHING asserted the behaviour of the version we actually ship. Renamed to what it really covers (a pre-1.31 version), and a new test DERIVES the pin from facts.env and asserts the cgroup v1 override is emitted for it. That test reddens when the pin is rolled back below 1.31 and fails closed when facts.env is unreadable. THE DRIFT WARNING WOULD HAVE LIED TO EVERYONE. k3s's version is fixed at cluster create, so every pre-existing cluster is now "drifted" -- the warning fires for the whole installed base. Its text blamed "an older/unpinned installer or K8S_VERSION=latest", which is not what happened to those operators: their cluster simply predates the pin move. Reworded in both twins to name that cause first, with a test that reads the pin from facts.env, simulates a 1.29.4 cluster, and asserts the message does not misattribute it. It WARNS and does not refuse, so re-runs on an older cluster keep working. Also regenerated/kept in step: the 00-install golden (one line -- which is the proof the help text is the operator-visible surface), the base64-embedded copy of the GPU Dockerfile inside install-k8s.ps1 (the drift guard caught it; the decoded delta is exactly the one ARG line, asserted in the re-embed), docker/k3s-cuda README examples, both installer header comments, and the manifest. README gains an operator note: a new install gets the pinned version, an EXISTING cluster keeps the version it was born with, and moving it means recreating the cluster -- with the data behaviour of each storage mode spelled out. Two things deliberately NOT changed: * The `1.31.0` literal in the cgroup gate. That is the release that ADDED --fail-cgroupv1, not our pin, and it must not track the pin. * The v1.35.5 drift-incident narrative comments that mention 1.29.4. They describe a past incident accurately; rewriting them would falsify history. The Windows GPU path does NOT depend on a prebuilt image for the new tag: the default path BUILDS the node image locally (install-k8s.ps1:6817 -> Build-GpuNodeImage) with --build-arg K3S_TAG=$K8S_VERSION, and only reaches for a prebuilt one when TRACEBLOC_K3S_CUDA_IMAGE or TRACEBLOC_IMAGE_REGISTRY is set. So GHCR does not gate this. Air-gapped/mirror customers do need the new tag in their mirror, and publishing ghcr.io/tracebloc/k3s-cuda:v1.36.3-k3s1-cuda-12.4.1-base-ubuntu22.04 (the workflow default is already bumped here) is worth doing as hygiene. Verified: cluster.bats 119/119, check-facts.bats 14/14, Pester install-k8s 736 passed / 0 failed / 13 skipped -- byte-identical to this base's develop baseline, measured by stashing -- plus copy-catalog, check-drift, check-style, gen-manifest, assess, common, hostpath-prep, bats-hygiene, chart-version-guard, gpu-embed-drift and check-digest-drift all green, `make drift` 18/18, bash -n clean on all four touched shell files, shellcheck -S warning -x at develop's baseline count. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(readme): release the secure environment BEFORE deleting the cluster (backend#2448) Bugbot's finding, and it is the most consequential thing on this PR. My pin-move note told operators to recreate with a bare `k3d cluster delete`. Both installers explicitly warn against exactly that: "Release this machine's secure environment BEFORE deleting the cluster -- it is anchored to the cluster's identity, so deleting the cluster first strands it on your dashboard for good" and print `tracebloc delete --keep-data` first. Verified in both twins (_recreate_cluster_hint / Write-RecreateClusterHint) rather than taking the finding on trust. WHY IT MATTERS MORE HERE THAN ANYWHERE ELSE. k3s's version is fixed at cluster create, so this pin move is precisely what forces a rebuild across the whole installed base -- which makes this README paragraph the most-followed recreate instruction in the repo the moment it ships. Following it as written would have stranded the backend secure-environment record for every one of those customers. That is a worse outcome than the EOL pin it exists to fix. Now the same two-step the installer prints, as a copyable block, with the reason stated rather than implied, and the "nothing installed yet? just the k3d line" carve-out kept. GUARDED, DERIVED, not restated. A new test reads the release command OUT OF _recreate_cluster_hint and requires the README to carry it -- and to carry it BEFORE the k3d delete, since the ordering is the entire protection. A guard that hardcoded "tracebloc delete --keep-data" would have agreed with itself while the hint moved on. Mutation-proved three ways, each reddening for its own reason: * README reverted to the k3d-only line -> "omits the release step the installer prints" * README lists the k3d delete first -> "puts the k3d delete (line 76) before the release (line 77)" * the HINT's command renamed in cluster.sh -> guard follows the hint and fails, proving it is derived rather than matching a literal Verified: cluster.bats 138/138, copy-catalog current, `make drift` 18/18, check-style clean, shellcheck -S warning -x at baseline (2), bash -n clean, manifest regenerated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(readme): don't assert which storage mode is the default (backend#2448) @saadqbal's sequencing flag on #819. He raised it as a note rather than an ask, but it is cheaper to remove the hazard than to coordinate around it. The paragraph said "In **hostpath** mode (the installer default)". client#808 (RFC-0003 D15) flips that default to node-local on the bash path -- so whichever of the two lands second silently makes the other's parenthetical false, and this one is in the README rather than a comment, i.e. the copy customers read. Reworded to describe both modes' data behaviour and name the knob that selects them (TB_STORAGE_MODE) without claiming which way it points. True under either merge order, so #808 needs no coordination with this PR at all. Deliberately did NOT write "the installer prints the mode": it only `log`s it to the install log (cluster.sh:681), so that would have been a new false claim in place of the old one. Verified: cluster.bats 138/138 (including the derived README-vs-hint guard), drift 18/18, check-style clean, manifest regenerated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…ode-node-local-default # Conflicts: # scripts/manifest.sha256
aptracebloc
left a comment
There was a problem hiding this comment.
Re-reviewed at 96289c5. Code side is clean from my end — nothing left to change.
- The
common.shcomment I flagged is fixed in2d898b1(it now points the training-run sign-off at #456 instead of asserting the gate closed). - Both Bugbot threads are resolved — the destructive-remedy High (
c2ab1c9, keep-your-cluster remedy leads +TB_STORAGE_MODE_SOURCEwording) and the ps1 "prototype" doc note. - Conflict against develop resolved in
3a3b407; back toMERGEABLE. - CI is fully green (the only non-passes are the conditional jobs that skip by design).
So there are no code concerns and no open review threads on my side. I'm deliberately not stamping approve yet, and it's purely your own two gates — not anything in the diff:
- Gate 1 — the green node-local training run on a dev Linux+GPU host. Your storage-side verification (single-node clamp,
local-pathSC, no/traceblocbind, delete-means-gone) covers the topology half convincingly, but the training-run half is still open. - Gate 2 — Saadi's Linux-vs-Windows scope decision.
An approval tells the merge tooling it's ready to land, and this must not land before Gate 1 closes — so the honest stamp here is "code-approved, held on the gates." Attach the Gate 1 run and get Saadi's Gate 2 call, and I'll approve on the next pass without re-litigating any of the above.
— drafted with Claude Code
saqlainsyed007
commented
Aug 24, 2026
|
Uh oh!
There was an error while loading. Please reload this page.
saqlainsyed007
commented
Aug 25, 2026
✅ Gate 1 satisfied — green node-local + GPU training run on devThe training-run gate that was overridden at merge is now met, verified on a real dev install:
So both halves hold on dev: node-local dataset storage works end-to-end, and a real GPU training cycle completes green. The merge-time override of this gate is now discharged. Separately, this run surfaced several installer bugs (GPU-on-Linux-k3d, |
saqlainsyed007
commented
Aug 25, 2026
Gate 2 — Linux/Windows scope: proceeding as Option 1Recording the scope decision for the record. The flip ships as Option 1: the Linux/macOS (bash-core) installer defaults to node-local; This is noted as settled — not blocking on a separate formal ratification. Option 1 is the recommended and implemented path; the follow-up for a Windows node-local story is tracked under the Windows installer epic, not here. |
What & why
RFC-0003 D15 — flip the installer default for
TB_STORAGE_MODEfromhostpathto node-local on the Linux/k3s (bash-core) install path. node-local shipped as a flag-gated prototype in #367/#368; this makes it the default so a fresh local install gets the RFC's "delete means gone" storage model (datasets live inside the k3d node on k3slocal-path, no world-writable~/.traceblocdirs, wiped bycluster delete).Closes#456. Epic: tracebloc/backend#1151. RFC: tracebloc/cli#366 §10 (D15).
Un-drafted so review can proceed. Reviewers/mergers: this must not merge until both gates below are closed — the draft flag no longer guards it, so the hold is manual.
Gate 1 — one green node-local training run on a fresh dev install (MERGE-BLOCKER)
The issue requires this before the flip. The old blocker (tracebloc/backend#1180,
/dataset/admin/401 on dev) is fixed (2026-08-20), so the run should now pass — but it is a live run needing dev credentials, private images, and a Linux GPU node, which this session could not execute (macOS, no dev creds, no GPU passthrough). CI'se2e-clusterdeliberately stops before the helm install + registration + training, so nothing automated covers it either. This gate needs a human/CI run on dev; evidence must be attached here before un-drafting. Repro:Gate 2 — Linux-only vs Windows scope decision → @saadqbal's call (do not merge until decided)
node-local is a Linux/k3s path only;
install-k8s.ps1has no Windows implementation. This PR implements Option 1 (flip the bash core, leave Windows on hostpath) because it is what unblocks the RFC-0003 storage claim without waiting on a Windows design — but the scope is explicitly Saadi's decision, not mine.install-k8s.shdefaults to node-local;install-k8s.ps1stays hostpath; the split is documentedMy recommendation: Option 1 (matches the issue's stated recommendation). If Saadi prefers Option 2, this PR should be held, not merged-and-reverted.
Changes
scripts/lib/common.sh— canonical default${TB_STORAGE_MODE:-node-local}; node-local still forces single-node (AGENTS=0,SERVERS=1). Comment block rewritten (node-local = default, hostpath = opt-out).scripts/lib/{cluster,summary,install-client-helm}.sh— every${TB_STORAGE_MODE:-hostpath}fallback flipped to:-node-localso the effective default is identical in the real installer and in isolated/unit contexts (incl. the existing-cluster storage-mode mismatch check). Removed a stale "(default)" from a hostpath warning.scripts/install-k8s.sh— help text: default is now node-local; documentsTB_STORAGE_MODE=hostpathas the opt-out and the Linux-only scope.docs/INSTALL.md— dataset-staging section: node-local is the default (no host folder →kubectl cp); hostpath staging is now the opt-out / Windows path.scripts/manifest.sha256— regenerated for the changed installer scripts (supply-chain manifest).TB_STORAGE_MODE=hostpathexplicitly (HOST_DATASET_DIR and bind-mount are hostpath-only), and added default→node-local assertions at three layers: the C1 single-node clamp (common.bats), cluster creation (cluster.bats), and renderedvalues.yaml(install-client-helm.bats).copy-catalog.batsgolden pins hostpath (it tests copy strings, not topology).Release notes (topology change)
Verification
CI (authoritative):
Lint✅ ·Source-of-truth drift✅ (manifest + env/facts vocabulary) ·bats (bash unit, mocked)✅ — the full mocked bats suite passes on CI with this change.Local (macOS):
make lint— green (53 scripts parse; shellcheck 60 files @error, clean)make drift— all 17 guards green (incl.check-facts,env-vocabulary-agreement, regeneratedmanifest.sha256)common.bats+cluster.bats(199/199), and the storage-relevant tests ofsummary.bats,leftover-guard.bats,copy-catalog.bats(golden),install-client-helm.batsall green, including the new default→node-local assertions.assess/doctor "healthy → home screen" tests that fail identically on cleandevelopon this Mac (CLI-present path) — unrelated to this change, and green on CI.🤖 Generated with Claude Code
Note
High Risk
Changes the default local-install storage topology and node count for every new macOS/Linux k3s install, including data lifetime (
cluster deletewipes datasets). Existing-cluster mismatch handling is the main upgrade-path risk; Windows is unchanged.Overview
Flips the Linux/macOS k3s installer default from hostpath to node-local (
TB_STORAGE_MODE). Fresh local installs now keep datasets on k3slocal-pathinside the node (wiped bycluster delete, no world-writable~/.traceblocdata dirs) and are forced single-node (AGENTS=0,SERVERS=1). Hostpath is an explicit opt-out; Windows (install-k8s.ps1) stays hostpath-only.Existing clusters are not rewritten: the storage-mode mismatch guard still refuses a topology clash, but after the flip it treats an unmodified re-run of a hostpath cluster as the new default (not “you asked for node-local”) and leads with
TB_STORAGE_MODE=hostpathto keep the cluster. Leftover-data copy no longer claims a node-local install would “silently adopt” host data.Installer fallbacks, Helm values, summary text, and INSTALL.md staging notes follow the new default. Tests pin hostpath where they still need bind-mounts/
HOST_DATASET_DIR, and add default→node-local assertions for cluster create, the C1 clamp, and renderedvalues.yaml.Reviewed by Cursor Bugbot for commit 96289c5. Bugbot is set up for automated code reviews on this repo. Configure here.