Skip to content

Latest commit

 

History

History
204 lines (171 loc) · 16.3 KB

File metadata and controls

204 lines (171 loc) · 16.3 KB

Backlog

Open work only, one item per line. Closed items move to docs_ai/BACKLOG_DONE.md. What the tool does today: ../commands.md (generated). How it is built: ARCHITECTURE.md. What the owner ruled: docs_ai/DECISIONS.md.

Rules

  • An id is permanent and never reused. Take one with bin/next-id <PREFIX>: one counter for every worktree on the machine, under a lock, and never below the highest number on any branch. Searching the text instead gave out CLI-26 three times and MAX-16 and MAX-23 twice on 2026-09-24.
  • Prefixes: RES research and measurement · OPS repository, tooling, CI, release · CORE cli-core · SPEC protocol spec and generator · MAX domain, client, transport, session · CLI commands and output · DOC handwritten docs · PROTO protocol unknowns · RISK risks.
  • One item: the task as a title, then where the work starts (path:line or a REQUIREMENTS §). Analysis goes to a plan in docs_ai/plans/, a ruling to DECISIONS.md.
  • Priority: P1 blocks work or breaks something real · P2 this cycle · P3 someday.
  • Mark: none — not started · 🚧 <branch> — taken · 🟡 — half done, the rest named · ⏸️ — deferred by the owner · 🚩 — waits on an owner decision.
  • Claim before code: put 🚧 <branch> on the line in the first push of the branch. Two agents built the same command on 2026-09-23 because an open PR was the only signal.
  • Close in the PR that ships the work: delete the line here in that PR, and append it to docs_ai/BACKLOG_DONE.md (local, not in git). Users read what shipped in CHANGELOG.md.

Features

  • CLI-58 · P2 · 🟡 mcp --http: ChatGPT and Claude in the browser reach the CLI without a third-party proxy. Done: Streamable HTTP on 127.0.0.1 behind the owner's tunnel, a one-owner OAuth login (one-time terminal code, PKCE S256, 1 h access / 30-day rotating refresh, hashes only), every write through the form (NEED-593), --revoke — cli-messaging #527/#528/#543 (0.146.0), tg-cli #266, max-cli #398, docs/remote.md in both. Left: the live check with Claude.ai and ChatGPT through Tailscale Funnel (owner; tg-cli bin/tg-remote) — it also answers whether the apps show MCP forms at all, without which --http only reads. MAX0.28.0 and TG0.27.0 are published with core0.17.0 and cli-messaging0.147.0; the reviewed search/history/service diagnostics work is included.
  • CLI-68 · P3 · mcp --http as a background service: server install for it (systemd/launchd), so the browser apps reach a machine without an open terminal. Follows CLI-58's live check (NEED-595 A: foreground first).

