Skip to main content

max / goingson

Record which JS file belongs to which described module Three claims about what was portable next were made and retracted on this task, each wrong in a way one grep would have caught. The cause was that nothing recorded the mapping: src/quasi/*.rs named a counterpart in prose only, and 6 of 8 did even that. All 48 esc()-carrying files are now accounted for in quasi/mod.rs, in four categories that sum to the measured 327. Described and retiring at the flip, 193. Staying JavaScript by decision, 50. Un-ported screens, 57, which is the only place to look for the next candidate. Not a screen at all, 27. Two things fall out of writing it down. The task list is not tasks.rs: that module is the single-task drawer at GET /tasks/{id} and board.rs is the kanban, so the list has no counterpart and nobody had noticed. And 77 sites are not reachable by porting anything, so the zero-esc done-condition needs an answer for them rather than more ports. The drift the task flagged as unverified is real, and it is not arithmetic. tasks.rs claimed task-overview.js carried 15 esc() at port time; it carried 19 plus 2 escAttr(, so the 15 matched nothing when it was written. The file is at 26 plus 7 today because 338aa9f gave tasks a blocking graph and the drawer grew a Dependencies section: blockers, dependents, their edit controls, a blockDepth badge, an unblocks count, a cycle warning. None of it is described here. board.rs carries the flat blocked and unblocks markers as tokens, so the gap is the section rather than the vocabulary. Nothing checks a described screen against the counterpart it was ported from, and this is the first time anyone asked, of any of the eleven ports.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-15 19:00 UTC
Signed with PGP, not checked
Commit: ef7e87c4172ccce72bb56b2f3ee39ab8752898e3
Parent: e86c70a
2 files changed, +95 insertions, -3 deletions
@@ -27,6 +27,75 @@
27 27 //! `Router::merge`, so composition is a chain of functions that each take the
28 28 //! router and give it back, rather than a table assembled somewhere central
29 29 //! that has to be kept in step with the modules.
30 + //!
31 + //! # Which JS file belongs to which described module
32 + //!
33 + //! Measured 2026-08-15: 48 files under `frontend/js/` carry 327 `esc()` call
34 + //! sites, plus 2 more in the `js/tests/run.js` gate. Every one of them is
35 + //! accounted for below, in one of four categories.
36 + //!
37 + //! This table exists because without it every claim about what is portable next
38 + //! is a guess. Three such claims were made and retracted, each of them wrong in
39 + //! a way one grep would have caught. Read the flat count correctly: a described
40 + //! screen does not delete its JS counterpart while the feature is off, so both
41 + //! exist and both are counted. The count starts falling at the flip. Progress is
42 + //! the first list, not the number.
43 + //!
44 + //! ## Described, and retires at the flip (22 files, 193 sites)
45 + //!
46 + //! | Module | JS counterpart | Sites |
47 + //! |---|---|---|
48 + //! | [`projects`] | `projects.js` 8, `projects-render.js` 16 | 24 |
49 + //! | [`contacts`] | `contacts.js` 12, `contacts-render.js` 29, `contact-dashboard.js` 16 | 57 |
50 + //! | [`tasks`] | `task-overview.js` | 26 |
51 + //! | [`emails`] | `emails.js` 3, `emails-render.js` 5, `emails-reader.js` 13, `emails-filter.js` 3, `emails-compose.js` 2 | 26 |
52 + //! | [`weekly_review`] | `weekly-review.js` 3, `weekly-review-render.js` 16 | 19 |
53 + //! | [`day_planning`] | `day-planning-render.js` 8, `day-planning-schedule.js` 4, `day-planning-paint.js` 1 | 13 |
54 + //! | [`problems`] | `problems.js` | 10 |
55 + //! | [`monthly_review`] | `monthly-review.js` 3, `monthly-review-render.js` 5 | 8 |
56 + //! | [`settings`] | `settings.js` | 6 |
57 + //! | [`board`] | `tasks-kanban.js` 3, `task-board.js` 1 | 4 |
58 + //!
59 + //! [`projects`] carries its dashboard as a submodule, which is the eleventh
60 + //! described screen against ten modules here.
61 + //!
62 + //! ## Stays JavaScript, by decision (4 files, 50 sites)
63 + //!
64 + //! - `settings-sync.js` 17, `settings-sharing.js` 14, `email-accounts.js` 10.
65 + //! Host-bound: OAuth flow, credential handling, `invoke(`.
66 + //! - `search.js` 9. Settled 2026-08-13 (quasicoherent `d52884b0`): a described
67 + //! field's state is its value, and the caret is the renderer's.
68 + //!
69 + //! These 50 never reach zero by porting. Retiring `escape.js` means giving them
70 + //! typed escaping some other way, or accepting that four files keep an escaper.
71 + //!
72 + //! ## Un-ported screens (12 files, 57 sites)
73 + //!
74 + //! A described counterpart could exist and does not. This is the candidate list,
75 + //! and it is the only place to look for what is portable next.
76 + //!
77 + //! - The task **list**, which is not [`tasks`]: that module is the single-task
78 + //! drawer at `GET /tasks/{id}`, and [`board`] is the kanban. The list itself
79 + //! has no counterpart. `tasks.js` 2, `tasks-render.js` 8, `tasks-filter.js` 2,
80 + //! `task-forms.js` 1, `saved-views.js` 1. 14 sites.
81 + //! - `import-external.js` 11, `import.js` 5, `export.js` 2. 18 sites.
82 + //! - `events.js` 10. Its grid rendering is bespoke; whether the CRUD/list half
83 + //! is a real candidate is unchecked, and per this table that is a claim to
84 + //! measure rather than assert.
85 + //! - `time-tracking.js` 6, `time-summary.js` 3. Waits on quasicoherent
86 + //! `f00244a6`, who owns a ticking clock.
87 + //! - `task-graph.js` 6. Draws the blocking DAG.
88 + //!
89 + //! ## Not a screen (10 files, 27 sites)
90 + //!
91 + //! Shared chrome and behaviour with no screen to belong to, so no port will
92 + //! reach them and they are not candidates. `components-modal.js` 7,
93 + //! `compose-form.js` 5, `whats-new.js` 3, `attachments.js` 2,
94 + //! `autocomplete.js` 2, `bulk-actions.js` 2, `plan-review-toggle.js` 2,
95 + //! `snooze.js` 2, `form-modal.js` 1, `groups.js` 1.
96 + //!
97 + //! Together with the 50 above, these 77 sites are what the done-condition
98 + //! actually has to answer for. Porting every candidate screen leaves them.
30 99
31 100 use std::sync::Arc;
32 101
@@ -2,11 +2,34 @@
2 2 //!
3 3 //! <!-- wiki: quasi-overview -->
4 4 //!
5 - //! Third screen ported, chosen by weight from `task-overview.js`: 15 `esc()`
6 - //! calls, and the fattest single screen left after contacts. The shipped screen
7 - //! is `frontend/js/task-overview.js` exactly as before; see [the module
5 + //! Third screen ported, chosen by weight from `task-overview.js`, the fattest
6 + //! single screen left after contacts. The shipped screen is
7 + //! `frontend/js/task-overview.js` exactly as before; see [the module
8 8 //! above](super) for why both exist at once.
9 9 //!
10 + //! This header used to say the file carried 15 `esc()` calls at port time. It
11 + //! carried 19, plus 2 `escAttr()`, measured at `a76f6d8` where this module was
12 + //! added. The 15 was wrong when it was written and matches nothing.
13 + //!
14 + //! # This description is behind the shipped screen
15 + //!
16 + //! Measured 2026-08-15, and the reason the count above was worth chasing.
17 + //! `task-overview.js` is at 26 `esc()` and 7 `escAttr()` today. Two commits
18 + //! touched it since the port, and one of them was a feature:
19 + //! `338aa9f` gave tasks a blocking graph, and the drawer grew a whole
20 + //! Dependencies section for it. Blockers and dependents with their edit
21 + //! controls, a "Blocked, N steps away" badge off `blockDepth`, an "unblocks N
22 + //! tasks" count, and a warning when the task sits on a cycle.
23 + //!
24 + //! Nothing in this module says any of it. [`super::board`] describes the blocked
25 + //! and unblocks markers as tokens, so the vocabulary can carry the flat facts;
26 + //! it is the section, its lists and its two edit controls that are undescribed
27 + //! here. Whether that is a port or a vocabulary question is unmeasured.
28 + //!
29 + //! Worth knowing generally: a described screen does not stop its JS counterpart
30 + //! from growing, and nothing checks the two against each other. This is the
31 + //! first time anyone asked, of any of the eleven ports.
32 + //!
10 33 //! This is the first port with something the vocabulary is meant not to reach.
11 34 //! The completion heatmap is a month grid of counts, and a description
12 35 //! expressive enough to produce one is a widget library wearing a description's