# TODO Durable backlog. Agents append here instead of leaving `TODO` comments in source. Small, specific, independently actionable. Remove only when actually done. ## Now - [ ] Choose a linter/formatter (e.g. Biome), then add `lint` to `package.json`, `AGENTS.md` and `docs/PERMISSIONS.md`. - [ ] Add CI on Gitea Actions: install, typecheck, and test on SQLite and Postgres. Add a guard that fails if `AGENTS.md` is over 150 lines. - [ ] Agent permissions for Task 16 commands: add `bun run typecheck`, `bun apps/server/src/main.ts` and `bun --hot apps/server/src/main.ts` (all verified 2026-10-30) to `docs/PERMISSIONS.md`, `.claude/settings.json`, `.gemini/settings.json`, then fill Typecheck/Dev/Start in `AGENTS.md` Commands. Needs a human: agents may not edit their own permission files. ## Next - [ ] API: response schemas in the OpenAPI document (requests only today). - [ ] API: login/register rate limit is per process and keyed on the socket IP; behind a reverse proxy every client shares one key. Add a trusted-proxy setting for `X-Forwarded-For`. - [ ] API: file imports are base64 in the `jobs.payload` row (up to ~67 MB of text). Move uploads to `DATA_DIR/uploads/` and pass a path. - [ ] API: `PATCH list-items/:id` only moves items; editing an item's note needs a core function. - [ ] Connections: a user-paused connection that never had credentials looks deleted (`paused` + no credentials) and disappears from `GET sources`. Add an explicit `deleted_at`. - [ ] Phase 2 and Phase 3 plans (spec §12). - [ ] Generate image thumbnails for attachments (Phase 1 sizes images with CSS). ## Someday ## Recurring - [ ] Maintain `AGENTS.md`: - **Add a rule only in response to a real failure.** When an agent repeatedly gets something wrong, that is a gap; add one line, ideally with a code example. Do not pre-empt hypothetical mistakes. - **Update in the same PR as the convention change.** A stale rules file is worse than none, because it actively misleads. - **Prune quarterly.** Delete rules whose convention has changed or whose mistake no longer occurs. - **Optional, cheap validation:** run the same task twice in clean sessions, with and without the file, and compare steps and token use. ## Known issues - [ ] Plugins: reload re-imports entry files only; edits to a plugin's other modules need a server restart. - [ ] Plugins: rate limiting is per run (each run builds its own client), not per plugin (spec §11); share a limiter per plugin in Phase 2. - [ ] Plugins: `ctx.log` reaches `source_runs.log` only after the run ends, so a crash mid-run loses it. - [ ] Sync: two concurrent runs of one connection outside the job queue (e.g. a manual run) can still race on `source_records`. Queued syncs are serialised by `lockKey`. - [ ] Restore: a new child work whose parent+position collides with an existing child of a re-matched parent fails with `ImportError("conflict")` instead of being merged or repositioned. - [ ] Restore: an unlink of identical attachment bytes between the pre-write and the commit could remove the file; mitigated by re-writing after commit, not locked. - [ ] Export bundles hold attachment bytes in memory; very large libraries need a streaming zip. - [ ] Admin merge does not merge colliding children recursively; colliding children stay under the tombstoned parent. - [ ] Matching: a shared parent resolved without external IDs or position (title/year reuse in `packages/core/src/matching.ts`) has no unique key, so concurrent matches can create it twice. - [ ] Library search (`q`) and the title sort use the work's title, not the user's `overrides.title` (overrides are a JSON text column). The `tag` filter matches the JSON text with LIKE. - [ ] Library hierarchy rollup and orphan detection look three levels deep; deeper trees are not rolled up. - [ ] Undoing a per-user move does not move copies or list items back, nor restore aliases that the move re-pointed. - [ ] `bun run typecheck` fails with TS18003 until source files exist under `apps/`, `packages/` or `plugins/`.