feat(server): agent API surface with API key auth (COD-379) - #6
Conversation
Add LLM-first /agent/* endpoints protected by Bearer token middleware:
- POST /agent/draft (idempotent: same title+body within 60s returns existing)
- GET /agent/posts (filterable by state, platform, limit)
- GET/PUT/DELETE /agent/posts/{id}
- POST /agent/posts/{id}/schedule
- GET /agent/calendar (upcoming scheduled content)
Add key management API (/api/v1/keys) for local operator bootstrap:
- POST creates a pgk_-prefixed key, returns raw key exactly once
- GET lists keys without exposing hashes
- DELETE revokes a key
Add postghost key create/list/revoke CLI commands.
Auth uses SHA-256 hashed keys stored in agent_keys table. Raw keys are
never persisted. 53 tests pass (28 existing + 25 new).
Co-authored-by: Archon <archon@purelymail.com>
🤖 Automated Review PanelGPT-5.5 (openai/gpt-5.5)Verdict: Functionally achieves the stated goal. All 6 agent endpoints work, auth middleware protects 🔴 Correctness bugs (FIXED before PR):
🟡 Convention violations (FIXED): 🟢 Done correctly: Platform parsing uses Gemini 3 Flash (google/gemini-3-flash-preview)Verdict: Functionally complete and CI-green. Several real correctness gaps addressed before merge. Goal alignment: ✅ All 6 endpoints + auth + key table + CLI present. Correctness bugs (FIXED):
Minor (deferred): No regressions: Router merge is additive, existing routes untouched, |
🤖 Auto-Merge Gate — ApprovalConfidence: 0.82 (threshold: 0.80) Goal alignmentPR implements COD-379 — agent API surface with API key auth for PostGhost. All 6
Checks observed (all SUCCESS)
Review panel outcomeDual-model review (GPT-5.5 + Gemini 3 Flash) run before PR open. 4 issues flagged and fixed before this PR was created:
No unresolved blocking language in any review comment. Scope limits / risk notes
RationalePR clearly fulfills the stated ticket goal. CI green, mergeable, dual-reviewed with all findings resolved, well-tested (56 tests). Confidence 0.82 reflects medium-large scope (10 files, +1641/-3) and the auth-adjacent nature of the change, balanced against complete goal alignment and fully-resolved review findings. 🤖 Merged by CodeFold Auto-Merge Gate (cron |
Summary
Implements COD-379: agent API surface with API key auth for PostGhost.
Adds LLM-first
/agent/*endpoints protected by Bearer token middleware, plus a key management API for local operators.Changes
Auth middleware (
auth.rs, new)agent_keystable/agent/*routesAgent endpoints (
agent_api.rs, new)POST /agent/draft— idempotent (same title+body within 60s returns existing, atomic lookup+insert under single lock)GET /agent/posts— filterable bystate,platform,limit(SQL-level filtering viaEXISTSsubquery)GET/PUT/DELETE /agent/posts/{id}— 404 on missing IDsPOST /agent/posts/{id}/schedule— creates pending scheduleGET /agent/calendar— upcoming scheduled contentKey management (
/api/v1/keys)POSTgeneratespgk_<uuid>key, returns raw key exactly onceGETlists keys without exposing hashesDELETErevokes a keyCLI
postghost key create --name <n>— mints a key, prints raw valuepostghost key list— lists keys with last_used timestampspostghost key revoke --id <id>— revokesStorage
agent_keystable (id, key_hash, name, created_at, last_used_at)save_content_if_not_recent_duplicate()— atomic idempotent insertlist_content_filtered()— filtered query with state + platform filtersdelete_content()now returnsResult<bool>(wasResult<()>)update_content_fields()— partial update of title/body/tagsReview panel findings (both fixed before PR)
Both GPT-5.5 and Gemini 3 Flash flagged 4 issues, all addressed:
DELETEreturned 204 for nonexistent IDs → now returns 404platformfilter silently ignored → implemented SQL-levelEXISTSfilteringTest plan
cargo build --all-targets— cleancargo test --all-targets— 56 tests pass (32 lib + 21 integration + 3 cli)cargo clippy --all-targets -- -D warnings— cleancargo fmt --all -- --check— cleanIntegration tests cover: auth (401 on missing/invalid/malformed keys, case-insensitive scheme), key lifecycle (create/list/revoke, hash not exposed), draft idempotency (within window + different body), all 6 endpoints, delete-404, platform filter.
Closes COD-379.
🤖 Generated with Archon. Co-authored-by: Archon archon@purelymail.com