[Bug]: `WorkspaceDefaults.scratchMount` is not in the TauWorkspace CRD and is silently pruned
- Dominant language
- Go
- Stars
- 15
- Forks
- 3
- Avg merge
- 21h 53m
- Merged PRs (30d)
- 131
Description
### Problem
The `tau` CLI's client-side `WorkspaceDefaults` type declares a `scratchMount` field that the `TauWorkspace` CRD has no schema for. Because CRD structural schemas prune unknown fields, anything written to `spec.defaults.scratchMount` is silently discarded by the API server — no error, no warning, the value simply is not there on read-back.
**This is latent, not an active data-loss bug.** I traced every reference before filing:
- `cli/internal/workspace/workspace.go:62` — declares `ScratchMount string \`json:"scratchMount,omitempty" yaml:"scratchMount,omitempty"\``
- `cli/internal/cli/run_workspace_test.go:484` — sets it in a test fixture
- …and that is the complete list.
No CLI flag sets it, no command writes it, and nothing reads it. So no user can lose a value through the CLI today. The problem is that the wire type asserts a field the API cannot store, which is a trap in two ways:
1. A contributor wiring up a `--scratch-mount` flag would produce a feature that appears to work and silently does nothing, with no compile-time or runtime signal.
2. A hand-authored `TauWorkspace` manifest (or a chart value) setting `defaults.scratchMount` is accepted by `kubectl apply` and silently pruned.
Contrast with the sibling field `Priority`, which carries an explicit comment in `controllers/tau-core/api/v1alpha1/types.go` warning that removing it from the CRD schema "makes the API server prune the field, which silently downgrades 'priority' workspaces to normal scheduling. Keep it." That is exactly the failure mode `scratchMount` is already in — it just has no consumer yet to make it visible.
The field has been present since the initial commit (`35f07c6`); it has never had a CRD counterpart.
I added a warning comment at that line in #110 so the next reader is not misled, but the underlying mismatch is unresolved and deserves a decision.
### Reproduction
1. Install the `tau-core-controller` chart so the `TauWorkspace` CRD is registered.
2. Apply a workspace that sets the field:
```yaml
apiVersion: tau.azure.com/v1alpha1
kind: TauWorkspace
metadata:
name: scratch-repro
namespace: tau-platform
spec:
target:
namespace: scratch-repro
defaults:
outputRoot: /data/projects/scratch-repro/runs
scratchMount: /mnt/scratch
```
3. Read it back:
```
kubectl get workspace scratch-repro -n tau-platform -o jsonpath='{.spec.defaults}'
```
4. Observe `outputRoot` is present and `scratchMount` is absent. The apply reported success.
Equivalently, `grep -rn "scratchMount" controllers/tau-core/config/crd/` returns nothing, while `cli/internal/workspace/workspace.go` declares it.
### TauGrid or tau version
`cb7e255` (field introduced in `35f07c6`; unchanged since)
### Environment
Not environment-specific — this is a schema/type mismatch in the repository. Reproducible on any Kubernetes cluster with the `TauWorkspace` CRD installed from `charts/tau-core-controller/crds/` or `controllers/tau-core/config/crd/bases/`.
Originally noticed while working on `TauWorkspace.spec.defaults` for #110 against a 1.35 AKS cluster.
### Relevant output
```shell
$ grep -rn "ScratchMount\|scratchMount" --include=*.go --include=*.yaml .
cli/internal/workspace/workspace.go:62: ScratchMount string `json:"scratchMount,omitempty" yaml:"scratchMount,omitempty"`
cli/internal/cli/run_workspace_test.go:484: ScratchMount: "/mnt",
# No match anywhere under controllers/tau-core/config/crd/ or charts/tau-core-controller/crds/
```
### Additional context
Two reasonable resolutions, and they are genuinely different decisions rather than one obvious fix:
1. **Remove the field.** Nothing consumes it, so this is the smaller, safer change and it eliminates the trap outright. Adding it to the CRD instead would mean inventing API surface for a feature that does not exist and has no defined semantics.
2. **Add `scratchMount` to `WorkspaceDefaults` in `controllers/tau-core/api/v1alpha1/types.go`**, regenerate via `make generate` / `make manifests`, and sync the chart CRD copy — but only if a scratch-mount default is actually wanted, in which case it also needs a consumer and documented behaviour.
I lean toward **(1) removal**, on the grounds that a type should not claim a field the API cannot persist, and reinstating it later is trivial once there is a real feature behind it. Flagging rather than deciding, since whether a scratch-mount default is on the roadmap is a product question I do not have context for.
Worth noting for whoever picks this up: #110 added a CRD-vs-chart drift test (`controllers/tau-core/api/v1alpha1/crd_chart_sync_test.go`) that keeps the two *generated* CRD copies in sync, but nothing checks the CLI's hand-maintained client-side struct against the CRD schema. That gap is what allowed this to sit unnoticed since the initial commit, and a similar check for the Go client types would prevent a recurrence.
Reported at the request of the East US 2 improvement-memo review, which recorded this in its §8.5 addendum.
Contributor guide
Research direction
Start with cli/internal/workspace/workspace.go:62 and cli/internal/cli/run_workspace_test.go:484, then compare the client type with controllers/tau-core/api/v1alpha1/types.go and the generated CRD copies under controllers/tau-core/config/crd/ and charts/tau-core-controller/crds/. Review the reproduction and the two proposed resolutions; done means the chosen API decision is reflected consistently and the relevant tests or generation checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- api, infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100