calternal_notes_core::tasks::build
build_task_file + append_inbox_line — canonical Task Note writers.
Responsibilities
Section titled “Responsibilities”-
build_task_file: produce a byte-canonical new Task Note from aBuildTaskFileInput. The output is immediately readable byextract_task_index(T6) without any round-trip loss: every value that would be mis-parsed by YAML is double-quoted via the sharedneeds_quoterule fromfrontmatter.rs. -
append_inbox_line: byte-stable append of- [ ] <title>\nto a legacy Checkbox file. Existing bytes are never rewritten.
Frontmatter field order (#27 T6, spec A §C.2 canonical — amends tasks spec §4.1)
Section titled “Frontmatter field order (#27 T6, spec A §C.2 canonical — amends tasks spec §4.1)”calternal-id, title, priority, scheduled, due, repeat, estimate, area, created
status: todo is always present. It marks the file as a Task independently
of its Home folder and is also its canonical initial status.
title and created are always present; every other field (INCLUDING the new
calternal-id/estimate) is emitted only when Some — see BuildTaskFileInput’s
doc comment for why calternal-id is optional despite the spec calling it
“required for file builds”. Date fields use CivilDate::to_ymd (→ YYYY-MM-DD,
date-only — the datetime-with-time format T7/T8 add is a LATER task, out of
this one’s scope); priority uses TaskPriority::as_word (→
“low”|“medium”|“high”|“urgent”). Neither is ever quoted — they never contain
YAML-special characters.
Quoting split: frontmatter vs. body vs. free-form prose
Section titled “Quoting split: frontmatter vs. body vs. free-form prose”String scalars in YAML frontmatter (calternal-id, title, repeat,
estimate, area) go through push_scalar, which calls
frontmatter::needs_quote and, when true, wraps the value in "..." with \
and " escaped — exactly mirroring emit_scalar in frontmatter.rs so the
same quoting rule is never duplicated.
The - [ ] <title> BODY line and the free-form body PROSE block (#27 T6)
are NOT YAML. Both are written verbatim, even when they contain a colon or
other YAML-special character — quoting them would corrupt the display text
(title) or mangle the user’s own prose (body).
Source: crates/calternal-notes-core/src/tasks/build.rs
Functions
Section titled “Functions”append_inbox_line
Section titled “append_inbox_line”pub fn append_inbox_line(text: &str, title: &str) -> StringAppend - [ ] <title>\n to a legacy Checkbox list such as
tasks/inbox.md; new task capture writes a Task Note instead (#430).
Byte-stable: existing bytes are NEVER modified. The return value is always
text + (optional "\n") + "- [ ] <title>\n".
Newline boundary rule: if text is non-empty and does NOT already end with
\n, one is inserted before the new line so the file stays well-formed.
This avoids corrupting the previous line by jamming the checkbox onto it.
Source: crates/calternal-notes-core/src/tasks/build.rs:208
build_task_file
Section titled “build_task_file”pub fn build_task_file(input: &BuildTaskFileInput) -> StringBuild a canonical new Task Note from input.
Output format:
---[calternal-id: <uuid>]title: <title>[priority: <word>][scheduled: YYYY-MM-DD][due: YYYY-MM-DD][repeat: <string>][estimate: <string>][area: <string>]status: todocreated: YYYY-MM-DD---
[<body prose, verbatim>]- [ ] <title verbatim>start is an Obsidian import field. The writer copies it to scheduled
only when scheduled is absent, and never emits a start: key (#430).
Fields in square brackets appear only when Some/non-empty. title and
created are always present. The canonical field order is fixed (#27 T6,
spec A §C.2, amending tasks spec §4.1) so extract_task_index always
finds fields in a predictable position.
body (T6): when Some and non-empty, emitted VERBATIM between the
closing fence and the root checkbox, followed by a blank separator — the
exact # <title>\n\n<body>\n shape build_standalone_note (T5) uses for
notes, applied here between frontmatter and checkboxes instead of after an
H1. None/empty adds zero bytes: the output is IDENTICAL to the
pre-T6 (no body) layout — frontmatter → one blank line → checkbox.
Round-trip guarantee: the Task projector reads the Note built from input
recovers every input field — title, priority, dates, recurrence, area,
created, PLUS (T6) calternal-id and body — from the resulting
TaskIndexEntry File row. estimate is written and preserved by every
subsequent byte-stable rewrite (set_task_frontmatter_field), but is not
yet a projected TaskIndexEntry field (no v1 consumer reads it back
through the projector — see BuildTaskFileInput::estimate’s doc comment).