151 lines
7.3 KiB
Markdown
151 lines
7.3 KiB
Markdown
# M6.6 — M6 composition gate
|
||||
|
|
|
|||
|
|
| Field | Value |
|
|||
|
|
|---|---|
|
|||
|
|
| Phase | M6 — agent-manager migration |
|
|||
|
|
| Size | M — 1–3 days |
|
|||
|
|
| Status | ⬜ Not started |
|
|||
|
|
| Flags | gate |
|
|||
|
|
| Spec | inlined below |
|
|||
|
|
| Blocks | all of M6 |
|
|||
|
|
|
|||
|
|
## Goal
|
|||
|
|
|
|||
|
|
Prove the schema, the query port, the network path, and the credentials
|
|||
|
|
bind together into one working system — not four pieces that each passed
|
|||
|
|
their own task in isolation. This is the property no single M6 task owns:
|
|||
|
|
M6.1 proves the cluster is healthy, M6.2 proves the schema applies, M6.3
|
|||
|
|
proves the queries work against a local test database, M6.4 proves a raw
|
|||
|
|
TCP connection reaches the cluster, M6.5 proves the credential decrypts —
|
|||
|
|
none of them alone proves agent-manager, running for real on the Mac,
|
|||
|
|
through the real ingress route, with the real ksops credential, against
|
|||
|
|
the real cluster, does its actual job: track a session end-to-end without
|
|||
|
|
losing or corrupting data.
|
|||
|
|
|
|||
|
|
## Facts (inlined — no spec read needed)
|
|||
|
|
|
|||
|
|
**"Bind together smoothly" means two concrete things here, not a vibe:**
|
|||
|
|
|
|||
|
|
1. **The full network path is exercised, not simulated.** M6.3's tests run
|
|||
|
|
against a disposable local Postgres — that validates the SQL, not the
|
|||
|
|
route. This gate is the first (and only) task that runs agent-manager
|
|||
|
|
unmodified, on the actual Mac, through M6.4's nginx `stream {}` route,
|
|||
|
|
authenticating with M6.5's ksops-sourced credential, against M6.1's
|
|||
|
|
real cluster.
|
|||
|
|
2. **Schema conventions match the rest of this homelab, not just
|
|||
|
|
"compiles."** This project's own `memory-db` (M2.x) and
|
|||
|
|
`agent-manager-db` (M6.x) are two unrelated Postgres schemas landing in
|
|||
|
|
the same cluster around the same time. They don't share data or a
|
|||
|
|
cluster (M6.1 already ruled that out), but a reviewer scanning
|
|||
|
|
`k8s/infra/databases/` should find the same shape twice: same
|
|||
|
|
`Cluster`/`Database` CRD structure, same `storageClass`, same
|
|||
|
|
`enableSuperuserAccess: false`, same GitOps-only provisioning
|
|||
|
|
discipline. "Binds together smoothly" includes that consistency check,
|
|||
|
|
not just agent-manager working in isolation.
|
|||
|
|
|
|||
|
|
**What a session round trip actually touches**, so the test isn't
|
|||
|
|
shallow: `CreateSession` (writes `sessions` + touches `groups` via the
|
|||
|
|
`ON CONFLICT DO NOTHING` insert) -> `UpdateStatus` -> `SetAgentSessionID`
|
|||
|
|
-> `SetReviewRepo` (writes `review_targets`) -> `Delete` (must cascade
|
|||
|
|
`review_targets` via the FK, per M6.2's decision, with no leftover row).
|
|||
|
|
That single flow crosses all 4 non-`settings` tables and exercises both
|
|||
|
|
the FK-cascade decision and the placeholder-conversion correctness from
|
|||
|
|
M6.3 in one pass.
|
|||
|
|
|
|||
|
|
## Steps
|
|||
|
|
|
|||
|
|
1. On the Mac, with agent-manager built from the fully-ported
|
|||
|
|
`add-headless-spawn` branch (M6.3 complete) and configured to use
|
|||
|
|
M6.4/M6.5's route and credential: run the `spawn` CLI subcommand to
|
|||
|
|
create a real session.
|
|||
|
|
2. Drive it through the full lifecycle above (status update, agent
|
|||
|
|
session id capture, review target set, delete) using agent-manager's
|
|||
|
|
own CLI/TUI, not a hand-rolled SQL script — the point is proving the
|
|||
|
|
actual client works, not that Postgres accepts hand-written SQL.
|
|||
|
|
3. Kill and restart agent-manager mid-lifecycle (after step 2's status
|
|||
|
|
update, before delete); confirm it reconnects and reads back the same
|
|||
|
|
state — proves the connection isn't accidentally caching state
|
|||
|
|
client-side that masks a write that never actually landed.
|
|||
|
|
4. Diff `k8s/infra/databases/agent-manager-db.yaml` against
|
|||
|
|
`k8s/infra/databases/memory-db.yaml` field-by-field for the
|
|||
|
|
convention-consistency check.
|
|||
|
|
5. Confirm both ArgoCD Applications (agent-manager's and this project's
|
|||
|
|
`memory-db`, once it exists) are tracked from the `repoURL` each
|
|||
|
|
actually watches — re-verify per M6.1's caveat, since this is the
|
|||
|
|
final point where a "pushed but ArgoCD never saw it" mistake would
|
|||
|
|
otherwise go unnoticed until much later.
|
|||
|
|
6. Commit `expected/m6.6.txt`; diff.
|
|||
|
|
|
|||
|
|
## Acceptance
|
|||
|
|
|
|||
|
|
- A session created, updated, and deleted through agent-manager's real
|
|||
|
|
CLI on the Mac round-trips correctly through the full network path.
|
|||
|
|
- A mid-lifecycle restart does not lose or duplicate state.
|
|||
|
|
- Deleting the session leaves zero orphan rows in `review_targets`/
|
|||
|
|
`review_bases`/`review_scopes` (FK cascade, not app-level cleanup).
|
|||
|
|
- `agent-manager-db.yaml` and `memory-db.yaml` match on every field that
|
|||
|
|
isn't inherently app-specific (name, storage size).
|
|||
|
|
- No manual `kubectl apply`/`psql` anywhere in the setup this gate
|
|||
|
|
exercises.
|
|||
|
|
|
|||
|
|
## Verify
|
|||
|
|
|
|||
|
|
**Harness:** the real Mac client, the real cluster, agent-manager's own
|
|||
|
|
CLI — this gate deliberately does not use a disposable/local database,
|
|||
|
|
since proving the disposable path works is exactly what M6.1-M6.5 already
|
|||
|
|
did.
|
|||
|
|
|
|||
|
|
**Integration test** — `verify/m6.6.sh` diffed against
|
|||
|
|
`expected/m6.6.txt`:
|
|||
|
|
1. `a1_full_roundtrip` — create/update/set-review/delete via the real CLI;
|
|||
|
|
assert no error at any step.
|
|||
|
|
2. `a2_no_orphan_review_rows` — after delete, query `review_targets`/
|
|||
|
|
`review_bases`/`review_scopes` directly (from inside the cluster, as a
|
|||
|
|
final-state check) for the deleted session's id; assert zero rows,
|
|||
|
|
with no explicit `DELETE FROM review_*` having been issued by the CLI
|
|||
|
|
(proves the FK cascade did the work, not leftover manual-cleanup code
|
|||
|
|
nobody removed).
|
|||
|
|
3. `a3_survives_restart` — kill agent-manager between status-update and
|
|||
|
|
delete; restart; assert the status update is still visible before
|
|||
|
|
proceeding to delete.
|
|||
|
|
4. `a4_schema_convention_match` — diff the two `Cluster` manifests' non
|
|||
|
|
app-specific fields; assert empty diff.
|
|||
|
|
5. `a5_repourl_confirmed` — for each of the two ArgoCD Applications
|
|||
|
|
involved, print which `repoURL` it watches and confirm it matches
|
|||
|
|
which remote was actually pushed.
|
|||
|
|
6. `a6_no_manual_apply_in_history` — review the shell history / session
|
|||
|
|
log from M6.1 through M6.5 for a `kubectl apply` or `psql` write
|
|||
|
|
command that wasn't inside an explicitly-flagged debugging exception;
|
|||
|
|
assert none exist outside that exception.
|
|||
|
|
|
|||
|
|
**Command:** `bash verify/m6.6.sh | diff - expected/m6.6.txt`
|
|||
|
|
|
|||
|
|
**False pass:**
|
|||
|
|
- Running assertion 1 against M6.3's disposable local Postgres instead of
|
|||
|
|
the real cluster because it's faster/already running. That's exactly
|
|||
|
|
the "four pieces that each passed in isolation" failure mode this gate
|
|||
|
|
exists to catch — it must hit M6.1's actual cluster through M6.4's
|
|||
|
|
actual route.
|
|||
|
|
- Treating a schema diff (assertion 4) as advisory and skipping it when
|
|||
|
|
short on time. A convention mismatch here is invisible today and
|
|||
|
|
becomes the thing a future reviewer trips over when comparing the two
|
|||
|
|
`k8s/infra/databases/*.yaml` files months later with no memory of why
|
|||
|
|
they differ.
|
|||
|
|
|
|||
|
|
## Traps
|
|||
|
|
|
|||
|
|
- Discovering during this gate that M6.4's nginx route works from inside
|
|||
|
|
the homelab LAN but not from wherever the Mac actually sits (VPN,
|
|||
|
|
different subnet, etc.) — a gap none of M6.1-M6.5's narrower tests
|
|||
|
|
would have caught, since this is the first task that tests from the
|
|||
|
|
Mac's actual network position rather than "outside the cluster" in the
|
|||
|
|
abstract.
|
|||
|
|
- Fixing a gate failure by loosening the gate (e.g. deleting assertion 2
|
|||
|
|
because the cascade "mostly works") instead of fixing the underlying
|
|||
|
|
FK/migration issue. Same discipline this project's other gates
|
|||
|
|
(M0.8, M1.8, M2.8...) already hold to.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
Background: [M6.1](M6.1-agent-manager-db-manifest.md) · [M6.2](M6.2-schema-port.md) · [M6.3](M6.3-store-query-port.md) · [M6.4](M6.4-nginx-stream-routing.md) · [M6.5](M6.5-credentials-secret.md)
|