**RESOLVED 2026-07-12 (w6 follow-ups).** +kubebuilder:validation:Pattern/MaxLength markers added to Repo/Branch/RootDir in lego/types/v1alpha1/app_types.go; CRD regenerated. Hand-applied App CRs now can't bypass the input validators.

# Add CRD-schema validation for repo/branch/rootDir — from w6/m6 t003 altitude review

w6/m6 added `ValidRepo`/`ValidGitRef`/`ValidRootDir` and wired them into the two
create paths (`apps.specFromCreate`, `store.appFromRequest`) and `SetRootDir`. But
those are the **bex-api** entry points only — a hand-applied `App` CR
(`scripts/app-apply.sh`, `examples/whoami-app.yaml`, `kubectl apply -f`) bypasses
all three, and the operator forwards `app.Spec.{Repo,Branch,RootDir}` straight
into `build.Build(...)` (`lego/operator/internal/controller/app_controller.go:168`)
with no sanitization of its own.

The deeper fix is the CRD schema: `Repo`/`Branch`/`RootDir` in
`lego/types/v1alpha1/app_types.go` carry **no** `+kubebuilder:validation:*` markers
today (every other constrained field — Type, Builder, Replicas, Port — does). Adding
`+kubebuilder:validation:Pattern`/`:MaxLength` to these three makes the kube API
server reject bad values from **every** writer in one place, and covers the
operator's consumption path (hand-applied CRs) for free.

Suggested markers (permissive at the CRD level; the Go validators stay the tighter
gate for the bex-api path):

- `Repo`: `+kubebuilder:validation:Pattern="^(https?://|ssh://|git@)"`,
  `+kubebuilder:validation:MaxLength=2048`
- `Branch`: `+kubebuilder:validation:Pattern="^[A-Za-z0-9][A-Za-z0-9._/@+-]*$"`,
  `+kubebuilder:validation:MaxLength=255`
- `RootDir`: `+kubebuilder:validation:MaxLength=512` (traversal still needs the Go
  validator — a "no `..` component" pattern is awkward in JSON schema)

Then `make manifests generate` from `lego/operator/` to regenerate
`config/crd/bases/app.bex.co_apps.yaml`.

**Why filed, not done in w6/m6:** this is a cross-module change (touches
`lego/types`, regenerates the CRD YAML) — adjacent to but outside the w6/m6
input-validation diff, and CRD schema tightening can affect existing CRs on update.
Worth a focused change with that blast radius considered.

Source: w6/m6 t003 altitude review (`/simplify`), 2026-07-11.
