prole/docs/plans/junie/README.md
chrisfu 6f506a97b2 docs(plans): file todo-1 brief — cfg save path refuses non-string widget values
Followup from commit dba8a2d's findings. ConfigMixin._save_knoe_cfg in
knoe/ui/screens/cfg.py reads Tk widget vars via `var.get()` and writes
the result to conf/<mode>.cfg. When a var is a MagicMock (interactive
./install.py run in a non-Tk context, partially-mocked widgets), the
save path serializes the mock's repr-string into the cfg, then the next
installer pass calls os.makedirs() on those values and produces
directories literally named `<MagicMock name='Canvas().tk.call().strip()'
id='4743999712'>/`.

The brief lays out a TDD approach for Junie:
  1. Write failing test at tests/installer/test_cfg_save_refuses_mock_values.py
     that passes MagicMock widget vars and asserts _save_knoe_cfg raises
     TypeError naming the field.
  2. Implement the minimal fix: a `_str_value(var, field=...)` helper in
     cfg.py that validates widget reads and raises if non-str. Use it
     in the .get()/.strip() chains across lines 103-155.
  3. Verify the 750 existing installer tests still pass.

Brief includes file pointers (cfg.py:44 _save_knoe_cfg, line 102
globals_to_save assembly, line 277 cfg_path.write_text), the canonical
failing test stub, both fix-approach options (per-read validator vs
end-of-flow dict walk), and explicit commit-shape guidance.

Index updates:
  docs/plans/junie/README.md — todo-1 row added under Active
  docs/TODO.md §"In progress" — todo-1 promoted above Phase 3 (smaller
                                scope, easy to land first)

Naming convention: `todo-N-<slug>.md` for follow-up bugs, distinct from
the `NN-<slug>.md` pattern reserved for ranked queue items.
2026-05-05 20:43:44 -04:00

79 lines
4.6 KiB
Markdown

# Junie briefs
Self-contained, single-task briefs for [Junie](https://www.jetbrains.com/junie/)
to consume from inside the IntelliJ IDE. Each file is a hand-off — Junie
reads the brief cold (no shared chat history), implements the change, and
opens an MR.
## What lives here vs. `../`
The `..` parent directory holds **architectural plans** — multi-section
documents covering an initiative's strategy, schema, and component design.
They outlive the implementation and become the architectural reference
once shipped.
This subdirectory holds **work briefs** — smaller, more tactical, scoped
to a single MR's worth of changes. They reference the master TODO index
(`../../TODO.md`) and contain enough context for Junie to land the change
without escalating questions.
## Brief shape (convention)
Each brief follows this skeleton:
1. **Why** — one or two paragraphs of context, including the trigger event
if any (e.g. "the 4/28 14:00 UTC outage").
2. **What changes** — concrete file paths, line numbers, before/after where
useful. Don't make Junie re-derive the change.
3. **Verification** — runnable commands or `helm template` diffs that
confirm the change. Each brief ends with a **Definition of done**
checklist.
4. **Out of scope** — explicit fences. The TODO is interconnected; without
this section briefs creep.
5. **Commit shape** — proposed commit message + structure.
## Status tracking
Every brief here corresponds to a numbered item in
[`../../TODO.md`](../../TODO.md) (or has an explicit "doesn't yet exist
in TODO" note). When Junie lands a brief:
1. Move the corresponding item from the TODO ranked queue into the
**Done** section with date + commit ref (or the convention used by
the rest of the file).
2. Don't delete the brief from this directory — it stays as the design
record.
## Current briefs (as of 2026-05-02)
### Active (in flight)
| File | Tracked at | Subject |
|---|---|---|
| [`k3d-knoe-auth-pod-deploy.md`](k3d-knoe-auth-pod-deploy.md) | TODO §"In progress"; parent [`../k3d-gke-mirror.md`](../k3d-gke-mirror.md) §6 Phase 3 | Phase 3 of k3d-mirror-of-GKE: build the knoe-auth image, `k3d image import`, run as a pod inside the cluster. Pre-merge smoke loop with `make k3d-knoe-{deploy,redeploy,undeploy}`. |
| [`todo-1-cfg-save-path-bug.md`](todo-1-cfg-save-path-bug.md) | followup from commit `dba8a2d` | TDD fix: `ConfigMixin._save_knoe_cfg` must refuse to serialize non-string widget values into `conf/<mode>.cfg`. Currently leaks `<MagicMock …>` reprs when widgets aren't real Tk StringVars. |
### Shipped (kept as design record)
| File | Queue # | Subject |
|---|---|---|
| [`k3d-knoe-auth-dev-loop.md`](k3d-knoe-auth-dev-loop.md) | k3d Phase 1 | CNPG + KDC in k3d; `make k3d-knoe-{up,pf,down}`; `--mode k3d` flag; `etc/krb5.local.conf`; smoke script; engineer doc. **Shipped 2026-05-02.** |
| [`02-k3s-prole-rename.md`](02-k3s-prole-rename.md) | #2 | Rename k3s `prole-*.yaml` → `knoe-*.yaml` (kustomize is broken). **Shipped 2026-05-02 (commit `fb7e8b7`).** |
| [`06-patch-garage-script-fixes.md`](06-patch-garage-script-fixes.md) | #6 | Three defects in `scripts/patch_garage_cross_cluster.sh`. **Shipped 2026-05-02 (commits `34a25dd` + `5d17325`).** |
| [`07-init-cnpg-gke-sa-wiring.md`](07-init-cnpg-gke-sa-wiring.md) | #7 | Wire `cnpg-backup-sa` into CNPG cluster spec; bump operator to v1.29. **Shipped 2026-05-02 (commit `c3fae73`).** |
| [`13-podmonitor-manual-management.md`](13-podmonitor-manual-management.md) | #13 | Migrate off CNPG-deprecated `enablePodMonitor` + `podMonitorRelabelings`. **Shipped 2026-05-02 (commit `c3fae73`).** |
| [`15-remove-dead-dashboard-consumer.md`](15-remove-dead-dashboard-consumer.md) | #15 | Remove dead Kong DASHBOARD consumer + `basicauth_credentials`. **Shipped 2026-05-02 (commit `c3fae73`).** |
| [`03-image-rename-knoe-authority-to-knoe-auth.md`](03-image-rename-knoe-authority-to-knoe-auth.md) | #3 | Rename Docker image `knoe-authority` → `knoe-auth`; add `Dockerfile.app`; update 2 manifests. **Shipped 2026-05-02.** |
| [`phase2-oidc-gke-deploy.md`](phase2-oidc-gke-deploy.md) | Phase 2 GKE | Enable OIDC in GKE deployment; Kong `/auth` route; `studioIngress`+`knoeAuth` values defaults. **Shipped 2026-05-02.** |
## How a session fires off a batch
The driving session (Claude Code, Cowork+Code, or a human) writes the
briefs into this directory and points Junie at one or more of them. Junie
reads the brief, implements, runs the verification checklist, opens an
MR. Each brief is independent — Junie can take them in any order, or in
parallel across separate IDE sessions.
The brief is the contract. If something is unclear, the brief is buggy
and should be edited before Junie continues.