Files
poimen-memory/tasks/M6.6-m6-gate.md
T

151 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M6.6 — M6 composition gate
| Field | Value |
|---|---|
| Phase | M6 — agent-manager migration |
| Size | M — 13 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)