Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
20 KiB
status, system, created, owners
| status | system | created | owners | |
|---|---|---|---|---|
| draft | tasks | 2026-09-01 |
|
Task plan append-mode write Requirements
Overview
update_task_plan_kandev replaces the whole plan document. There is no partial write at
any layer, so a caller adding a section must read the whole plan and send it back with
the addition attached. One write therefore costs the size of the entire plan, and a run
costs the square of the number of writes in it.
The plan is also a task's only durable memory across a context reset, so it grows monotonically for as long as the task runs. On this instance the largest stored revision is 158,393 characters, so the two effects compound in production, not in theory.
This capability adds a second write mode in which the caller submits only the fragment it wants to add and the system composes the stored document. It changes what a caller must send and what the system must guarantee about composing it, not what a plan is, how revisions are numbered, or how the browser edits one.
The tasks system owns this capability because the durable artifact is the plan and its
revision history, not the MCP surface exposing the write. The missing-task boundary
stays owned by REQ-TASKS-DOCUMENTS-001.
Write serialization and truncation reporting belong to plan-write-consistency; the
stored-content size limit to plan-content-size-limit, both in this canon. This
capability composes inside the per-task write lock the first established, and
REQ-TASKS-PLAN-APPEND-007 measures an append against the second.
REQ-TASKS-PLAN-APPEND-003 still states in full what append requires of serialization,
so this contract stays readable and testable on its own.
Prior art
Recorded in full, with both search receipts, in the system design under Prior art.
Terminology
- Plan write: an operation that upserts the task plan HEAD row and writes or merges a revision.
- HEAD: the single
task_plansrow for a task, holding the current content. - Mode: the requested composition behavior of an agent plan update, either
replaceorappend. - Fragment: the
contenta caller submits inappendmode; an addition to the stored document, not the whole of it. - Composed content: the content a plan write commits in
appendmode, formed from the stored content and the fragment. - Stored content: the plan content in effect for that task at the instant the composing write reads it inside the serialized write path.
- Agent write path: the MCP tools
create_task_plan_kandevandupdate_task_plan_kandev. - Browser write path: the WebSocket actions handled by
wsCreateTaskPlanandwsUpdateTaskPlan. - Truncation guard: the existing check reporting a write that retains less than half the characters of the content it replaces.
- Whitespace: a character whose Unicode
White_Spaceproperty is true. This set is normative wherever this document says "whitespace"; it includes U+0085 NEL and U+00A0 no-break space, so a hand-rolled" \t\r\n"test does not satisfy this contract. - Whitespace-only line: a line whose characters are all whitespace, excluding the line terminator.
- Size limit: the maximum stored plan content a single write may commit, owned by
plan-content-size-limitand unchanged here.
Requirements
REQ-TASKS-PLAN-APPEND-001: A caller selects the write mode explicitly and an
unrecognized mode changes nothing
Intent: The default must stay what every existing caller relies on, and an
unrecognized value must not be interpreted: treating it as replace would let one typo
overwrite a plan with a fragment, the destructive outcome this capability exists to
remove.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-001.1: When an agent plan update omits the mode or supplies
an empty mode, the system shall treat the write as
replace. - AC-TASKS-PLAN-APPEND-001.2: When an agent plan update supplies the mode
replaceorappend, the system shall perform that mode. - AC-TASKS-PLAN-APPEND-001.3: When an agent plan update supplies any other mode
value, including a value differing only in letter case such as
AppendorAPPEND, the system shall reject the request as a validation error, name the two accepted values in the error, leave the stored plan content, title and revision history unchanged, and create no revision. - AC-TASKS-PLAN-APPEND-001.4: When an agent plan update supplies no content, or supplies content that is empty, the system shall reject the request as a validation error in either mode and create no revision.
- AC-TASKS-PLAN-APPEND-001.5: When an agent plan update in
appendmode supplies a fragment consisting only of whitespace as this document defines it, the system shall reject the request as a validation error and create no revision, because such a fragment can only add separator noise to a document from which it cannot be removed. - AC-TASKS-PLAN-APPEND-001.6: When an agent plan update in
appendmode targets a task that has no plan, the system shall reject the request with the same plan-not-found outcome thatreplaceproduces for that task, and shall not create a plan. - AC-TASKS-PLAN-APPEND-001.7: When one request violates more than one criterion, the
system shall report exactly one failure, selected in this order: mode validity
(AC-TASKS-PLAN-APPEND-001.3); task-reach authorization (AC-TASKS-PLAN-APPEND-005.6);
content validity (AC-TASKS-PLAN-APPEND-001.4, AC-TASKS-PLAN-APPEND-001.5); plan
existence (AC-TASKS-PLAN-APPEND-001.6); failure to read the stored content
(AC-TASKS-PLAN-APPEND-003.5); the size limit (AC-TASKS-PLAN-APPEND-007.2). In every
case the stored plan content, title and revision history are unchanged and no revision
is created. Missing-task is not in this order; it stays owned by
REQ-TASKS-DOCUMENTS-001.
REQ-TASKS-PLAN-APPEND-002: An append composes the stored document with a separator
that cannot join two lines
Intent: Downstream consumers count headings. A fragment beginning with a heading
appended onto the last line of the stored content yields a line that is no longer a
heading, so any consumer counting ## headings silently reads one fewer. Stated over
headings generally, not one consumer's heading text, so the rule outlives any counter
built on it. The separator is contract, not implementation.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-002.1: When a plan write in
appendmode commits, the composed content shall consist of the stored content, then a separator, then the fragment, in that order. The only characters the system may add are the separator itself; the only ones it may remove are the edge whitespace that AC-TASKS-PLAN-APPEND-002.2, AC-TASKS-PLAN-APPEND-002.3 and AC-TASKS-PLAN-APPEND-002.5 each require it to remove. Beyond those it shall perform no insertion, reordering or removal, and shall not examine or alter any interior character of either body. This criterion frames its siblings rather than contradicting them. - AC-TASKS-PLAN-APPEND-002.2: When both the stored content and the fragment contain a non-whitespace character, the composed content shall contain exactly one empty line between the last non-empty line of the stored content and the first non-empty line of the fragment, regardless of how many line endings the stored content ends with or the fragment begins with. Leading spaces and tabs on the fragment's first non-empty line shall be preserved.
- AC-TASKS-PLAN-APPEND-002.3: When the stored content is empty or contains only whitespace, the composed content shall be the fragment with its leading empty and whitespace-only lines removed, shall preserve leading spaces and tabs on the fragment's first non-empty line, and shall not begin with a blank line.
- AC-TASKS-PLAN-APPEND-002.4: When a plan write in
appendmode commits, the composed content shall preserve the fragment's trailing characters as submitted, and the system shall neither add nor remove a trailing line ending. - AC-TASKS-PLAN-APPEND-002.5: When a plan write in
appendmode commits, the composed content shall preserve every character of the stored content that precedes its trailing whitespace. Trailing whitespace on the stored content's final line may be dropped. - AC-TASKS-PLAN-APPEND-002.6: When a plan write in
appendmode supplies a title, the system shall apply it exactly asreplacedoes; when it supplies none, the system shall leave the stored title unchanged.
REQ-TASKS-PLAN-APPEND-003: An append reads and commits against the same state, and
never commits a fragment alone
Intent: An append is a read-modify-write. If the read runs outside the serialization that orders plan writes, two concurrent appends read the same stored content and the second commit overwrites the first, losing a section while both callers are told the write succeeded. The replace-only API prevented that by construction; it must not return one layer down, invisible.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-003.1: When a plan write in
appendmode commits, the stored content it composed from shall be the plan content in effect for that task at the instant that same write commits, not content read before another write to the same task committed. - AC-TASKS-PLAN-APPEND-003.2: When two plan writes in
appendmode for the same task run concurrently and both report success, the resulting plan content shall contain both fragments in full. - AC-TASKS-PLAN-APPEND-003.3: When plan writes for the same task run concurrently, the resulting plan content shall equal the result of performing those writes one after another in some order. The system shall not guarantee which order, and shall not guarantee that the order matches the order in which the callers submitted them.
- AC-TASKS-PLAN-APPEND-003.4: When a plan write in
appendmode runs concurrently with one inreplacemode for the same task, the system shall apply AC-TASKS-PLAN-APPEND-003.3 to that pair. A replace committing between an append's read and that append's commit would otherwise be discarded entirely, leaving content matching no serial order. Serializing appends against each other alone does not satisfy this criterion. - AC-TASKS-PLAN-APPEND-003.5: When the stored content for an
appendcannot be read, the system shall fail the write, create no revision, leave the stored plan unchanged rather than committing the fragment as the whole document, and report the failure distinguishably from AC-TASKS-PLAN-APPEND-001.6's plan-not-found outcome, exposing no storage detail. - AC-TASKS-PLAN-APPEND-003.6: When the same
appendrequest is submitted more than once, the system shall append the fragment once per accepted request. An append is not idempotent and repeated fragments shall not be deduplicated.
REQ-TASKS-PLAN-APPEND-004: The truncation guard does not judge an append
Intent: The guard catches a replace that dropped content. An append cannot drop content, since the composition contains the stored content in full, so running the guard there yields only a false warning and a needless revision split, teaching an agent to distrust an otherwise reliable warning.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-004.1: When a plan write in
appendmode commits, the system shall emit no truncation warning, whatever the ratio between the fragment's length and the stored content's length. - AC-TASKS-PLAN-APPEND-004.2: When a plan write in
appendmode commits, the system shall not force a new revision on the truncation guard's account, and shall leave the write eligible for the existing coalescing rules. - AC-TASKS-PLAN-APPEND-004.3: When a plan write in
appendmode commits, the response shall carry no truncation warning field and no prior revision number field, matching a non-truncating write's shape today.
REQ-TASKS-PLAN-APPEND-005: Replace-mode behavior and every other plan surface are
unchanged
Intent: This capability adds a mode. A regression in the default would cost more than the change saves, and surfaces never asked to change must not drift.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-005.1: When a plan write runs in
replacemode, the stored content, stored title, revision numbering, revision coalescing, truncation detection, forced-revision behavior, emitted events and response shape shall be identical to those produced before this capability existed. The wording of the truncation warning is excluded from this freeze and owned by REQ-TASKS-PLAN-APPEND-006; its trigger condition, the counts it reports and the response field carrying it are frozen here. - AC-TASKS-PLAN-APPEND-005.2: When a caller supplies a non-empty mode to
create_task_plan_kandev, the system shall reject the request as a validation error namingupdate_task_plan_kandevas the tool that offersappend, store nothing, and leave stored content, title and revision history unchanged. It shall not ignore the value, which would commit the fragment as the entire plan. An absent or empty mode is treated as absent, leaving that tool's behavior unchanged, consistent with AC-TASKS-PLAN-APPEND-001.1. - AC-TASKS-PLAN-APPEND-005.3: The browser write path shall have no mode field in its
payload contract and shall ignore an unrecognized field rather than reject it —
that path's existing behavior for any unknown field, and therefore what "unchanged"
means for it. It never sends a mode, so it takes the
replacedefault. The asymmetry with AC-TASKS-PLAN-APPEND-005.2 is deliberate. - AC-TASKS-PLAN-APPEND-005.4: When a plan write in
appendmode commits, the system shall emit the same events, in the same order, that areplacewrite committing the same resulting content emits. - AC-TASKS-PLAN-APPEND-005.5: When a plan write in
appendmode commits, it shall create or coalesce exactly one revision as areplacewrite does, and the stored revision content shall be the composed content, not the fragment. - AC-TASKS-PLAN-APPEND-005.6: When a plan write in
appendmode runs, the system shall apply the same task-reach authorizationreplaceapplies, and shall not read the stored content of a task the caller cannot reach.
REQ-TASKS-PLAN-APPEND-006: Every agent-facing text describing plan writes admits
that append exists
Intent: A caller decides between the two modes from the text the system shows it.
Several texts today assert there is no append mode, spread across both plan tools'
descriptions and content parameters and the truncation warning shown after a write
destroyed content. Left alone they argue against the mode; the warning does so at the
worst moment, steering a caller who just lost content away from the remedy, and the
create tool while prescribing the read-then-resend pattern this capability removes.
Softened too far, they drop the warning that keeps the replace path safe. Enumerating
these texts has twice missed one, so AC-TASKS-PLAN-APPEND-006.9 binds the class instead
of a list.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-006.1: The
update_task_plan_kandevdescription shall name both modes, state which is the default, and state thatreplacesubmits the whole document whileappendsubmits only an addition. - AC-TASKS-PLAN-APPEND-006.2: The
update_task_plan_kandevdescription shall retain, scoped toreplace, the warning that the write overwrites the entire document and that sending only a section deletes the rest. - AC-TASKS-PLAN-APPEND-006.3: The
update_task_plan_kandevdescription shall state thatappendplaces a blank line between the stored content and the fragment. - AC-TASKS-PLAN-APPEND-006.4: The
update_task_plan_kandevdescription shall state that an append is not idempotent and that resubmitting it adds the fragment again. - AC-TASKS-PLAN-APPEND-006.5: The
update_task_plan_kandevdescription shall state thatappenddoes not require the caller to read the plan first. - AC-TASKS-PLAN-APPEND-006.6: When a plan write in
appendmode succeeds, the acknowledgement returned to the caller shall report the size of the stored document after the write rather than the size of the submitted fragment. - AC-TASKS-PLAN-APPEND-006.7: The truncation warning shall not state or imply that no partial update or append mode exists.
- AC-TASKS-PLAN-APPEND-006.8: The truncation warning shall name
appendas the way to add a section without resubmitting the whole document, while continuing to state where the pre-write content lives, that the MCP plan tools cannot fetch it, and that the caller must not rewrite the plan from memory. - AC-TASKS-PLAN-APPEND-006.9: No agent-facing text describing a plan write shall
state or imply that no partial update or append mode exists, or direct a caller who
wants to add a section to read the plan and resubmit it. This binds every tool and
parameter description on the agent write path, not only those above. On
create_task_plan_kandeveach shall still state that this tool replaces the whole plan and nameupdate_task_plan_kandevinappendmode as the way to add a section, and its schema MAY declare amodeparameter that only rejects, keeping AC-TASKS-PLAN-APPEND-005.2's message reaching the caller.
REQ-TASKS-PLAN-APPEND-007: An append is measured against the document it will store
Intent: The size limit measures what the caller submitted. In append the caller
submits a fragment but the system stores the composition, so measuring the submission
would let a small fragment commit an oversized document, defeating an existing limit.
Acceptance criteria
- AC-TASKS-PLAN-APPEND-007.1: When a plan write in
appendmode is admitted, the system shall evaluate the size limit against the composed content, not against the submitted fragment. - AC-TASKS-PLAN-APPEND-007.2: When the composed content would exceed the size limit, the system shall reject the write, store nothing, create no revision, and leave the stored plan content and title unchanged. Composed content whose size is exactly the limit shall be accepted, matching the existing check's boundary.
- AC-TASKS-PLAN-APPEND-007.3: When the system rejects an append for exceeding the size limit, the size it reports shall be that of the composed content, so a caller is not told a fragment far below the limit exceeded it.
- AC-TASKS-PLAN-APPEND-007.4: When the system evaluates the size limit for an
append, it shall do so against the same stored content that write composed from, inside the region that serializes plan writes for the task, so the value admitted is the value committed. - AC-TASKS-PLAN-APPEND-007.5: When a plan write runs in
replacemode, the size limit's value, the point at which it is evaluated and the error it produces shall be unchanged.
Out of scope
- The plan size limit itself. Its value and error are owned by
plan-content-size-limit. REQ-TASKS-PLAN-APPEND-007 fixes only which content an append is measured against; nothing here raises, lowers or removes the ceiling, nor bounds growth below it. - Revision compaction and server-side collapse. An append creates or coalesces a revision as any other write does; none is merged, pruned or rewritten.
- Automatic collapse of spent detail. Collapsing stays a deliberate
read-then-replace by the caller: per
concepts/agents-md-pattern.md, automating the full rewrite is what erodes detail, so only accumulation becomes cheap. - A section-patch or replace-a-named-heading mode. Only whole-document replace and end-of-document append are defined.
- An idempotency key for appends. AC-TASKS-PLAN-APPEND-003.6 states the non-idempotence rather than removing it; deduplication needs a caller-supplied key and a store for it — a separate contract.
- A mode on
create_task_plan_kandevor on the browser write path. Fixed by AC-TASKS-PLAN-APPEND-005.2 and AC-TASKS-PLAN-APPEND-005.3. - Reading a past revision through MCP. Unchanged: no plan tool returns one.
- Prepend, or insertion at any position other than the end.