Files
cg_api_secure-webshare/AI_MASTER_PLAN.md

103 lines
10 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.
# AI Master Plan — cg.cx Refinement Pass
## 1. Current Repo Understanding
### Architecture
- **10-crate Rust workspace** (`cgcx-core`, `cgcx-config`, `cgcx-crypto`, `cgcx-db`, `cgcx-storage`, `cgcx-content-typing`, `cgcx-file-pipeline`, `cgcx-moderation`, `cgcx-bot`, `cgcx-server`)
- **SQLite** database with WAL mode, 7 migrations already applied (`001_init` through `007_hash_blacklist`)
- **Svelte 5** SPA frontend (`frontend/`), Vite build, served as static files by Axum fallback
- **Teloxide** bot (standalone binary) + **Axum** server (standalone binary), both share DB and config
- Content encrypted with XChaCha20-Poly1305, per-file CEKs wrapped with AES-KW under a master key
- BLAKE3 plaintext hashes stored for deduplication and hash-blacklist enforcement
### Already Implemented (verified in code)
| Task | Status | Location |
|------|--------|----------|
| D — GLOBAL_BAN config | ✅ | `config/default.toml` `[groups] global_ban`; `propagate_punishment()` in bot |
| F — Approval message with media batches | ✅ | `handle_forward_callback` "approve" — decrypts files, batches up to 10, appends caption to last batch |
| G — Review group media | ✅ | `finalize_upload` — decrypts and sends media batches to review group, appends review text to last batch |
| H — Review buttons (Ban, Blackl., Ban/BL u.) | ✅ | Inline keyboard in `finalize_upload` and handlers in `handle_forward_callback` |
| K — Show/Hide Author toggle | ✅ | `UploadOptions.show_author`, `toggle_author` callback, `show_author` DB column (migration 005) |
| L — File list metadata | ✅ | `ViewContent.svelte` shows `created_at`, `total_size`, `author` (username hyperlink + ID) |
| M — Deduplication | ✅ | `FilePipeline::ingest_file` checks `find_active_by_plaintext_hash`, increments `ref_count` |
| N — Hash blacklist | ✅ | `HashBlacklistRepo`, migration 007, blocked-hash rejection in pipeline |
| O — Username change tracking | ✅ | `UserRepo::ensure_exists` logs changes to `data/uname_changes.json` (configurable path in config) |
| Partial A — Misc report UI | ✅ | `Home.svelte` already has "Report Content via Telegram" link + "Report Content directly" input/button |
| Partial Q — Homepage bot link | ✅ | `Home.svelte` already has `t.me/{BOT_USERNAME}` link, but in wrong DOM order and styling needs tweak |
### Actual Bugs / Gaps to Fix
| Task | Root Cause | Fix Strategy |
|------|-----------|--------------|
| **B — /get_id** | Admin commands gated behind `msg.chat.is_group() \|\| msg.chat.is_supergroup()`, **excluding channels**. Also, HTML parse errors in logs come from unescaped `<arg>` tokens in `/help`, but `/get_id` must also be hardened for channels where `msg.from` / admin visibility differs. | Add `msg.chat.is_channel()` to admin command scope. Ensure `handle_get_id_search` gracefully handles channels (`get_chat_administrators` works in channels too if bot is admin). |
| **C — /help** | `help_text` raw string contains literal `<ID>`, `<@username>`, `<displayname>`, `<user_id>`, `<dur>`, `<unit>`. Telegram HTML parse mode rejects unsupported tags like `<id>`. | Escape all argument placeholders: replace `<arg>` with `&lt;arg&gt;` or `[arg]`. Minimally invasive: keep the rest of the formatting intact. |
| **E — blacklist_uid / whitelist_uid** | Commands are technically restricted to `admin_group_ids` inside the handler, but the outer command dispatch allows them in any group for admins, producing a confusing "only available in admin group" message. Missing-parameter handling exists but UX is inconsistent with other admin commands. | Move the admin-group check into the command dispatch so non-admin-group chats get a clear "Unauthorized" response. Ensure missing-parameter usage info is returned **before** the admin-group gate when possible, so users in the admin group see usage info immediately. |
| **I — Password + auto-destroy 410** | `serve_file` increments `view_count` for **HEAD requests** because `is_conditional` only checks `If-None-Match`, not request method. Some browsers/proxies/link previews issue HEAD before GET, consuming the view and causing the subsequent GET to hit `view_count >= max_views` → 410. | Add `Method` extractor to `serve_file` and skip view increment when `method == Method::HEAD`. Also skip increment for any non-GET method as defense-in-depth. |
| **J — Password field UX** | `Home.svelte` `submit()` calls `fetchMetadata(cxid)` **without password first**. For password-protected content this returns 401, throws, and the catch block sets a raw JSON error string. `needsPassword` is **never set to true**, so the password field never appears on the home page. Users cannot access password content from the home page at all. | Restructure `submit()`: on 401 from `fetchMetadata`, explicitly check if the error is auth-related and set `needsPassword = true` instead of treating it as a generic error. Ensure password verification only runs on explicit submit/Enter, not on keystrokes. |
| **A — Misc report (complete)** | Frontend UI exists but the "direct" report still opens a Telegram deep link instead of submitting via the web backend. The hardcoded `harmfulmeowbot` username is wrong; should use `BOT_USERNAME` from `api.js`. | Add `POST /api/report` endpoint to the server (it has access to `config.telegram.bot_token`). Server inserts report into DB and forwards a notification to configured review groups via direct Bot API HTTP calls. Update frontend to call the API instead of opening Telegram. |
| **Q — Homepage bot link** | Bot link is present in `Home.svelte` but **DOM order is wrong** (currently above Content ID label; should be between Content ID field and "-- cannibal girls --"). Styling says underline + very dark green/blackish green; current color is `var(--retro-green)` which may need to be `var(--retro-accent)` or a darker custom value. | Reorder elements in `Home.svelte`. Adjust CSS to match spec. Keep `BOT_USERNAME` dynamic import. |
## 2. Locked Implementation Rules
- **No broad rewrites.** Fix only the targeted bugs and gaps.
- **No redesign of working flows.** The upload pipeline, encryption, submission forward system, and moderation engine are working — do not touch them except where task I requires the HEAD-request guard.
- **Preserve existing frontend style and behavior.** Keep retro theme, fonts, colors, and animations. Only adjust the specific elements requested in A, J, Q.
- **No cleanup-only changes.** Do not refactor unrelated code, rename variables, or change formatting.
- **4-agent cycle mandatory** for implementation batches.
- **SQLite schema is frozen** except if a new migration is absolutely required. Tasks AQ do not need new DB tables (report endpoint can reuse existing `reports` table with `reporter_user_id = 0` for web reports).
## 3. Exact Batch Order for This Refinement Pass
### Batch 1: Security + Stability (Agent 1)
- **B** — /get_id channel support and robustness
- **C** — /help HTML escaping fix
- **E** — blacklist_uid/whitelist_uid command behavior refinement
- **I** — HEAD request view-count bugfix in `serve_file`
### Batch 2: Telegram Bot + Permissions (Agent 2)
- Verify Batch 1 bot changes compile and pass basic smoke tests
- **A** backend — Add `POST /api/report` endpoint to server (reuse `reports` table, forward to Telegram review groups via reqwest HTTP call to Bot API)
- **O** verification — Confirm username tracking writes correctly in channels/groups
- **D** verification — Confirm global_ban propagation logic works with recent schema
### Batch 3: Content Delivery + Rendering (Agent 3)
- **A** frontend — Wire "Report Content directly" to call `POST /api/report` instead of Telegram deep link
- **J** — Fix home page password flow (needsPassword trigger on 401)
- **Q** — Reorder bot link, adjust underline/dark-green styling
- **L** verification — Ensure metadata bar renders correctly after Batch 1 server changes
### Batch 4: Docs + QA + Regression (Agent 4)
- **P** — Update `docs/COMMANDS.md`, `docs/API.md`, `docs/MODERATION.md`, `README.md` to reflect all changes
- Regression test checklist: /get_id in group + channel, /help output, blacklist_uid usage, password+auto-destroy content loads on first GET, home page password flow, report submission API, bot link styling
- Run `cargo check --workspace` and `cargo test --workspace`
- Run frontend build (`cd frontend && npm run build`) and verify no new warnings
## 4. Key Risks
| Risk | Mitigation |
|------|-----------|
| Adding `Method` extractor to `serve_file` changes its signature and could break route registration if not matched exactly. | Use `extract::Method` in the handler signature; Axum `get()` accepts handlers with extra extractors. |
| `POST /api/report` needs to send Telegram messages from the server, which currently has no Telegram client. | Use `reqwest` (already transitive via Axum) to make direct HTTPS POSTs to `https://api.telegram.org/bot<token>/sendMessage`. Add `reqwest` explicitly to `cgcx-server/Cargo.toml`. |
| Channel admin command handling may behave differently because `msg.from` in channels can be the channel itself or anonymous. | Use `msg.sender_chat` or check `msg.from` carefully; `is_admin` still works with the bot's own admin check. |
| Frontend `fetchMetadata` 401 handling change in J must not break non-password flows. | Only set `needsPassword = true` when `err.status === 401`. Keep existing catch behavior for other errors. |
## 5. Exact 4-Agent Loop
```
Batch N assigned to 4 subagents -> execute in parallel -> wait for all 4 ->
brief review -> update AI_CHECKPOINT.md -> continue to Batch N+1
```
Agent definitions (always use these exact names):
1. **Security + Stability** — Server-side hardening, HTML escaping, view-count logic, command permission gates
2. **Telegram Bot + Permissions** — Bot command behavior, channel support, global_ban, backend API wiring
3. **Content Delivery + Rendering** — Frontend UX, Svelte components, API integration, styling
4. **Docs + QA + Regression** — Documentation updates, end-to-end verification, build checks, regression checklist
## 6. Resume Rules
- On any resume, **read this file first**, then `AI_CHECKPOINT.md`, then `AI_RESUME_PROMPT.md`.
- Do not skip batches. Do not merge batches.
- If a batch fails review, re-run that batch before advancing.
- Update `AI_CHECKPOINT.md` after every batch completes.
- Preserve all existing working behavior not explicitly listed for change.