aboutsummaryrefslogtreecommitdiff
path: root/assets/2026-07-31-agenda-json-api-contract.txt
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-10-05 22:33:45 -0600
committerCraig Jennings <c@cjennings.net>2026-10-05 22:34:54 -0600
commit3472deda0fcc13425717554b3708052b078ff9d2 (patch)
tree15dc9fb21ebe597b58c0be843d1742d5027f3ac1 /assets/2026-07-31-agenda-json-api-contract.txt
parent1e134f5022f626ed36279915369c06fa6df0e76e (diff)
downloadarchsetup-3472deda0fcc13425717554b3708052b078ff9d2.tar.gz
archsetup-3472deda0fcc13425717554b3708052b078ff9d2.zip
chore(assets): file the nine inbox handoffs worth keeping
The inbox held 74 processed handoffs from July and August. Nine carry reference material (three hardware photos, the board-swap context and the settings-panel and agenda-json notes) and move flat into assets/ under dated names. The photos are downscaled to 1600px and stripped of EXIF before entering a cloneable repo. Four more were already filed under docs/design on 09-13, so the archive's diagnosis link now points there. Two stay out of the tree on purpose: their facts are recorded elsewhere and their text is not for a public repo. I deleted the rest: acknowledgements, receipts and requests that had already become tasks.
Diffstat (limited to 'assets/2026-07-31-agenda-json-api-contract.txt')
-rw-r--r--assets/2026-07-31-agenda-json-api-contract.txt79
1 files changed, 79 insertions, 0 deletions
diff --git a/assets/2026-07-31-agenda-json-api-contract.txt b/assets/2026-07-31-agenda-json-api-contract.txt
new file mode 100644
index 0000000..e4253e1
--- /dev/null
+++ b/assets/2026-07-31-agenda-json-api-contract.txt
@@ -0,0 +1,79 @@
+It's built and pushed. Function, call example, then three things you need to know before you wire it.
+
+* The call
+
+ (cj/agenda-window-json START-EPOCH END-EPOCH &optional OUT-PATH)
+
+From a shell:
+
+ emacsclient --eval '(cj/agenda-window-json 1785474000 1785560399 "/tmp/agenda.json")'
+
+Both bounds are epoch seconds, inclusive. It returns the JSON string and, with
+OUT-PATH, also writes it there through a temp file and a rename. The file lands
+0644 so a reader running as anyone can open it.
+
+Per row: title, start, end, all-day, type, file, keyword, done, repeater,
+location, organizer. Absent values are null rather than omitted, so the shape is
+stable. Verified against my real agenda: 13 rows today, sorted by start, both
+calendars and both todo files, no Emacs buffer left modified.
+
+* The repeater premise was wrong, and the real gap is bigger
+
+You cited "Sched. 19x:" as evidence of repeating entries. That is
+org-agenda-scheduled-leaders, and the number counts days an unfinished
+scheduled item has been carried forward. It is not a repeater. My agenda files
+contain zero repeating timestamps right now.
+
+Your instinct was right anyway, and it points at something worse than the case
+you asked about. I have 18 undone scheduled items dated before today. Org shows
+every one of them on today's agenda, because that is what carrying forward
+means. A query that selects on timestamps inside the window cannot see them. So
+today my agenda has about 31 items and this query returns 13.
+
+Deadlines do the same thing in the other direction: org surfaces a deadline up
+to 14 days before its date, and the query only returns it on the day itself.
+
+I have not guessed at what you want here, because it is a real design question
+for your surface rather than a bug. A 24-hour axis has nowhere obvious to draw
+"overdue since the 12th." Three options, roughly: leave it (a timed-events
+surface, which is defensible), add an overdue flag and let you decide where they
+go, or pin them to the window start. Tell me which and I will build it.
+
+* The .+ field is not there, and I think it should not be
+
+You asked for the fallback mark as a testable field. I did not add it, because
+the state it marks cannot occur, and I would rather tell you than ship a field
+that is permanently false.
+
+Org's own org-closest-date matches the repeater with a regexp that ignores the
+prefix entirely, so .+ and ++ expand from the base exactly like +. The restart
+semantics happen at completion time: org rewrites the base timestamp in the file
+when you close the task. So for an open task the base already is the last
+repeat, and there is nothing unresolved to mark.
+
+You said to tell you rather than guess, so this is me telling you. If you still
+want the field for defensive reasons, say so and it is a one-line addition.
+
+* Smaller things worth knowing
+
+Repeats resolve at day granularity, matching org's agenda, so an hourly repeater
+gives one row per day rather than one per hour.
+
+Archived and commented subtrees are skipped, because org's agenda skips them.
+
+Titles render org links as their description text. One of my live entries is a
+captured web item, and it would otherwise arrive as [[https://...][Tracking your
+habits]] on your wallpaper.
+
+The window is capped at 366 days, and each bound must fall between 1900 and
+2200. Both checks exist for one reason: Date.now() returns milliseconds. Passing
+it for both bounds looks like a plausible 41-day window and answers with dates in
+the year 58549, so magnitude is checked as well as width.
+
+* On the tests
+
+58 of them, across three files. The SCHEDULED one you asked for is there, and
+its fixture carries no body timestamp on purpose, so an implementation that
+drops planning timestamps fails it rather than passing on the body stamp.
+
+The trap earned its comment in the source, as you suggested.