Uh oh!
There was an error while loading. Please reload this page.
Conversation
main's promote-merge commits (#148, #155) aren't in develop's ancestry, so the next develop→main promote would conflict on release drift again. Trees are already identical (v0.6.0 == develop), so this changes no files — it only brings main's history into develop so future promotes fast-forward cleanly.
…op-2026-07-07 chore: back-merge main → develop (reset promote ancestry after v0.6.0)
test(preflight): pin #152's schema-type-aware label diversity in the parity harness
…+ single-machine CLI scope (#157) Decided by Lukas 2026-07-07. Two coupled decisions: - The CLI is scoped to THIS machine (one client per machine — the §7.2 anchor); the account's fleet lives in the web-UI. So `client use` is removed and `client list` is internal-only (hidden; still callable for the installer pre-flight). Amends the §6.2 surface; folds in the cli#136 client-surface prototype. - Offboarding is a top-level `tracebloc delete` (not `client delete --uninstall`): a SOFT offboard that revokes the machine credential, tears down the local install, wipes local data, and RETAINS all backend artifacts (client record, dataset catalog, use cases, trained models) as history. A hard row-destroy is REJECTED — it would cascade the client's training telemetry (weight refs, confusion matrices, carbon). New §7.10 (design of record) + Rev 9 callouts on §6.2/§7.4; R12 flipped to addressed; C.6 corrected to name the built machine-revoke endpoint (POST /edge-device/<id>/revoke, backend#886) and note DELETE is unrouted. Supersedes the cli#136 proto's client delete/DELETE offboarding draft. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…beddings (#162) (#163) The Schema drift check (scripts/sync-schema.sh --check) was red on every open PR: internal/schema/ingest.v1.json had drifted from upstream tracebloc/data-ingestors@master, which added two task categories (sentence_pair_classification, embeddings), a content_hash data_id strategy, and description updates. - Re-vendor the current upstream schema (sync-schema.sh). - Add both new categories to categoryRegistry as FamilyText (they stage raw .txt from texts/, per data-ingestors conventions.py TEXT_CATEGORIES). - Mark both CLISupported: false with an UnsupportedNote, mirroring causal_language_modeling/seq2seq/token_classification, until the `tracebloc ingest` discover/build staging path for them is confirmed. (Flip to true if the push path already supports them.) - Update the pinned lists in category_registry_test.go. Fixes the registry⇄schema parity test (TestRegistryCoversSchemaCategories) that a bare schema sync would otherwise break. go build/vet/test green. Closes#162 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ace (§7.10) (#160) * feat(nodeboot): node teardown seam for offboarding (RFC-0001 §7.10) Add internal/nodeboot — the inverse of the installer's node bootstrap that `tracebloc delete` will drive. Based on the cli#136 prototype's k3d/helm teardown, with an injectable Runner exec seam: - ClusterExists(name) / TeardownCluster(name) — `k3d cluster delete` when the cluster exists (also prunes its kubeconfig entry); a missing cluster is an idempotent no-op. - UninstallChart(namespace) — `helm uninstall`, swallowing not-found. - PruneImages() — NEW beyond #136: reclaim tracebloc images, SCOPED to `ghcr.io/tracebloc/*` (docker images -q | docker rmi), deduped, best-effort. NEVER a blanket `docker system prune`. All four are unit-tested against a fake Runner — no real k3d/helm/docker runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(cli): top-level `tracebloc delete` offboarding (RFC-0001 §7.10) Add `tracebloc delete` — a top-level command (NOT `client delete --uninstall`): on the single-machine CLI the host owns one client, so "delete the client" is "remove tracebloc," and a top-level verb avoids colliding with `data delete`. A SOFT offboard with a removed / retained / left three-way summary shown before a TYPED-CLIENT-NAME confirm (skipped only with --yes). Flow, in order: - guard: refuse if the client is online / has a running job unless --force (reuses the #146 lookupClientStatus / clientStatusOnline); - api.RevokeClient(id) → POST /edge-device/<id>/revoke (NEW; 2xx = revoked) — kills the credential while PRESERVING the row (never a hard destroy that would cascade the retained training history); - nodeboot.UninstallChart → TeardownCluster → PruneImages (best-effort warns); - rm -rf HOST_DATA_DIR (~/.tracebloc) unless --keep-data; - remove the running CLI binary + its sibling `tb` symlink LAST (best-effort; on failure prints the exact rm, or `brew uninstall tracebloc` if brew-managed). Never removes Docker/Homebrew/kubectl/k3d/helm/NVIDIA, never reboots, never `docker system prune`. Flags: --yes / --keep-data / --force + the standard --kubeconfig/--context/--namespace; uses the existing exitError contract. Tests (fake nodeboot Runner + httptest backend + temp HOST_DATA_DIR + temp config dir; no real ~/.tracebloc, k3d/helm/docker): (a) no --yes non-interactive refuses with no side effects; (b) --yes runs the full sequence — revoke POSTed to /edge-device/<id>/revoke, nodeboot fakes called in order, ~/.tracebloc removed; (c) --keep-data spares ~/.tracebloc; (d) running job refuses unless --force; (e) the RETAINED + LEFT copy is present in output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(cli): withdraw `client use`, hide `client list` (RFC-0001 §7.10) The single-machine CLI owns exactly one client, so there is nothing to select: - Remove `client use` (newClientUseCmd + runClientUse + its AddCommand entry + TestClientUse). The active-client pointer is now set only by `client create`. - Hide `client list` (Hidden: true) — kept callable for the installer's one-client-per-machine pre-flight, off the user-facing surface. - Rewrite the `client` parent help and the root home-screen: drop the `client list` line, add `tracebloc delete`, point offboarding at it. - Retarget the residual "run `client use`" guidance (create save-failure fallback, client status, doctor, clustertarget "runs elsewhere" + multi-namespace refusal) to `client create` / --namespace, and adjust the test that asserted the old string. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(cli): correct data-delete catalog copy — kept, not removed (RFC-0001 §7.10) The catalog metadata for a deleted dataset is NEVER removed — it is kept as a record on tracebloc and marked unavailable (soft-flagged). The old "removed automatically" copy in `data delete` help + its success line, and the push.TeardownPlan doc comment, wrongly implied the backend deletes it. Reword all three to "kept as a record on tracebloc, marked unavailable." Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(cli): redirect the save-failure hint off the removed `client use` Review finding (medium): the client-create config-save fallback still pointed at `tracebloc client use %d`, which T3 removes. Point it at `client create` (idempotent — it re-adopts this cluster's client). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(cli): address delete-offboard review findings (§7.10) Review follow-ups on the tracebloc delete offboarding PR: - api: RevokeClient POSTs to /edge-device/<id>/revoke/ WITH a trailing slash — the DRF DefaultRouter registers the `revoke` @action as /edge-device/<pk>/revoke/, and a slashless body-bearing POST hits Django's APPEND_SLASH (which errors instead of redirecting), aborting the whole offboard at step 1. - cli: a 403 on revoke now speaks in offboard terms ("offboarding requires CLIENT_WRITE") instead of the provisioning copy the shared askAnAdmin hardcoded; askAnAdmin takes action/capability params. - cli: an empty namespace warns + points at --namespace instead of silently skipping the Helm uninstall while the summary claims success. - nodeboot: UninstallChart matches helm's specific "release: not found", not a bare "not found" that could swallow a cluster-unreachable error. - cli: --force help no longer advertises a running-job check the guard doesn't implement. - cli: looksBrewManaged resolves symlinks so the Intel /usr/local/bin → Cellar install gets the `brew uninstall` hint. - config: correct stale `client use` comment. Tests added for each behavioral fix; go build/vet/test green (11 pkgs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Asad Iqbal <asad.dsoft@gmail.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…inter under --keep-data (#165) Two Cursor Bugbot findings on the develop->main PR (#164): - High: `tracebloc delete` registered --kubeconfig/--context but runDelete never read them, so `helm uninstall` ran against the ambient current-context — offboarding could uninstall the wrong release when the operator's context isn't the tracebloc cluster. UninstallChart now takes kubeconfig + kubeContext and appends --kubeconfig/--kube-context (only when set, preserving default-context behavior); runDelete threads the flags through. (k3d cluster delete targets the cluster by name, so it's context-independent.) - Medium: under --keep-data, offboard revoked the credential but left the active-client pointer in ~/.tracebloc, so a later sign-in/reinstall still saw the host as enrolled as the (now-revoked) client. Clear ActiveClientID/Name/Namespace even under --keep-data (token + on-host data stay; re-running `client create` re-adopts by cluster_id), per §7.5. Tests: flags reach helm (unit + delete-level); --keep-data clears the pointer while sparing the data dir. go build/vet/test green (11 pkgs). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
…p stale client-list hints (#168) Thorough review pass on the develop->main PR (#164), addressing the new Bugbot finding plus adjacent gaps a review flagged: - Stale client pointer after a failed wipe (Bugbot): after revoke, if `rm -rf ~/.tracebloc` failed the default path left the active-client pointer intact (the --keep-data path cleared it). Now the pointer is cleared in memory once after revoke and persisted in BOTH paths, incl. the wipe-failure branch — the host never looks enrolled under a dead credential. - Misleading success line: the closing "Offboarded … no longer connected" printed unconditionally even when uninstall/teardown/wipe left real state behind (all best-effort warns). Track a `degraded` flag over the state-leaving steps and print an honest closing that tells the user to finish the flagged steps by hand. (Image reclaim is pure disk cleanup — excluded; exit stays 0 since the credential revoke, the core, succeeded.) - Online guard: a stored id not in the signed-in account (found=false) now emits a hint instead of silently passing the guard. - Stale copy: `client status` errors pointed at the now-hidden `client list`; retargeted to `client create` / the installer, matching the phrasing used elsewhere. Fixed a `create/use` comment (use removed). Tests added: wipe-failure clears the pointer; a failed teardown produces the degraded closing. go build/vet/test green (11 pkgs). Rolls up under the §7.10 offboarding work (Bugbot follow-up). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
#166) (#167) The CLI streams a full copy of the dataset into SharedRoot/.tracebloc-staging/<table>, and the in-cluster ingestor COPIES (shutil.copy, never moves) those files into the final table dir. So after a successful `tracebloc data ingest` BOTH copies lived on the shared PVC — the staged source was only ever removed by `data delete` or an `--overwrite` re-ingest. Every successful push of a file-bearing dataset silently doubled PVC usage, eventually surfacing as "no space left on device" on a later ingest with no signal as to why. Add push.CleanStaging: a best-effort rm -rf of ONLY StagedPrefix(table) via the same ephemeral stage-identity pod Teardown already uses (it runs as the uid that wrote the staging files, so the rm works by ownership on hostPath and CSI alike). It never touches the final table dir or the MySQL table. runDataIngest calls it after a CLEAN success only (classifyPushOutcome == "succeeded"), so it never fires on --detach (the Job is still reading the source), completed_with_failures, or any failure. A failed reclaim logs a warning and does not fail the ingest. Robustness (from pre-PR adversarial review, all low-severity): - the reclaim's wait+exec is bounded by StagingCleanupTimeout (45s) so a stuck/unschedulable cleanup pod can't tack the full pod-ready timeout onto a command the user already saw succeed; - the cleanup pod is created under a detached context so a parent-ctx cancel in the create window can't orphan a server-committed pod; - with --output-json the result object is emitted BEFORE the reclaim, so scripted consumers get their result at ingest-completion latency. Longer term the cleaner fix is server-side (ingestor move-not-copy / remove SRC after a verified load) — will file a data-ingestors follow-up. Closes#166. Refs #67. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…save fix(cli): delete guard fails fast on 426; keep-data save failure marks offboard degraded
Uh oh!
There was an error while loading. Please reload this page.
…171) `removeSelf` deleted any sibling file named `tb` (guard was only `tb != exe`), with no check that it was tracebloc's own symlink. If a user had an unrelated `tb` on the same PATH dir tracebloc installed into (another tool's binary, or a symlink elsewhere), `tracebloc delete` removed it — wrong-target deletion of a file tracebloc never created. Make delete symmetric with install. The installer refuses to clobber a pre-existing `tb` (install.sh: creates it only when absent or when `readlink tb == PREFIX/tracebloc`). Delete now mirrors that: new aliasStatus() removes `tb` only when it is a symlink resolving to this binary; a regular file or a symlink pointing elsewhere is left in place with a note ("isn't tracebloc's `tb` alias"). Relative targets resolve against the link dir, and an EvalSymlinks fallback covers the case where the binary itself is a symlink (Intel Homebrew). Found in the FR review of the offboarding surface; not a Bugbot finding. Tests: TestDelete_OwnTBAlias_Removed (real tb->binary symlink is removed), TestDelete_ForeignTBAlias_Left (a foreign regular-file `tb` is NOT removed and is reported), and the full-sequence test now lays down a real symlink. The foreign-tb test is verified to fail without the guard. Suite + vet green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
) The `tracebloc data ingest` run worked but spoke Kubernetes and went silent at the worst moment. Three UX fixes surfaced by the ingest-flow audit: 1. Silent hang after submit. WatchJob's waitForJobPod polls up to 5 min (PodReadyTimeout) for the ingestor Pod to schedule + pull its image, printing nothing — the CLI looked hung right after the key step. Now a live spinner ("Waiting for the ingestion to start…", with a Ctrl-C hint) covers that wait, then a clean "Ingestion started — live progress:" precedes the log stream. WatchJob takes a nil-safe *ui.Printer for this; nil (tests) stays silent as before. 2. Undisclosed 1-hour watch cap. JobWatchTimeout is 1h; on expiry the CLI silently "detached". Step 4 now discloses the follow window up front — and only when NOT --detach (the hints used to promise streaming even under --detach, which was itself dishonest). 3. Kubernetes jargon on the happy path. Reworded the run narrative to plain language: upload-channel wording instead of "stage Pod", "Submitted — tracebloc is validating your data…", "Connecting to your workspace to submit the run…", and plain detach/timeout messages. The raw `kubectl logs` reconnect stays (there is no CLI re-attach verb yet) but as a labelled optional follow, not jargon in a sentence. From the pre-PR adversarial review: the green "✔ Ingestion started" now only shows for a live/completed pod — a Pod already Failed (immediate crash, or a prior backoffLimit retry) gets a neutral "streaming logs:" line instead of a success checkmark before its crash output (waitForJobPod now returns the selected pod's phase). The pod-wait-timeout detach message no longer claims "you don't need to do anything" (false for the PSA-rejection / unschedulable subcases the same path covers). No control-flow or exit-code changes — output copy + one nil-safe progress-reporter param. Tests updated for the reworded strings + the new waitForJobPod phase return. Closes#172. Part of the data ingest UX sweep (epic #67). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nomy (#174) * docs(rfc-0002): tracebloc data ingest — flow, terminology & task taxonomy Draft RFC capturing the ingest-UX redesign discussed with Lukas: - Invert the flow: ask for the DATA first, sniff the family from the layout, then offer only the compatible tasks — instead of the current task-first 16-item wall shown before anything is known about the data. - Accept a flexible input path (a bare .csv for tabular/time, a directory otherwise) — today every family requires a directory, even tabular. - Never "upload/push/stage" in user copy — the data stays on the user's own infrastructure; "ingest" umbrella, "copy into your storage" for the move. Rename --category -> --task (required), --intent -> --split. - Reduce ceremony: one environment, so drop "Connect to your workspace" and the cluster/PVC fields; Kubernetes behind --verbose. - The 15 ML tasks with data-scientist-facing names + one-liners (HF / scikit-learn / Papers With Code research); the label column is task-specific (skipped for the self-supervised text tasks). - The taxonomy contract: the task list is duplicated in 5 places across 3 repos with one enforced edge; make the schema enum the single source of truth + cross-repo drift checks. - Phased delivery incl. wiring the 5 CLI-pending text tasks so the CLI matches the platform. Grounded in a code-level audit of CLI develop + the ingestor + the backend. Supersedes the copy in #173 where they conflict. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(rfc-0002): Rev 2 — split→name→path order, file-or-folder echo, label column task-specific Per discussion with Lukas: settle the Phase-1 prompt order (train/test → name → path → task), make the file-or-folder mental model explicit (point at your data in whatever shape it has; the "Found ..." echo removes the confusion), and move the label column fully into the task-specific questions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(rfc-0002): Rev 3 — label design (kill #340 silent-null) + full 15-task input matrix Rewrite the label section: three shapes (class/target/absent), precise per-family wording (never the ambiguous "label to predict"), and pick-from-real-headers + exact-match-or-hard-fail validation that closes the data-ingestors#340 case-mismatch silent-NULL-label bug. Add the full task-specific input matrix for all 15 tasks. New reconciliation open questions (drop vestigial --label-column for sidecar-labeled vision, forecasting timestamp gap, target_size placement, schema-for-regression). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(rfc-0002): Rev 4 — settle the 4 reconciliation decisions Per Lukas: drop --label-column for sidecar-labeled vision (object detection/keypoint/segmentation); forecasting gets a first-class timestamp prompt + preflight; normalize --target-size to file_options; surface inferred schema for confirmation on the regression family. Task display names remain under review (decoupled from the wire task_id). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…of exiting 0 (#75) (#175) `tracebloc data ingst` (and cluster/auth/client typos) printed the group's help and exited 0, silently swallowing the mistake. A parent command with subcommands but no Run/RunE is "not runnable", and cobra short-circuits a non-runnable command to flag.ErrHelp BEFORE it validates args — so the unknown token never reached arg validation. (The issue's suggested `cobra.NoArgs` does NOT fix this: it's an arg validator, never reached on a non-runnable command.) Give the four group commands (data, cluster, auth, client) a RunE=runGroup: a bare `tracebloc <group>` still prints help and exits 0, but a mistyped subcommand is now a hard error (exit 1) with a nearest-match suggestion, matching the "unknown command" wording the root already emits via its default legacyArgs. SuggestionsMinimumDistance=2 drives the hint; SuggestionsFor skips hidden commands, so the Rev-9 hidden `client list` is never suggested. The root command is unchanged — as the parent-less command it already errored on unknown tokens. Tests: internal/cli/group_test.go — unknown-subcommand-errors (across all four groups + the `dataset` alias), nearest-match suggestion, hidden-list not suggested, bare-group-still-helps. The error cases are verified to fail without the fix (unfixed groups print help + exit 0). Full internal suite + vet + gofmt green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
… drop --ingestor-sa (#7) (#176) The ingestor ServiceAccount name was hardcoded to "ingestor" in DiscoverParentRelease, with a manual --ingestor-sa flag on both `cluster info` and `data ingest` as the only escape for customers who set a non-default `ingestionAuthz.serviceAccountName`. A renamed SA made the CLI mint a token jobs-manager then rejected — and `data delete` had no flag at all, so it broke with no workaround. Discover it instead from the chart's `<release>-ingestion-authz` ConfigMap (key `ingestion-authz.yaml`) — the very policy jobs-manager enforces, so it's the authoritative source. New best-effort cluster.discoverIngestorSAName reads `allowed[]`, keeps entries whose `namespace` matches the namespace we mint in (the rendered policy always populates namespace), and requires exactly one distinct `service_account`; a missing ConfigMap (older chart), RBAC denial, empty, or ambiguous policy all keep the "ingestor" default. It never errors — discovery is advisory. With discovery authoritative, --ingestor-sa is removed from `cluster info` and `data ingest` (its acceptance criteria); everything downstream (stage/teardown pods, the jobs-manager token mint, and now `data delete`) reads the discovered release.IngestorSAName. Verified the contract against tracebloc/client templates/ingestion-authz-configmap.yaml: name `<release>-ingestion-authz`, key `ingestion-authz.yaml`, `allowed[].service_account` + per-entry `namespace` — NOT the top-level `serviceAccountName` the issue sketched. Tests: discover_test.go — DiscoversRenamedSAFromConfigMap, AmbiguousSAKeepsDefault, CrossNamespaceSAIgnored (pins the namespace gate); the existing happy-path (no ConfigMap) proves the fallback. Full internal suite + vet + gofmt green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e requested one (#4) (#177) `cluster info` printed the REQUESTED token lifetime ("expires in ~10m0s (server may cap shorter)"), computed from ExpirationSeconds — even when kube-apiserver's --service-account-max-token-expiration capped the grant shorter. The customer saw a lifetime the token doesn't actually have. The TokenRequest response already carries the authoritative expiry (TokenRequestStatus.ExpirationTimestamp, capped by policy) — no JWT parsing needed, contrary to the issue title. Capture it as IngestorToken.ExpiresAt; `cluster info` shows the real remaining lifetime when set, falls back to the requested value when the server didn't return a timestamp, and still reads "never" for the long-lived static-secret fallback (ExpiresAt stays zero there). Tests: token_test.go — CapturesServerExpiry (server caps 3600→300, asserts ExpiresAt reflects the cap), StaticSecretHasNoExpiresAt (zero → "never"). Full internal suite + vet + gofmt green. Low priority per the issue (tokens are short-lived, so the misleading window is small) — but a cheap correctness win now that the API value is right there. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atch phase) Four low/medium follow-ups from the Bugbot review of PR #164; the other five Bugbot items were already fixed by #165/#168/#171. - delete: fail fast on a 401/403 from the pre-offboard online check (revoked/expired credential) with a `tracebloc login` hint, instead of warning and marching the user through the confirm only to fail at revoke. - delete: clear + persist the active-client pointer IMMEDIATELY after the revoke succeeds (before the best-effort teardown), so a failed or interrupted teardown can't leave the host looking enrolled under a dead credential. - delete: mark the offboard degraded when removeSelf can't remove the CLI binary / own `tb` alias, so the closing line stops claiming a clean offboard while the CLI is still on disk. - data ingest: a pod already in Succeeded prints "Ingestion complete — showing its logs:" (replayed) instead of the "live progress:" line. Tests added for each; full internal/... suite + go vet + gofmt green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 073d19a. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.

Note
Medium Risk
tracebloc deleteis irreversible local teardown plus credential revoke; behavior is heavily tested and backend rows are preserved, but mis-runs or partial teardown still need careful operator review.Overview
Machine offboarding (RFC-0001 §7.10) adds top-level
tracebloc delete: typed-name confirm (or--yes),POST /edge-device/<id>/revoke/via newRevokeClient, then best-effort local teardown throughinternal/nodeboot(helm uninstall, k3d delete, scopedghcr.io/tracebloc/*image prune, optional~/.traceblocwipe, CLI/tbremoval). Backend client history stays; closing output distinguishes clean vs degraded teardown.Single-machine client UX drops
client use, hidesclient list(installer-only), and updates hints away from multi-client selection.askAnAdmintakes action-specific copy for provision vs offboard.CLI ergonomics (#75): parent commands use
runGroupso mistyped subcommands exit non-zero with suggestions (hidden commands excluded).Cluster / ingest: ingestor SA comes from the ingestion-authz ConfigMap (
--ingestor-saremoved ). Token mint records serverExpiresAtforcluster info. Successful ingests runCleanStagingto drop.tracebloc-staging/<table>on the PVC.data deletecopy now says catalog metadata is retained, not auto-removed.Docs: RFC 0001 Rev 9 (offboarding, revoke vs DELETE); new RFC 0002 draft for inverted
data ingestUX. Category registry addssentence_pair_classificationandembeddings; parity goldens cover schema-aware tabular label checks.Reviewed by Cursor Bugbot for commit 073d19a. Bugbot is set up for automated code reviews on this repo. Configure here.