From the PyMax comparison (2026-09-24, NEED-175). Each is what PyMax's source declares (MaxApiTeam/PyMax, src/pymax/api/, commit 53103f0) — a claim until measured. Every writing operation is measured first in Saved messages (chat 0), as replies and reactions were (NEED-150), and needs the owner's yes before it ships. Deleting messages was ruled out (NEED-32) until the owner asked for it on 2026-09-24 (MAX-47); marking read only on an explicit flag (CLI-33, REQUIREMENTS §19).

  • MAX-48 · P3 · Send a round video note ("кружок"): opcode 82 {type: 1, uploaderType: 1}, thumbhash from the upload answer, _type: "VIDEO" with videoType: 1. MAX refuses a file that is not 480×480, yuv420p, limited range, bt709, baseline, AAC 48 kHz mono (PyMax #94). thumbhash is bytes — a Uint8Array in a payload goes out as MessagePack bin since MAX-40.

  • MAX-49 · P3 · Two-step password: log in when MAX asks for it (passwordChallenge in the login answer, then AUTH_LOGIN_CHECK_PASSWORD 115 {trackId, password}), and set or remove one (112 → 107 → 111). PyMax 2.4.1, code; a user logged in with it on the mobile client (PyMax #106). The password is typed at a prompt, never an argument. Correction 2026-09-28: logging in with a password shipped with session start (PR #66, src/session/login.ts:51). Left: setting and removing one (112 → 107 → 111).

  • MAX-34 · 🟡 P3 · Live events: a long-running max listen that prints new messages, edits, reactions and typing as they arrive (PyMax's on_message, on_message_edit, on_reaction_update…). Conflicts with one-shot commands (CLAUDE.md constraint 4), so it needs a ruling first. What is new since the last check is already max inbox (CLI-23). Correction 2026-09-25: the long-running part exists. max serve holds the connection and max watch prints new messages as they arrive (src/server/server.ts, #pushed). What is left is edits, reactions and typing. The server receives them but passes on only new messages (opcode 128).

    Done 2026-09-25 from the third tab recording: max watch --events prints edits (128 with status: EDITED), deletions (128 with status: REMOVED) and reactions (155); the plain stream is unchanged. Left: typing — MAX pushes 129 only after 75 {chatId, subscribe: true}, which the tab sends for the chat it has open and repeats every 60 s; max serve subscribes to nothing.

  • MAX-4 · 🟡 P3 · Chat addressing. Done: an id, or a title matched exactly then as a fragment, an ambiguous one refused (resolve, src/client.ts:325; pickChat, src/resolve.ts:13). Left: @username, a phone number, a chat the account is not in.

  • CLI-36 · P3 · The local copy made optional: a setting under which max writes no chats or messages to disk and answers everything from MAX (--offline and messages search then refuse). Owner, 2026-09-24: «я бы сделал хранение опциональным в P3». Correction 2026-10-03 (T6): the per-profile cache is removed; this option would now need to control shared adapter recording and the login record (src/record.ts).

  • CLI-5 · P3 · max raw <operation> — a debug escape hatch, validated against the spec, never arbitrary frames (REQUIREMENTS §22).

  • MAX-52 · 🟡 P2 · The requests a real tab sends right after LOGIN: 21 on a fresh start (48 48 272 35 32 302 163 208 27×4 209 28 22 48 28 35 53 209 35) and 9 after a re-login. max sends none, which shows on every login — a stronger difference than telemetry. Decide per request: the read-only ones (272 folders, 302 banners, 163 call history, 27) could be copied; 22 subscribes to push and changes state. Captured 2026-09-25, docs/dev/capture/2026-09-25-web-tab.md. Names by PyMax (53103f0): 22 CONFIG, 27 ASSETS_UPDATE, 28 ASSETS_GET_BY_IDS, 32 CONTACT_INFO, 35 CONTACT_PRESENCE, 48 CHAT_INFO, 53 CHATS_LIST, 208/209 stories, 272 FOLDERS_GET, 302 BANNERS_GET; 163 is not in its list. Only max serve will send them. 2026-09-25: the recording kept 27's type only as "string", and no answer bodies, so what 27 asks for and which sync value each re-login sends back are unknown. The recorder now keeps both; the code waits on the next recording (with MAX-51).

    Done 2026-09-25 from the second recording (docs_ai/captures/2026-09-25-web-tab-2.jsonl): max serve sends 272, 302, 163 and 27 ×4 (STICKER, FAVORITE_STICKER, REACTION, ANIMOJI_SET) after every login, each re-login with the sync its previous answer returned (src/client.ts, live.readLikeTab). Left: 48 {chatIds}, 32 and 35 {contactIds}, 28, and the stories 208/209. Never: 22, which subscribes to push.

  • RES-5 · 🟡 P2 · Does LOGIN move presence or read state? Reading history does not (no CHAT_MARK, tested). Partly answered by the capture of 2026-09-25: the tab's own LOGIN sends interactive: false too; true goes only in pings, while its window has focus. Left: whether opening a chat with unread messages marks it read without opcode 50 — see RES-10. Correction 2026-09-25 (RES-10, captured): the tab marks a chat read with an explicit opcode 50 after opening it, not with 49; and 49 without interactive moves nothing (measured, RES-11). Left: whether LOGIN itself moves presence — needs a second device watching.

  • RES-7 · P3 · What a real client sends as opcode 36's payload. {}, {marker} are refused and {marker, count} closes the connection (pnpm probe:contacts), so only a capture answers it. It is the only route to contacts who share no chat. Closes PROTO-1.

  • PROTO-1 · 🟡 P3 · What opcode 36 returns: other clients call it CONTACT_LIST, the protocol notes call it GET_BLOCKED. Waits on RES-7.

  • PROTO-2 · P2 · How long MAX remembers a cid. The send retry rests on deduplication measured seconds apart; minutes apart is unproven (ARCHITECTURE.md §6).

  • PROTO-3 · P3 · The upper bound on chatsCount in LOGIN: 100 works, 200 is refused. The spec caps it at 100 (src/spec/operations/session.ts:109).

  • PROTO-6 · P3 · What the messages object in the LOGIN answer holds. Nothing reads it (src/spec/operations/session.ts:156); pnpm probe:ids prints its type and key count.

  • SPEC-3 · 🟡 P3 · Sanitized protocol fixtures, synthetic values only (REQUIREMENTS §24). Done: the web client's frames, headers and payload structure without values (src/testing/fixtures/web-capture-2026-09-25.json, MAX-40), and the recorder for more (scripts/capture/web-recorder.js). Left: fixtures of MAX's answers to our own operations — response shapes are still tested with made-up payloads in src/spec/.

  • SPEC-4 · P3 · A generated list of implemented operations (§8, §30). Deferred: listing what MAX has and we lack means maintaining MAX's whole surface (§10).

Group moderation on the personal account (NEED-306…NEED-314, plan docs_ai/plans/2026-09-27-group-moderation.md). review --unanswered shipped as CLI-43, chats events as CLI-44, chats members list as CLI-45, chats rules and chats check as CLI-46, MCP max_chats_check as CLI-47.

  • CLI-48 · P3 · Roles in chats members list come from the chat as the login carried it, which lags: right after admins add the bot still showed as member, while bot admins list already had it. Refresh the chat (opcode 48, CHAT_INFO) before reading roles, or say the roles may be old.

  • MAX-62 · P3 · Lifting a bot's ban. max <bot> bot members remove --block (and bot chats check) ban a person from rejoining by the invite link (measured 2026-09-27). The Bot API has no unblock, and the owner found no ban list in the MAX app. Re-adding the person by an admin works, but whether it lifts the ban is unknown — after leaving, the link may still refuse them. Find where MAX keeps the ban (a capture of the web client's group settings, or CHAT_MEMBERS 59 with another type), then offer max chats members unban.

Foundation and risks

  • CLI-60 · P1 · 🟡 Personal-account commands onto cli-messaging's shared commands, deleting max's copy as each moves (T6). Done: delete, reactions, pin, mark-read, send/edit/forward, polls, chats and contacts reads, messages list|show|context|search|links (#282), the store group (#307), conversations (#308), transcripts into the shared store (item 5 step 2), inbox/review (step 3), MCP reads (step 4), shared completion and store diagnostics in doctor (step 5), record-backed client/callers/serve (#340–#343), removal of the cache command and storage code (steps 6–7), and contact writes (add|remove|block|unblock|rename|import), the chats folders group, and account update/account sessions list|end, and group administration (create|join|leave|update, members/admin writes, invite links), and group reads (members list, events, inspect), and shared moderation/rules with legacy checkpoint migration. Left: a live check of messages list --transcribe. MAX permission levels, config migration and MCP filtering are complete. Correction 2026-10-03: models text is shared since #322; models audio, its catalogue and installer now use the shared package too. Plan and handoff: docs_ai/plans/2026-10-02-t6-item5-cache-off.md, docs_ai/plans/2026-10-02-t6-item5-handoff.md. Shared runner and operational diagnostics: done (#347/#352). Correction 2026-10-03: search read-only MCP bridge is merged (#357), as is the shared package-upgrade workflow (#358). The permission-model move is complete. Canonical permissions now govern CLI/native reads, server writes/reads and MCP; config migrate preserves legacy levels and group checkpoints.

  • CORE-10 · P3 · Plugins from npm, only from an allow-list kept in the CLI itself — package names with pinned versions and integrity hashes — never an arbitrary package: a plugin runs inside a program holding the token of a personal account. oclif's plugin-plugins is the model.

  • CORE-11 · P3 · Installers and standalone archives per platform (oclif's pack), after a single-file build (G4 §3.9: Bun only). Lowest priority.

  • RES-12 · P3 · Word search at 1M messages misses the speed targets of storage phase 2 §6 (accepted for phase 2 by the owner, 2026-10-02): every word with no chat or sender filter up to 124 ms (45), any word over all chats up to 232 ms (130), filling the index 53 s (20) with a 1.2 s vocabulary batch (500 ms). Every target holds at 100k. Starts at cli-messaging src/store/sqlite/words.ts (matchWords, the ranked-first path) and src/store/sqlite/search-index.ts (fillSearchIndex); measure with bench/search/store-chain.ts (cli-messaging bench/search/results.md, "Phase 2 item 8").

Later — each reopens a ruling

Added by the owner on 2026-09-24. Each one goes against REQUIREMENTS §3 or §18, and the line says which; the plan for it starts by saying so.

  • CLI-27 · P3 · Hooks for workflows: max runs a configured command when a check finds something new. Asked by the owner 2026-09-24 (NEED-172). Two things to settle in the plan: the message text reaches that command, so it must go as data on stdin and never into the command line; and max watch --jsonl | <command> on a running max serve (MAX-35) already does this for live messages, as max inbox --new on a schedule does for batches — say what a hook adds over those two pipes. Correction 2026-09-24: written before max serve existed.

Parity tooling follow-up

  • Completed 2026-10-04: release documentation describes canonical P7 defaults, resource-specific restrictions, explicit deletion confirmation and current permission recipes. Publication is separate.

  • Completed 2026-10-03: repository parity-audit skill runs the shared detailed auditor (#365; shared #470–#474). No account access.

  • Completed 2026-10-03: shared sends-list factory honors configured limit and shared skill factory exposes named link-conversations instructions (#368).

  • Completed 2026-10-03: message downloads, scheduled reads and evidence now use shared factories (#370); MAX retains safe transport and compatibility --output. Session-end mutation metadata is explicit.

  • Completed 2026-10-03: shared account-show factory retains MAX profile fields; contact-lookup argv refusal never repeats a number (#371). Permission runtime remains with T6/P7.

  • Completed 2026-10-03: response MIME preserves shared download fallback extensions (SDK0.136); streams remain lazy and bounded, without eager unused attachment requests.

  • Completed 2026-10-03: chats-show member counts explain possible self omission or partial lists without claiming incomplete loading (SDK0.137, CLI-62). Online and offline consumer regressions retain JSON counts and members.

  • Completed 2026-10-03: MAX poll.already.voted refusal explains explicit retract before a new vote when the poll permits changing votes (CLI-61). Provider error identity and one attempted write are preserved; wire refusal regressions cover other errors and an explicit retract refusal.

  • Completed 2026-10-04: coordinated MAX0.27.0/TG0.26.0 published, provenance and installed CLI versions verified; core0.17/shared0.140.

  • MCP parity · ✅ canonical personal tool catalogue and strict shared input schemas mounted on MAX’s held session; missing supported bindings and local-write permission checks implemented. Telegram forum tools remain unavailable; legacy moderation/rules names and native preview/transcript behavior retained. Shared prerequisite 0.144.0; final synthetic audit is kept in the private implementation plan. Consumer publication is separate.