Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions WORKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,21 +159,29 @@ Details: Cycle 34 (Codex-6) applied `@fastify/rate-limit` to `POST /v1/channels/
Files: `services/core/src/app.ts` + `packages/contracts/src/protocol.ts` (flag Claude for the schema shape) + test
Details: Two related gaps Codex-12 surfaced: no `GET /v1/communities/:communityId/members` route exists (only mutation routes), and message `author` snapshots never refresh after send time (affects `customStatus` and presence `status` alike). Scope this as: add the member-list route (returns each member's current `Account` + role IDs, live-looked-up — this alone unblocks member-list-based visibility, which is a smaller, more contained fix than making message-author snapshots live). Flag to Claude whether refreshing message-author snapshots is worth pursuing separately, or deferred indefinitely as a "point-in-time" design choice.

**Codex-18 landed** (`d7cc6ef`) — Claude did this one directly rather than assigning it (small, well-understood, faster to just do). Bumped to 50 MB. Found a deeper duplication while doing it: `initiateUploadRequestSchema`'s `size` field had its own independent `.max(26_214_400)` in `protocol.ts`, hardcoded separately from `app.ts`'s constant — bumping only the `app.ts` side would have left uploads silently capped at the old 25 MB via schema rejection regardless. Moved `MAX_ATTACHMENT_BYTES` into `@cove/contracts` as the single source of truth for both sides; both hardcoded `"25 MB"` error strings now derive from it. 2 new tests.

> **Note on the gap here:** Codex-13/14/15 (guided reports, community rename, rich link embeds) were reassigned off this queue and completed tonight (2026-07-02 evening) via a parallel Grok CLI trial run instead — see the "Grok" section below. DM channels (P3 item 32) is the natural next big backend feature, but it needs a real schema design session (`communityId` is required on every existing channel/message code path today; making DMs fit will touch a lot of call sites) rather than a rushed decision — flagging for a dedicated Claude scoping pass before assigning it to any agent.

---

### Grok — ad-hoc parallel trial, 2026-07-02 evening (all 4 tasks landed)
### Grok — ad-hoc parallel trial, 2026-07-02 evening (all 4 tasks landed) + AG-20 running

Operator has a 7-day trial of the Grok CLI (`C:\Users\Vornecs\.grok\bin\grok.exe`, headless via `-p`/`--prompt-file`). Workflow: each task ran in its own fully disposable local git clone (no `origin` remote, no `git alternates` — zero path back to the real repo) under the session scratchpad, with `--permission-mode bypassPermissions` scoped to that one throwaway directory (explicitly operator-authorized each time). Claude reviewed every diff, independently re-ran `typecheck`/`test` from scratch (not trusting Grok's self-report), fixed real gaps found, and manually re-applied each change into the real repo before committing — Grok never had direct write access to the real working tree or push access to GitHub.

**Model correction:** the CLI's default resolved to `grok-composer-2.5-fast` at some point during tonight's earlier runs — its own model registry (`~/.grok/models_cache.json`) labels this model `"description": "Cursor's latest coding model"`, `"agent_type": "cursor"`, i.e. **not an xAI/Grok model at all**, apparently proxied through the same CLI. `~/.grok/config.toml` has `[models] default = "grok-build"` (labelled `"xAI's latest coding model"` in the same registry), which is what should be used — flagged by the operator, verified by checking `--debug-file` output confirming `model: "grok-build"` against `cli-chat-proxy.grok.com`. **All invocations from AG-20 onward pass `-m grok-build` explicitly** rather than relying on whatever resolves as default. Unclear whether the earlier 4 trial tasks tonight ran on `grok-build` or `grok-composer-2.5-fast` — the outputs were reviewed and verified independently either way, so the shipped code is sound regardless of which model produced it, but the model-identity itself for that batch is not confirmed.

**All 4 trial tasks landed and verified tonight:**

1. **Rich link-embed backend** (former Codex-15 scope, P3 item 16) — `4788fd8`. One real gap found and fixed by Claude: IPv4-mapped IPv6 addresses (e.g. `::ffff:10.0.0.5`) weren't checked against the private-IP blocklist, a genuine SSRF-adjacent gap.
2. **Guided report flow backend** (former Codex-13 scope, P3 item 26) — `f2788de`. Matched spec exactly; no revision needed.
3. **Community rename/edit endpoint** (former Codex-14 scope, P3 item 25, partial) — `f2788de`. Correctly caught a gap Claude's own task spec missed: `'community'` needed adding to `auditEventSchema.targetType`, not just the `action` enum, or the audit-log assertion would fail schema validation.
4. **Themes & appearance settings panel** (P2 item 15) — `5acd95f`. Matched spec closely; curated 5-preset palette, live CSS-variable preview, full accessibility attributes (`aria-pressed`/`aria-checked`/`radiogroup`), no `App.tsx` edit.

**Landed, confirmed on `grok-build`:**

5. **AG-20 — composer attachment upload UI** (P3 item 17, frontend half 1/2) — `b558f7a`. Extends `Composer.tsx` with drag-drop, file picker wiring, client-side image compression (canvas resize + re-encode, only above ~2MB), and a pending-attachment preview strip. Matched spec closely — no revision needed. Took noticeably longer than the earlier 4 tasks (60+ tool-call turns, multi-million cumulative tokens per the debug log) — almost certainly the jsdom canvas/Image mocking, which the task prompt had flagged as the tricky part up front. Worth knowing for future task sizing: browser-API-mocking-heavy frontend tasks cost meaningfully more than backend-route tasks of similar prompt complexity.

**Process note — real, not hypothetical:** tasks 2-4 ran while Codex was _simultaneously_ live-editing the same real `services/core/src/app.ts`/`app.test.ts` for Codex-12, uncommitted, in the same working tree. Verified this was really happening (via `tasklist`/hash-stability polling, not assumption) before touching anything. Landing tasks 2-3 required manually separating Claude's clean hunks from Codex's in-progress hunks via `git apply --cached` (hunk-by-hunk, since one import line was genuinely shared) rather than a blind `git add -A`, verifying the isolated staged state independently (via `git stash push --keep-index`) before committing, then restoring Codex's stash — one trivial one-line merge conflict on the shared import, resolved by keeping both. **Lesson for future concurrent-agent nights:** confirm file stability before any hunk-separation work, and don't trust a `npm test` run's failure at face value in a shared working tree without confirming which agent's code the failure actually belongs to (the first failing-test read this session belonged to a test Codex had already deleted by the time it was diagnosed).

---
Expand All @@ -196,7 +204,13 @@ Details: Per-channel notification settings beyond mute: all-messages / @mention-

**AG-19:** Attachment approval panel component (P3 item 27)
Files: `apps/web/src/AttachmentApprovalPanel.tsx` (new), unit tests
Details: Admin approve/reject UI badge/panel for uploads stuck in "pending" quarantine. Backend quarantine route already exists (check `services/core/src/app.ts` for the current attachment-status route names before wiring props). Props: `attachment: { id, filename, status, uploadedBy }`, `onApprove: (id) => void`, `onReject: (id) => void`. Do NOT edit App.tsx.
Details: **Correction from earlier assumption:** there is no existing approve/reject route to wire against — `app.ts`'s upload endpoint (`app.ts:2005`) auto-approves on successful upload (`quarantineStatus` goes straight from `'pending'` to `'approved'`), so nothing is actually stuck pending today. Build the panel UI on spec anyway (approve/reject buttons, badge states) since a real moderation-review step is a reasonable future addition, but note in your status file that a backend `PATCH`-style approve/reject route doesn't exist yet and would need to be added before this panel has anything real to call. Props: `attachment: { id, filename, status, uploadedBy }`, `onApprove: (id) => void`, `onReject: (id) => void`. Do NOT edit App.tsx.

**AG-20 landed via Grok tonight** (`b558f7a`) — reviewed and matches spec closely: file picker + drag-drop wired to the previously-inert attach button, compression correctly gated to `image/*` over 2MB only, picks the smaller of JPEG/WebP re-encodes, graceful fallback to the original file on any error, proper object-URL cleanup via `useEffect`, presentation-only (no network calls). 6 new tests with solid `canvas`/`Image`/`URL` mocking. No revision needed.

**AG-21:** Inline attachment rendering in messages (P3 item 17, frontend half 2/2) — **left queued for Antigravity's normal rotation**
Files: `apps/web/src/MessageAttachment.tsx` (new), unit tests
Details: `Message.attachments` (`Attachment[]` — `id`, `filename`, `mimeType`, `size`, `quarantineStatus`, `createdAt`) is already on every message from the backend; content is served from `GET /v1/attachments/:attachmentId/content`. Build a component that, given `attachments: Attachment[]`, renders each one inline: `image/*` MIME types render as a clickable `<img>` (pointed at the content endpoint) with a sensible max-width/height so a large image doesn't blow out the message bubble — clicking opens the full image in a new tab is fine for v1, no lightbox needed. Everything else (video/audio/pdf/zip/text) renders as a compact download chip: filename, human-readable size, download icon, linking to the content endpoint. Props: `attachments: Attachment[]`. Full unit test coverage. Do NOT edit App.tsx or MessageList.tsx — Claude wires this into `MessageList.tsx`'s per-message render once both this and AG-20 land.

---

Expand Down Expand Up @@ -251,7 +265,7 @@ Claude pulls from here when agent work is integrated. Agents work from their own
### P3 — Core messaging polish

16. **Rich link embeds** — YouTube, Twitter/X, images, OG tags unfurl inline. ✅ backend unfurl endpoint (`POST /v1/link-preview`) shipped 2026-07-02 evening via Grok trial run + Claude review (`4788fd8`); frontend rendering (inline unfurl in message list) not yet assigned.
17. **File & image uploads** — drag-drop, inline previews
17. **File & image uploads** — drag-drop, inline previews. Operator explicitly asked for this (2026-07-02 evening) — wants pics uploadable in channels/servers/group chats, with client-side compression and limits looser than Discord's. Backend already fully built and working (initiate/upload/serve/attach-to-message) — this is a frontend-only gap. Split three ways per operator request: ✅ byte-cap bump done directly by Claude (Codex-18, `d7cc6ef`); ✅ composer upload UI done via Grok (AG-20, `b558f7a`); inline message rendering left queued for Antigravity's normal rotation (AG-21). **Unlike the rest of the unwired-component backlog, Claude is committing to wire these into `App.tsx` as soon as they land — not left to pile up.**
18. **Pinned messages** — backend done Cycle 34 (Codex-8: pin/unpin/list endpoints, permission-gated); UI (pin button + panel) — Claude Cycle 35 queue.
19. **Message search** — keyword search within channel (deferred — see P5, overlaps with the FTS stub)
20. ✅ ~~React error boundary~~ — component built Cycle 32 (AG-2), wired into `main.tsx` Cycle 33
Expand Down
Loading
Loading