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

7.3 KiB
Raw Permalink Blame History

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 testverify/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.2 · M6.3 · M6.4 · M6.5