events: pure event parser and describe rows (calendar step 3) #783
Closed
kayg
wants to merge 8 commits from
feat/calendar-event-parser into dev
pull from: feat/calendar-event-parser
merge into: kayg:dev
kayg:main
kayg:feat/style-sheet-fixes
kayg:storage/wal-checkpoint-off-save-1051
kayg:t3/paged-search-reconcile-final
kayg:feat/pass8
kayg:review/calendar-2
kayg:fix/shared-row-swipes
kayg:feat/contrast
kayg:dev
kayg:feat/collections-db
kayg:fix/instant-keys-1056
kayg:feat/money-round
kayg:perf/stalls-1054
kayg:wip/tiering-v3-cold4
kayg:wip/tiering-v3-cold5
kayg:port/rows-actions
kayg:port/rows-drop
kayg:port/hidden-blocks
kayg:port/rows
kayg:port/port-tables
kayg:port/port-tables-2
kayg:t3/mail-1011-liveness
kayg:port/devices
kayg:port/port-attachments
kayg:port/port-attachments-2
kayg:port/port-attachments-3
kayg:docs/design-consistency
kayg:docs/engineering-standards
kayg:fix/rusqlite-0.41-rustsec-2026-0459
kayg:feat/iphone-fixes
kayg:shared/restore-and-stale-918-919
kayg:fix/phone-top-band-contrast
kayg:feat/notes-approve
kayg:perf/soak-max-gate
kayg:feat/files-s1-identity
kayg:fix/lifecycle-event-id
kayg:feat/quickfix
kayg:wip/tiering-v3-cold
kayg:perf/web-mockup-frame-fixes
kayg:port/contacts-merge
kayg:port/contacts-edit
kayg:test/shared-room-no-deleted-text
kayg:perf/first-paint-credits
kayg:fix/shared-history-after-grant
kayg:fix/phone-swipe-regressions
kayg:feat/contrast-r1
kayg:review/sharing-pr3-review
kayg:feat/tiering-v3-s2-tags
kayg:feat/folder-drop
kayg:fix/deskpills-lazy-share
kayg:feat/sharing-s1-pr3
kayg:tmp/money-round-before
kayg:fix/phone-pane-backdrop-roots
kayg:fix/palette-preload-chips
kayg:fix/invite-defaults
kayg:port/tasks-matrix
kayg:fix/restore-green-gates
kayg:fix/sharing-fast-path-hardening
kayg:t3/photos-s1
kayg:feat/tiering-v3-s1-namespace
kayg:notes-archive-hide
kayg:feat/tasks-actions
kayg:t3/photos-plan-slice-one
kayg:feat/whiteboard-s1
kayg:t3/paged-search-reconcile
kayg:t3/smooth-pane-transitions
kayg:t3/index-position-startup-scan
kayg:fix/private-staging-759b-r2
kayg:feat/dav-transport
kayg:feat/imap-notes-fetch
kayg:feat/imap-notes-projection
kayg:feat/imap-notes-readonly
kayg:feat/imap-notes-auth
kayg:feat/imap-notes-server-foundation
kayg:docs/undo-block-ids-plan
kayg:fix/undo-768
kayg:proto/block-identity-v7d
kayg:issue/carddav-read-perf-fix-r2
kayg:issue/carddav-read-r2
kayg:docs/imap-766-plan-v2
kayg:docs/imap-notes-plan
kayg:docs/quota-plan-2
kayg:fix/parallel-test-flakes
kayg:feat/contacts-companion-pure
kayg:docs/calendar-backend-v2-plan
kayg:feat/calendar-ical-converter
kayg:docs/tasks-writes-v2-plan
kayg:docs/carddav-writes-v2-plan
kayg:docs/contacts-import-v2-plan
kayg:issue/610-pm-midnight
kayg:feat/calendar-v2-s1-containment
kayg:docs/dav-recorder-v2-plan
kayg:plan/previews-865
kayg:plan/save-log-durable-entry
kayg:fix/e2e-data-on-ram
kayg:feat/appwindow3
kayg:feat/appwindow2
kayg:feat/appwindow
kayg:feat/money-p1
kayg:feat/keys-sheet
kayg:review/calendar-2-themes
kayg:feat/smooth-cursor
kayg:fix/float-style
kayg:review/calendar-2-float
kayg:release/2026-11-06-hotfix
kayg:archive/port/rows-drop-code
kayg:archive/port/rows-actions
kayg:archive/port/rows
kayg:scratch/tasks-894-ui-gates
kayg:review/calendar-2-night-wip
kayg:release/2026-11-05
kayg:archive/feat/tiering-v3-s1-namespace
kayg:archive/flaky/rows-drop-fixed
kayg:archive/flaky/rows-actions
kayg:archive/feat/tiering-v3-reader
kayg:archive/feat/tiering-v3-roots
kayg:archive/flaky/rows
kayg:sim/bm15-final
kayg:sim/bm15-fix
kayg:sim/bm15-bis-932
kayg:sim/bm15-bis-909
kayg:sim/bm15
kayg:sim/bm15-bis-887
kayg:perf/tiering-option-b
kayg:port/style-3
kayg:port/style-2
kayg:port/style
kayg:fix/sw-lazy-precache
kayg:fix/vim-w-waits-for-save
kayg:fix/signout-test-races
kayg:fp-scratch/all
kayg:sim/bm15-first-paint
kayg:archive/bm15/rows-drop
kayg:archive/bm15/rows-actions
kayg:fix/palette-snippet-contrast
kayg:archive/bm15/rows
kayg:archive/bm15/hidden
kayg:archive/plan/save-log-durable-entry
kayg:mock/money-fix2
kayg:archive/fix/e2e-data-on-ram
kayg:mock/appearance-all
kayg:mock/pill-press
kayg:archive/docs/design-consistency
kayg:mock/auto-swipes
kayg:mock/mail-actions
kayg:archive/feat/mail-p1
kayg:mock/money-static
kayg:archive/review/standards-917
kayg:archive/docs/engineering-standards
kayg:perf/tiering-761-fix
kayg:mock/type-audit
kayg:mock/third-pane
kayg:feat/contacts-import-v2-s1
kayg:perf/executor-hot-path
kayg:archive/port/hidden-blocks
kayg:archive/port/devices
kayg:scratch/executor-on-894
kayg:scratch/executor-spans2
kayg:scratch/executor-spans
kayg:train/2026-11-03-bm14c
kayg:archive/port/rows-drop
kayg:feat/tiering-761-d-scale
kayg:feat/tiering-761-c-index
kayg:feat/tiering-761-b-reader
kayg:archive/review/sharing-pr3-review-9fec3d1f
kayg:train/2026-11-03-bm14b
kayg:perf/ports-lazy-budgets
kayg:feat/tiering-761-a-migration
kayg:train/2026-11-03-bm14
kayg:train/2026-11-03-bm12
kayg:archive/review/sharing-pr3-review
kayg:archive/feat/sharing-s1-pr3
kayg:train/2026-11-03-bm11
kayg:archive/feat/imap-notes-fetch
kayg:train/2026-11-03-bm10
kayg:archive/review/sharing-pr3-review-code
kayg:archive/plan/previews-865
kayg:train/2026-11-02-bm9
kayg:archive/port/port-attachments-3
kayg:archive/port/contacts-merge
kayg:fix/motion-audit-859
kayg:train/2026-11-02-bm8
kayg:archive/scratch/bm8-prep
kayg:archive/port/port-pickers
kayg:archive/port/port-tables-2
kayg:archive/port/port-tables
kayg:archive/feat/sharing-s1-pr3-code
kayg:archive/scratch/bm7-fixed
kayg:train/2026-11-02-bm7
kayg:archive/fix/parallel-test-flakes-code-minipc01
kayg:train/2026-11-02-bm6
kayg:docs/imap-766-readonly-slice
kayg:feat/dav-recorder-v3
kayg:research/788-diagnosis
kayg:archive/fix/parallel-test-flakes
kayg:archive/perf/pr792-cold-index-edit
kayg:docs/sharing-slice-1
kayg:archive/docs/imap-766-plan-v2
kayg:feat/dav-recorder-v2
kayg:archive/docs/dav-recorder-v2-plan
kayg:spike/imap-766-s0-cases
kayg:archive/fix/undo-768
kayg:feat/dav-recorder
kayg:archive/docs/contacts-import-v2-plan
kayg:archive/feat/calendar-ical-converter
kayg:feat/contacts-import
kayg:perf/cold-growth-on-764
kayg:perf/cold-growth-on-tiering
kayg:archive/docs/tasks-writes-v2-plan
kayg:archive/docs/calendar-backend-v2-plan
kayg:archive/feat/contacts-companion-pure
kayg:feat/tasks-set-status
kayg:feat/tasks-move-reorder
kayg:archive/docs/carddav-writes-v2-plan
kayg:archive/feat/calendar-v2-s1-containment
kayg:feat/tasks-delete-promote-duplicate
kayg:archive/feat/dav-transport
kayg:archive/fix/carddav-rebuild-r1
kayg:archive/fix/carddav-retention-r1
kayg:feat/carddav-writes
kayg:perf/quota-on-tiering
kayg:perf/quota-simple
kayg:perf/cold-growth-on-quota-stack
kayg:feat/calendar-identity
kayg:feat/calendar-props-maps
kayg:port/glass-when-ring
kayg:feat/tiering-761-s1
kayg:wip/10by32-01-impl-759b-scratch-20261030
kayg:wip/6by32-01-bm3-webkit-pause-20261030
kayg:wip/10by32-01-bm3-chromium-pause-20261030
kayg:wip/6by32-01-tier-761-s1-pause-20261030
kayg:spike/imap-766-s0
kayg:wip/6by32-02-calternal-pause-20261030
kayg:wip/8by64-01-review-688-pause-20261030
kayg:wip/6by32-01-verify-744-pause-20261030
kayg:wip/6by32-01-verify-742-pause-20261030
kayg:fix/private-staging-759b
kayg:wip/6by32-01-review-748-pause-20261030
kayg:wip/6by32-01-review-733c-pause-20261030
kayg:wip/6by32-01-review-733b-pause-20261030
kayg:wip/6by32-01-perf-idle-8-pause-20261030
kayg:wip/6by32-01-perf767-base-pause-20261030
kayg:wip/6by32-01-perf767b-767-pause-20261030
kayg:wip/6by32-01-perf767b-764-pause-20261030
kayg:wip/6by32-01-perf767-767-pause-20261030
kayg:wip/6by32-01-perf767-764-pause-20261030
kayg:wip/6by32-01-lists-b-pause-20261030
kayg:wip/6by32-01-ids-verify5-pause-20261030
kayg:wip/6by32-01-ids-verify4-pause-20261030
kayg:review/calendar-month
kayg:wip/10by32-02-undo-768-20261030
kayg:test/ids-verify3
kayg:wip/10by32-02-bm3-chromium-20261030
kayg:wip/10by32-01-review-753-20261030
kayg:wip/10by32-01-perf-idle-2-20261030
kayg:wip/10by32-01-bm2-webkit2-20261030
kayg:plan/759b-staging
kayg:train/2026-10-30-bm2
kayg:review/758b-tests
kayg:review/758-tests
kayg:review/764d-tests
kayg:review/767b-tests
kayg:review/preview-2026-10-29
kayg:review/767-tests
kayg:docs/tiering-731-plan
kayg:wip/c6b02-when2
kayg:wip/c6b02-tasks-create-fix5
kayg:wip/c6b02-settings-frost-mock
kayg:wip/c6b02-settings-frost-base
kayg:wip/c6b02-settings-frost
kayg:wip/c6b02-ring
kayg:wip/c6b02-review-733d
kayg:wip/c6b02-bm1-full-a
kayg:wip/compute02-when-field
kayg:wip/compute02-webkit-lists-repro
kayg:wip/compute02-train-bl2-dev
kayg:wip/compute02-dev-green-pw164
kayg:docs/deploy-plan
kayg:review/764c-tests
kayg:review/764b-tests
kayg:review/748g-tests
kayg:review/764-tests
kayg:review/759b-tests
kayg:fix/storage-owner-liveness-642
kayg:fix/storage-fix-7
kayg:wip/compute02-storage-fix-7
kayg:review/759-tests
kayg:feat/tiering-731
kayg:wip/tiering-731-first-attempt
kayg:wip/compute02-storage-fix-1
kayg:review/754g-tests
kayg:perf/idle-honest-2
kayg:review/754f-tests
kayg:review/754e-tests
kayg:review/755-tests
kayg:review/754d-tests
kayg:review/754c-tests
kayg:review/754b-tests
kayg:review/754-tests
kayg:fix/storage-private-tmp-642-dev
kayg:wip/compute02-verify-750
kayg:test/ids-verify5
kayg:test/ids-verify4
kayg:fix/storage-exact-file-quarantine-642
kayg:wip/compute02-verify-740
kayg:perf/one-flush-save
kayg:review/calendar-static
kayg:wip/compute02-verify-737
kayg:review/indexing-ring
kayg:review/when-field-2
kayg:wip/compute02-review-733
kayg:proto/block-identity-2-review
kayg:proto/block-identity-review
kayg:wip/c6b02-tc-design
kayg:review/when-field
kayg:issue/tasks-create-ids
kayg:issue/tasks-create
kayg:review/combined
kayg:wip/compute02-review-combined
kayg:review/task-polish
kayg:review/top-buttons
kayg:review/q1-q5
kayg:train/2026-10-26-bl2
kayg:archive/wt-398h
kayg:archive/train-bm-proptest-seed
kayg:archive/integ325-293
kayg:archive/integ325-ci
kayg:archive/client-auth-review-baseline
kayg:archive/wt-sim-4853
kayg:archive/wt-sim-4811
kayg:archive/wt-448m
kayg:archive/wt-398a-allocator
kayg:issue/calendar-adr
kayg:archive/old/train/2026-10-23bk2
kayg:archive/old/train/2026-10-23bk
kayg:issue/469-mockup-9a
kayg:issue/smart-tasks-mockup
kayg:issue/469-menus
kayg:issue/652-signout-flake
kayg:issue/652-history-fix7
kayg:issue/652-history-fix6
kayg:archive/old/issue/spring-check-perf
kayg:issue/spring-check-perf
kayg:issue/659-rename-fast
kayg:archive/old/train/2026-10-21ar
kayg:issue/search-hardening-3
kayg:issue/652-history-fix5
kayg:issue/660-port-sheets-glass
kayg:issue/652-history-fix4
kayg:issue/652-history-fix3
kayg:issue/652-history-fix2
kayg:issue/652-history-flake
kayg:train/2026-10-21an
kayg:issue/settings-admin-port
kayg:issue/search-port
kayg:train/2026-10-20am
kayg:issue/storage-split-fix2
kayg:issue/storage-split
kayg:archive/old/issue/folder-ids-fix
kayg:train/2026-10-20al
kayg:archive/old/issue/folder-ids
kayg:train/2026-10-20ak
kayg:issue/tables-mockup
kayg:train/2026-10-19aj
kayg:train/2026-10-19ai
kayg:issue/469-merge-fixes
kayg:issue/sidebar-band
kayg:archive/old/issue/608-settings-spec
kayg:train/2026-10-19ah
kayg:issue/swipe-offscreen
kayg:train/2026-10-19ag
kayg:archive/old/issue/590-nlp-adr
kayg:archive/old/issue/587-event-after-write-2
kayg:train/2026-10-19af
kayg:archive/old/issue/587-event-after-write
kayg:issue/469-pill-room-c
kayg:issue/469-pill-room
kayg:train/2026-10-19ae
kayg:issue/469-narrow-handle
kayg:issue/397-ios-swipe-2
kayg:archive/old/issue/adrs-photos-files-tasks
kayg:issue/469-desk-fixes
kayg:archive/old/issue/auto-update-adr
kayg:issue/469-filter-gap
kayg:issue/469-port-1b
kayg:issue/442-opacity-flake
kayg:archive/397-ios-swipe-2
kayg:issue/327-web-fast-3
kayg:archive/old/issue/469-port-1
kayg:issue/469-port-1
kayg:issue/327-web-fast-2
kayg:archive/old/issue/327-web-fast
kayg:archive/old/issue/425-stt-bench-vq1
kayg:archive/old/issue/445-no-bleed
kayg:archive/old/issue/400-swipe-mockup-2
kayg:issue/426-client-review
kayg:issue/426-client-2
kayg:issue/426-client
kayg:archive/old/issue/476-safe-area-lab
kayg:archive/445-top-light-2
kayg:archive/old/issue/445-top-light
kayg:issue/471-blocks-mockup
kayg:archive/old/issue/448-links-app-2
kayg:archive/old/issue/448-links-app
kayg:archive/old/issue/398-cold-links
kayg:issue/434-442-small-2
kayg:issue/434-442-small
kayg:archive/old/issue/398-unload
kayg:archive/old/issue/445-bottom-band
kayg:issue/445-bottom-band
kayg:issue/351-rem-3
kayg:archive/312-views-mockup
kayg:issue/351-rem-2
kayg:issue/351-rem
kayg:archive/old/issue/327-first-note
kayg:issue/395-width-phone
kayg:archive/old/issue/327-typing
kayg:issue/396-ios-edges
kayg:issue/397-ios-swipe
kayg:archive/398-allocator
kayg:archive/old/issue/327-notes-index
kayg:issue/345-347-contrast-empty-2
kayg:archive/old/issue/44-arenas
kayg:issue/44-arenas
kayg:archive/integ325
kayg:archive/old/issue/327-perf-harness
kayg:archive/old/issue/44-thp
kayg:issue/44-thp
kayg:archive/old/issue/285-sticky-pills
kayg:archive/old/issue/44-trim-3
kayg:issue/44-trim-3
kayg:archive/old/issue/165-cards
kayg:archive/old/issue/165-picker-2
kayg:archive/old/issue/212-multi-select
No reviewers
Labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
kayg/calternal!783
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/calendar-event-parser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Failure → effect → detection → recovery → test: unsafe input → explicit refusal with no note writes → boundary validation → edit the note or enable the completed UI contract later → awkward YAML / hidden syntax / stored replay / cross-folder transfer regressions. Gates: fmt, four-crate clippy with -D warnings, events/notes/tasks/calternal tests on dev-01.
Plan (ADR 0067 build order, step 3)
Add the pure event parser and the describe rows for events: a new small crate
crates/events(calternal-events). Nothing here writes files, allocates identity, or touches DAV. Step 4 (identity and promotion) builds on its marker module.What it is
clock: the log clock grammar (superset ofcrates/daily/src/log.rs: it also reads real end seconds and fractions). Pure.line: one clock-starting line (with or without a list marker) ->Head(clock range, start-only,all day), checkbox mark, title, tags, trailing block marker. Checkbox wins over clock (the row istask, notevent).marker: the one parser for trailing^idmarkers (16 lowercase Crockford = event id; legacy 6-char kept as-is). Step 4 adds writing next to it.scan: Markdown walk: skips frontmatter, code (fenced + indented), HTML blocks/comments, blockquotes; supplies the day (daily note stem orday:; else nearest whole ISO-date ATX heading); finds direct child sub-bullets (standalone link, checkbox).note: note classification from frontmatter (event owner / series / per-day override), so an event note withstatusis not a todo task.calternal-taskscalls it.describer:EventsDescriber(notes::describer::Describer), registered byEventsPlugin(no actions yet). Rows go innotes/meta.dbin the note's own transaction, like tasks.Rows (derived; version-bumped rebuild)
event_lines(note,line,kind,day,all_day,start_s,start_frac,end_s,end_frac,end_next,has_end,point,title,tags,area,block,event_id,children),event_children(note,parent,line,kind,target,mark),event_notes(note, event_id, start, end, all_day, zone, calendar, status, series, occurrence, repeat),journal_events(note,event_id, title, start, end, all_day, zone, calendar, status)(theeventsmap read with the step-2props::keys_at/get_at). Civil data only (day + clock seconds); instants/zones are a reader concern (frozentime-zoneis stored, not interpreted).Sizes and big-O
events/event-id/serieskey returns the shared empty answer (like tasks'nothing()), so ordinary notes cost O(N) scan only.note); cold fill drops indexes and rebuilds like tasks.describe_budgetasserts it on realistic notes (ordinary prose, a 30-event daily note) in--release; debug runs use a 10x bound.Failure table
0845,25:00,9am+letters,13:00pm)shared_log_vectors,differential_vs_dailyskips_code_frontmatter_html_quotesboxed-> kindtaskkind='task'row onlyclassificationstatus:found::taskaskscalternal_events::note::is_eventevent_note_is_not_a_taskneeds_a_datepropsrefuses; owner row hasbroken-less empty fieldsbroken_frontmatter_reads_nothing_unsafeduplicate_markers_are_keptnever_panicsNotesdescribe step onlyrows_commit_with_the_note(real Notes home)describe_budgetGate tests
Old shared log vectors (
contracts/log-entries.json, everyentrieslist, run through this parser and compared tocalternal_daily::log::entries), new vectors (contracts/event-lines.json: sub-bullet, all-day, seconds/fractions, tags, markers, start-only, equal/reversed ends), event/task classification, no second scan (realNoteshome, rows read back), describe budget.Decisions (no questions asked)
daily: the clock grammar is a superset (end seconds, fractions) anddaily/the editor share the vectors byte for byte; a differential test pins them together on random lines.- 08;45 - tomorrow Walkstays start-only with the old text, per the old vector). Multi-day events carry bounds in their owner (start/end).event_childrenfor it.Results (calternal-dev-01-compute02, inside the
infra/nix-devshellflake; flake files not committed)cargo clippy -p calternal-events -p calternal-notes -p calternal-tasks -p calternal --all-targets -j4 -- -D warnings: clean;cargo fmtapplied.cargo test -p calternal-events -j4: 13 passed. Gates:old_shared_log_vectors(every case ofcontracts/log-entries.jsonon the legacy list-line subset, task boxes included),differential_vs_daily(5,000 random clock-shaped line sets, same accepted lines and fields ascalternal_daily::log::entries),event_vectors(16 new cases incontracts/event-lines.json: sub-bullets, all-day, seconds and fractions, tags, markers, headings, lenient clocks; expectations generated once and reviewed by hand),checkbox_lines_are_tasks_and_plain_clocks_are_eventsand thenote::kindtests (classification),rows_commit_with_the_note(realNoteshome: rows appear with the note, change with an outside edit, vanish on delete, and a rebuild after clearing the describer version gives the same rows; no other scanner exists),never_panics.cargo test --release -p calternal-events describe_budget -j4 -- --nocapture: prose note (6.5 KB) p95 0.098 ms; busy daily note (30 event lines with children) p95 0.092 ms; both under the 0.2 ms gate. (Debug builds only check a 5 ms bound.) A fresh quiet perf-VM measurement is recorded below; this older figure is from a shared VM.cargo test --no-fail-fast -p calternal-notes -p calternal-tasks -p calternal: notes 435, tasks 29 (newan_event_note_with_a_status_is_not_a_task_but_its_child_tasks_are), calternal all green.contracts/actions.jsonis unchanged (the plugin has no actions yet).Also added to the notes crate:
props::pairs_at(read the pairs of a nested map), used bynote::journal_events.Resume changes and verification (2026-10-31)
Bare
10:00 - 11:00 Going for a stroll #area/dailylivinglines are events too. Added parsing, direct-child relationships, hand-checked vectors andbare_clock_lines_are_separate_events; code/fences and time-shaped prose stay excluded. Describer version is 2 so existing indexes rebuild. The old daily grammar still requires list markers: its unchanged shared vectors and 5,000-case differential test run against that subset; bare clocks are explicitly covered by the new test and event vectors.Fresh dev-01 checks, Nix shell; heavy commands wrapped in
~/bin/slot:cargo fmt --all -- --check: passed.cargo clippy -p calternal-events -p calternal-notes -p calternal-tasks -p calternal --all-targets -j4 -- -D warnings: passed.cargo test -p calternal-events -j4: 14 passed, including old/new vectors, classification, same-transaction index/rebuild, fuzz and describe budget.cargo test --release -p calternal-events describe_budget -j4 -- --nocapture: passed; prose p95 0.1277 ms, busy day p95 0.1052 ms (limit 0.2 ms).cargo test -p calternal-events -p calternal-notes -p calternal-tasks -p calternal --no-fail-fast -j4passed: notes 435 / 6 ignored, tasks 29, calternal all green. Those crates are also checked on the final step-4 stack.Raw logs:
calternal-dev-01-compute02:~/cal-resume-s3.log,~/cal-resume-s3-verified.log. No PRs merged.Quiet describe measurement
Release test executables built on dev-01 were relayed through the control host to perf-01, SHA256 checked at both ends, then run as three alternating pairs under
~/bin/perf-lock. Head (1b6e5659, SHA2564091973618e68fb46417a158d4b878b88d022dd00242c4b727c340d843e21b41) median of per-run p95: prose 0.0555 ms, busy daily 0.0461 ms, both below 0.2 ms. Comparator was the existing step-4 executable at8e95a8b0(unchanged pre-fix parser from735106a0, SHA256899f9ce8b4000340500ef4cb745bce302ff97b97d7352516d7681df0458cad10); median p95 0.0573 / 0.0453 ms. This is a parser/describe microbenchmark, not the 100k cold-index or DAV delivery gate.Exact measurement:
~/bin/perf-lock bash -c 'set -e; for n in 1 2 3; do ~/cal-resume-parser-baseline-identity describe_budget --nocapture; ~/cal-resume-parser-head describe_budget --nocapture; done'. Raw output:calternal-perf-01-backup01:~/cal-resume-describe.log.Independent review, round 1
Verdict: fix first. Reviewed
1b6e56594f21e696744fc0d508637036857d46d8relative to #781, with ADRs 0067/0068/0056/0066. Findings are source-level traces; full suites were not rerun by this reviewer. Inherited #781 preservation blockers also remain.P1 — Indented code becomes events.
crates/events/src/scan.rs:85and:98. A daily note containing\t10:00 code\nproduces an event because indentation counts bytes (one tab), not Markdown columns. Also- parent\n\n 10:00 code\nretainsin_list=trueand treats the list's indented code as an event. Fix: track actual Markdown containers and code indentation, including tab expansion and code inside list items. Add both vectors; downstream identity/promotion must never write markers into these code blocks.P1 — Frontmatter with CRLF/BOM is scanned as body.
crates/events/src/scan.rs:50(frontmatter::lenonly recognizes---\n). For a daily file with---\r\ndescription: |\r\n 10:00 YAML text\r\n---\r\n, the description is emitted as an event. Fix: recognize supported frontmatter envelopes consistently or suppress unsafe parsing when an unsupported/unclosed envelope is detected. Add CRLF/BOM block-scalar clocks and malformed envelopes to vectors.P1 — Relationship scan reads checkboxes/links inside HTML comments.
crates/events/src/scan.rs:225(children). For- 09:00 Event\n <!--\n - [ ] fake\n -->\n, the child scan emits a task relationship. It has its own fence state but no HTML/comment state, unlike the main walk. This can also make promotion treat a commented task-note link as an existing owner. Fix: derive relationships from the same parsed container/visibility state; test commented and raw-HTML children as well as code. Do not scan their text as relationships.P2 — Non-ASCII tags are truncated into different tags.
crates/events/src/line.rs:165(ASCII-only tag byte loop on this head).- 09:00 Walk #caféindexescaf;#area/工作loses its calendar tag. The editor recognizes Unicode letters/numbers. Fix: share the tag grammar or use Unicode-aware character iteration and add non-ASCII vectors, including promotion metadata.P2 — Child lookup is not linear as claimed.
crates/events/src/scan.rs:106callschildrenon each event's remaining subtree. With nested event lines, each ancestor traverses descendants again;MAX_CHILDRENlimits returned direct children, not traversal. Fix: collect parent/direct-child relationships in one container walk, or explicitly bound supported nesting and account for skipped spans. Add a nested-note scaling case alongside the flat 30-event budget fixture.Failure-table audit:
skips_code_frontmatter_html_quotesexists on this head.checkbox, despite 0068 O01 saying unsupported.no_day_no_eventcovers missing context and owner-body policy; whole-date headings have vectors.eventshas a test. The citedbroken_frontmatter_reads_nothing_unsafetest does not exist.pairs_atdoes not validate the whole YAML block or reject duplicate returned child keys; add nested duplicates and malformed-owner fixtures before asserting “valid keys only.”never_panicsexercises scan/read with random text; it does not prove semantic exclusions.rows_commit_with_the_noteexercises outside edit/delete/rebuild; it does not itself assert transaction ordering at journal publication or room-edit behavior. No independent watcher was introduced.describe_budgetchecks two small fixtures; debug allows 5 ms. PR reports quiet release p95 below 0.2 ms, but those numbers were not independently remeasured here. Nested complexity and 100k cold-index growth remain unproven.Times/all-day/seconds/equal ends/next-day rollover have vectors; full multi-day bounds are retained in owner fields. I found no specified explicit end-day line grammar to require inventing here. Quoted event prose remains excluded; quoted checkbox support and unknown-box refusal still need reconciliation with O01.
Mergeability: fresh dev-01
git merge-tree --write-tree origin/dev 1b6e5659exits 0 againstdev=2f304154054ec68b7855bb1f2bd24b1fb15a386d(tree53dcef917614148b2159e42717375afb01f668cd). Forgejo still says false. #781 ancestry explains the cumulative diff, not a content conflict; exact server cause remains unproven. No code pushed or merged.Independent reproduction addendum: the dev-01 standalone Rust probe (
/tmp/cal-independent-r1/repro.rs, binary/tmp/cal-independent-r1/repro), using parser modules copied directly from the reviewed stack and built inside Nix through~/bin/slot, emitted an event for tab-indented code, an event for six-space code inside a list, an event for the CRLF YAML block-scalar clock, and a boxed child for the checkbox inside an HTML comment. All four bad outputs were observed. The focused probe links cached Notes dependencies; it is not a full gate or performance run.Round 1 implementation fixes
Head
3f94719e, rebased onto #781f92341a6. No merge.review_code_and_unsafe_yaml_are_not_events.review_relationships_share_visibilityincludes comments, raw HTML and list code.caféandarea/工作;review_unicode_tags_are_whole.Red evidence: all three new regression tests failed before changes in
~/cal-r1-s3-red.log. The first focused run also exposed an existing vector treating a bare clock lazily continuing a blockquote as an event. Under Markdown container rules it is quoted prose; the vector now explicitly excludes it. Ordinary bare clocks remain supported.Fresh dev-01 Nix gates, heavy commands through
~/bin/slot, log~/cal-r1-s3-gates.log:cargo fmt --all && cargo fmt --all -- --checkcargo clippy -p calternal-events -p calternal-notes -p calternal-tasks -p calternal --all-targets -j4 -- -D warningscargo test -p calternal-events -p calternal-notes -p calternal-tasks -p calternal --no-fail-fast -j4All passed: events 17, notes 438 / 6 ignored, tasks 29, plus calternal unit/integration gates. Existing ignored tests remain ignored. No new quiet perf measurement or 100k cold-index claim. Lookup adds one Markdown parse and sorted exclusion ranges; nested child traversal retains the documented worst-case quadratic limitation. No further independent review round is claimed.
Other review-audit gaps retained for follow-up: quoted-checkbox container support, unknown-box refusal, fuller malformed/nested-owner fixtures, independent journal publication ordering assertion, and large cold-index/perf validation. These do not waive the P0/P1 fixes above.
Independent review, round 2
Verdict: fix first. Reviewed
3f94719e35a3ddabd39ec794de1f24dde77b49cfrelative to #781, both round-1 comments, and ADRs 0067/0068/0056/0066. No prior round-2 comment existed when checked. No code pushed or merged. #781's remaining byte-preservation blocker is inherited.review_code_and_unsafe_yaml_are_not_eventsincludes both exact code reproductions; Markdown code-block ranges now exclude them.review_relationships_share_visibilityproves standalone comment, div and list-code cases. It omits multiline inline comments; see below.review_unicode_tags_are_wholechecks exactcaféandarea/工作output; code advances by UTF-8 character lengths. This is not full parity with every editor tag form.New P1 — Multiline inline HTML comments still expose hidden relationships.
crates/events/src/scan.rs:298(theEvent::Htmlexclusion match) and:254(child exclusion lookup). With:scan(..., Day::Fixed("2026-10-26"))returns a child checkbox forfake. The same happens whentext <!--is on an indented continuation line before the hidden checkbox. Pulldown emits inline HTML for these comments, but the added exclusions handleEvent::Htmland HTML blocks, notEvent::InlineHtml; the old line state only notices comments starting a line. This emits a derived task relationship for text the person cannot see; in #785 the plain-checkbox identity scanner uses the same exclusions, so hidden checkboxes can also become identity targets when writes are enabled. Fix: include multiline inline-comment spans in the shared visibility model, filtering by the candidate token's actual span so visible text before/after inline HTML remains usable. Add both vectors, hidden clock/checkbox/link variants, and a real promotion test proving a commented owner link is ignored. This is a surviving class of the round-1 problem, not a newly introduced syntax category.Verification: dev-01 Nix shell, via
~/bin/slot,cargo test -p calternal-events review_ -j4at stack head771eb102passed 17 tests (including the three parser regressions). A standalone Rust probe linked the current stack libraries and observed both inline-comment false relationships; the standalone-comment control had no child. The relevant exclusion/children helpers are unchanged from this PR. Probe/output:/tmp/cal-r2-probe.rs,/tmp/cal-r2-probe.out. No fresh release performance, full-suite or 100k cold-index result is claimed.Other round-1 audit limitations remain: quoted-checkbox support, unknown-box refusal, malformed/nested-owner semantics, independent journal-publication ordering, and large cold-index validation. Changing the old lazy-blockquote vector agrees with Markdown container rules; it does not prove these other cases.
round 2 fixes for final review
Head
510610d6, based on #78194807faa. Simplification: mask invisible Markdown spans before scanning event, checkbox or relationship candidates, retaining byte and line offsets. Raw HTML-comment delimiters cover comments split by Markdown list boundaries; code spans/blocks keep comment delimiters literal. No merge.review_round2_comments_code_yaml_are_invisiblecovers single/multiline HTML comments, top-level/nested fences and YAML.review_round2_inline_comments_never_create_taskschecks the actual tasks describe pass.Passed on dev-01 in Nix, log
~/cal-r2-s3-final3.log:Events: 18 passed; notes: 439 passed / 6 existing ignored; tasks: 30 passed; calternal unit/integration suites passed with existing ignored tests. No build/test ran on the control host; Nix scaffolding was not committed.
Visibility uses O(n + r log r) work for bytes/ranges. The inherited repeated nested child traversal is unchanged; no new large-note or cold-index performance claim is made. Malformed frontmatter suppresses scanning conservatively; the old visibility fixture now quotes its YAML string correctly. Existing round-1 audit/performance limits remain. Final review round 3 is pending; no review approval is claimed.
Independent review, round 3 (final)
Verdict: stop and simplify. Reviewed
510610d6c84675741c1ea66344b829c273f56c4a, round-2 review #70966, fix status #71021, simplification notes and ADRs 0067/0068. No code pushed or merged. A new P1 remains in this final round; #781's new P0 also blocks this stack layer.New P1: multiline inline code still produces calendar events.
crates/events/src/scan.rs:299,:302. For a daily note whose exact bytes are"\n10:00 hidden\n\n"(one backtick on the first and third lines), CommonMark treats the clock as inline code.visible_textreturns those bytes unchanged andscan(text, Day::Fixed("2026-10-26"))emits a 10:00 event on line 1. The list-opening variant"-\n10:00 hidden\n\n"also emits it. The implementation recordsEvent::Codeonly incode, used to ignore literal HTML-comment delimiters, but omits it from the actual exclusionranges. Fenced/indented-code tests cannot catch this. This feeds false derived events through the production parser; marker generation remains release-gated in #785, so no enabled marker-writing claim is made.Concrete simpler design / fix: construct one immutable exclusion view from original Markdown offsets, including inline code as well as code blocks, HTML/comments and YAML. For an initial conservative contract, skip any candidate/relationship line intersecting an excluded span; leave partially mixed lines to source editing rather than reparsing space-masked Markdown through a second parser and another fence state. Use that same candidate test for events, tasks and identity. Add complete multiline code-span fixtures with one/multiple backticks, clock-only and nested child variants, and check both derived rows and refusal of identity targets. Retain writes disabled until the common visibility contract is proven. This deliberately narrows mixed-line support instead of starting a fourth syntax-patch review round.
Fresh verification on dev-01, Nix shell, stack head
eb7ffd2d(the implicated exclusion implementation is unchanged from this PR), heavy commands via~/bin/slot:cargo test -p calternal-events -p calternal-notes -p calternal-tasks review_ -j4: events 21, notes 25, tasks 7 passed, including all existing round-2 visibility regressions.~/bin/slot rustc --edition=2024 /tmp/cal-r3-probe.rs -L dependency=target/debug/deps --extern calternal_events="$events_lib" -o /tmp/cal-r3-probe, then executed. Observed unchanged visibility bytes and a false event for both multiline inline-code examples.$events_libwas the newest built events rlib. VM source/output:/tmp/cal-r3-probe.rs,/tmp/cal-r3-probe.out; test log/tmp/cal-r3-review-tests.log.No fresh full-suite, clippy, release-perf, 100k index or browser result is claimed. Inherited round-1 audit limits remain; no additional new P2/P3 finding.
On hold under the three-round stop-and-simplify rule. The replacement plan is PR #802: #802
Plan: https://git.kayg.org/kayg/calternal/src/branch/docs/calendar-backend-v2-plan/docs/plans/0067-calendar-backend-v2.md
No further patches or fourth review round on this stack. The plan chooses a strict whole-frontmatter write allowlist, the editor's Lezer parser with an explicit backend bridge feasibility gate, and centralized marker writes disabled until full UI hiding. It lists salvage, independent tests and smaller replacement PRs. This comment changes no implementation code and requests no merge.
kayg referenced this pull request2026-11-05 23:21:11 +00:00
housekeeping #1009: needs-decision.
Calendar v1 parser/describe slice was held with #781/#785; #802 and pure converter #803 are the simpler replacement direction. Retain any uncovered parser vectors.
original head:
510610d6c84675741c1ea66344b829c273f56c4a. against devcd7f84432febfc63b788fbb9b9f9950452982d74, git cherry reports 23 unmatched and 0 equivalent patches. the landing audit lists each candidate missing commit and stable patch match inpr-783.md; unmatched patches can include superseded behavior.left open, source branch unchanged. no rebase or new test claim for this decision lane.
Superseded by calendar backend v2 (#802/#803). The branch and original tips are archived under
archive/(see #1009), so nothing is lost; useful regression vectors are noted there for the active lanes. Closing.Pull request closed