summaryrefslogtreecommitdiff
path: root/.agent/critiques.md
blob: a507cbdeb189ee733dd066ba6974a38a481206b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Critiques (running list)

Working notes on structural/design weaknesses, gathered as they come up in
conversation rather than invented in the abstract. Not a plan — a list to
react to and prioritize before anything here gets acted on.

## Data model

1. **`native_tasks` is one flat table doing ~4 jobs.** A task, a
   chain-membership, a bucket-membership, and a recurrence-series are all
   the same row, distinguished only by which subset of bolt-on columns
   (`chain_id/position/unlocked`, `bucket_id/state/last_active_at`,
   `recurrence_freq/interval/weekdays/series_id/override`) are non-empty.
   Every new feature adds more nullable-in-practice columns to the same
   row; every query has to reason about which columns are "live" for a
   given row's shape. Cost grows linearly with feature count.

2. **No real task-dependency graph.** "Blocking" / "depends on" only exist
   as (a) a chain's implicit position ordering, or (b) free-text notes a
   human has to read and self-enforce. There's no way to express "task B
   can't start until task A" when A isn't B's chain predecessor, without
   falling back to prose. This is the literal gap hit building the Pelagic
   Marine Electronics project (5 real dependency edges, none enforceable).

3. **Chains and projects are welded 1:1.** `CreateChain` always creates its
   own backing project — no chain-within-an-existing-project, no
   multiple-chains-sharing-a-project. This is why one business plan with 7
   phases produced 7 separate entries in the project list. Looks like a
   modeling shortcut, not a deliberate choice.

4. **Three incompatible "shapes" of repeat/pooled work.** Chains (WIP-1,
   ordered, position-based), buckets (pick-N pool, cycle-based,
   staleness-ordered), and recurrence (single-task series, date-anchored)
   solve overlapping problems with three separate non-composable
   mechanisms and three separate column sets on the same table. A task
   can't be "a bucket item that's also gated behind another task" — none
   of the three concepts compose.

5. **Labels have no referential integrity.** `labels(name, color)` is
   color metadata only; actual label assignment is a raw JSON array on
   `native_tasks` with no FK to `labels.name`. A typo in a label string
   silently creates an new, uncolored "label" rather than erroring or
   reusing the existing one.

## Process / instruction-file cruft (doot-scoped)

6. **`.agent/config.md`'s "ULTRA-STRICT ROOT SAFETY PROTOCOL"** (wait for
   explicit "GO" before any system-changing call) contradicts how this
   project actually runs — confirmed stale 2026-08-14. Pending: fold into
   whatever the workspace-wide instruction-file cleanup lands on, rather
   than patch in isolation.

7. **`.agent/worklog.md`** references issues (#66-73) that don't match any
   real recent work — leftover scaffolding, not maintained. Confirmed
   stale 2026-08-14. Same pending treatment as #6.

## Integrations

Reviewed 2026-08-14. Five immediate papercuts found and fixed same day:
`getAtomDetails`'s gtasks case was a stub (logged every completed Google
Task as literally "Google Task" with no due date); gtasks completion via
the web Tasks/Timeline tab and the Agent API skipped cache invalidation
(trello had it, gtasks didn't, in two call sites); `HandleTaskDetailPage`
hand-duplicated `loadTaskDetailData`'s lookup instead of calling it, so it
never got the earlier gtasks-detail fix; `PlanToEatAPI.GetRecipes` was
dead code (own comment: "for Phase 2," never called) — deleted.

Long-term questions surfaced, not decided:
- Should `GoogleTasksAPI` grow real create/due-date methods (the REST API
  supports both; the interface just never exposed them)?
- Should the ~13 copy-pasted `switch source` dispatch blocks collapse into
  one shared resolver? Not urgent at 3 actionable sources.
- The ad hoc `findGoogleTask`/`findCard` linear-scan-by-ID lookups are
  copy-pasted inline in ~5 places instead of reused — style issue at
  current (personal-scale) data volumes, not a performance one.
- Read-path caching is already well-unified (generic `CacheFetcher[T]`) —
  don't over-correct that side, the inconsistency was only ever on
  write/invalidation.