ca-task · diff

git:20261004.4a578c5 to git:20261031.bbdac89

62 added, 88 removed. Audit A to A.

---
name: ca-task
- description: The sanctioned task-board mutator — add a queued task, start one (flips to in-progress and stamps the date, minting a dotted ID on pick-up), or mark an in-progress task done. The only blessed write to open-tasks.md.
- argument-hint: "add \"<desc>\" | start <id|\"title\"> | done <id|\"title\">"
+ description: Add, select, start, complete, or reopen local work through its owning store.
+ argument-hint: "add <description> | list | start <WORK-ID> | done <WORK-ID> | reopen <WORK-ID>"
---
- # /ca-task — task-board writer
+ # /ca-task — selected local work
- The one blessed way to mutate `<project-root>/.codearbiter/open-tasks.md`
- (resolves D-1). Hand-editing the board is no longer the only path; this command keeps
- every entry schema-conformant and every transition dated. The board LOGIC lives in the
- pure `_taskboardlib` transforms; this command runs the thin writer
- `taskwrite.py` from the selected installed package.
+ Use the installed `hooks/work.py` facade for ordinary work in both native and
+ legacy projects. It selects the current owner, gives new work a stable `WORK-ID`,
+ and performs one semantic action through that owner. Existing boards stay
+ legacy until an explicit adoption. Do not create a board beside native work or
+ write both owners. A mixed or unsafe store is a refusal to report, not a reason
+ to switch writers.
- Before an authorized board mutation, read the installed helper card:
+ Before invoking the helper, read the installed helper card:
`../../includes/helper-invocation.md` relative to this loaded skill.
- Set its loaded-resource input
- to the absolute path of this **loaded** command or skill, and select the literal
- relative helper `hooks/taskwrite.py`. Resolve and check that helper exactly once
- using the card, then run its interpreter-selection block for the current shell.
- Run from the intended project worktree so the writer targets
- that project's board. Do not switch to the plugin directory, use a root token
- from a hook environment in an ordinary tool call, or search source/cache copies.
-
- ## Verbs
-
- Always put `--` before user text (a desc or title) so a value beginning with `-` is not
- parsed as a flag. Use the validated Python 3 interpreter selected by the card;
- never retry a refused helper under another interpreter. Keep every option before `--` and
- pass user text as one literal argument.
-
- - **add** — append a queued task. ID-less by default; pass `--id <group>.<type>` to mint
- a dotted ID now, `--from <origin>` for a harvest back-ref, `--boundaries a,b` for the
- security/trust boundaries it touches. The description must be nonblank and
- single-line; origin and boundary values must also stay on one line.
- - Invoke the resolved helper with `add [--id group.type] [--from origin] [--boundaries a,b] -- <desc>`.
- - **start** — flip a task to in-progress and **stamp the started date** (so it can never
- be a dateless `[~]`). On an ID-less item, pass `--as <group>.<type>` to mint its dotted
- ID at pick-up. `--date YYYY-MM-DD` overrides today.
- - Invoke the resolved helper with `start [--as group.type] [--date YYYY-MM-DD] -- <id|title>`.
- - **done** — flip an in-progress task to done and stamp the done date (`--date`
- overrides today). A queued task must be `start`ed first.
- - Invoke the resolved helper with `done [--date YYYY-MM-DD] -- <id|title>`.
-
- The following are literal minimal `add` invocations after the installed helper
- and interpreter have been resolved. Bind the named text variable to the exact
- caller-supplied description; do not paste that text into the command syntax.
+ Use this loaded command or skill as the card's resource input and resolve
+ `hooks/work.py` exactly once. Run it with the card's selected Python interpreter
+ from the intended project worktree. Keep caller text in literal arguments; do
+ not interpolate it into shell syntax or search for a source/cache copy.
- ### PowerShell add invocation
- ```powershell
- & $caPython -B $caHelper add -- $caDescription
- if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
- ```
+ ## Ordinary actions
- ### POSIX add invocation
- ```sh
- "$ca_python" -B "$ca_helper" add -- "$ca_description"
- ```
+ - **List or select:** `work.py list --limit 32`, then `work.py get <WORK-ID>`
+ for the selected item. Use the returned `work_id`, not a title or dotted
+ legacy alias. If the item is absent or selection is ambiguous, stop and
+ report it.
+ - **Add:** `work.py create --title <description> --intent <description>
+ --type unknown --operation-id <stable-request-id>`. Pass `--origin <source-key>`
+ when work comes from a durable source. A distinct action gets a new request
+ ID; an uncertain retry keeps the original ID. Use the returned `work_id` for
+ later actions.
+ - **Start:** `work.py start <WORK-ID> --operation-id <stable-request-id>`.
+ - **Complete:** `work.py complete <WORK-ID> --operation-id <stable-request-id>`.
+ Queued work already performed can be recorded complete directly. Do not
+ invent a start event. This records local progress; checks remain unknown
+ until their actual evidence is assessed.
+ - **Reopen:** `work.py reopen <WORK-ID> --operation-id <stable-request-id>`.
- When `add` needs fields, bind each value separately and keep all options before
- `--`. Use the `--from=<value>` form if the origin begins with a hyphen. These
- examples preserve quotes, metacharacters, and non-ASCII description text as
- one argument; neither shell evaluates the variable's contents as a command.
+ For a create, bind the caller's description and stable request ID as separate
+ variables after resolving the installed helper and interpreter from the card.
+ Pass each value as a literal argument from the intended worktree. A distinct
+ intent may be bound separately when its wording differs from the title.
- ### PowerShell add with options
+ ### PowerShell create invocation
```powershell
- $caAddArgs = @('add', '--id', $caId, "--from=$caOrigin", '--boundaries', $caBoundaries, '--', $caDescription)
- & $caPython -B $caHelper @caAddArgs
+ $caCreateArgs = @('create', '--title', $caDescription, '--intent', $caDescription, '--type', 'unknown', '--operation-id', $caRequestId)
+ & $caPython -B $caHelper @caCreateArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
```
- ### POSIX add with options
+ ### POSIX create invocation
```sh
- "$ca_python" -B "$ca_helper" add --id "$ca_id" "--from=$ca_origin" --boundaries "$ca_boundaries" -- "$ca_description"
+ "$ca_python" -B "$ca_helper" create --title "$ca_description" --intent "$ca_description" --type unknown --operation-id "$ca_request_id"
```
- For `start` and `done`, replace only the verb and its literal option array,
- keeping the same resolved helper and `--` before the one title or ID argument.
+ The facade reads the selected revision for an ordinary update and applies the
+ owner's exact change check. When a caller already holds the preimage, pass
+ `--expected-revision` and `--expected-model-sha256` together for native work,
+ or `--expected-model-sha256` with the returned board hash for legacy work.
+ Keep the same request ID and preimage for an exact retry after an uncertain
+ result. A changed item is a conflict to inspect; do not overwrite it by
+ minting a fresh request ID.
- A missing target, an already-matching state, an out-of-order transition, a malformed
- add field or `--date`, or an invalid `GROUP.TYPE` namespace is reported and writes
- nothing (exit 1).
- A queued `done` identifies the task as queued and tells the caller to `start` it first.
- **Targeting by title is best-effort:**
- prefer the dotted ID, and
- note that if two ID-less items share a title, `start`/`done` act on the first — give one
- an ID (`/ca-task start --as <group>.<type> -- "<title>"`) to disambiguate.
+ For a historical ID-less board row that cannot be selected through a stable
+ `WORK-ID`, `hooks/taskwrite.py` remains an explicit compatibility or repair
+ path. Inspect the exact row and use its documented selector and board lock;
+ do not teach best-effort title matching as the normal /task route. Direct
+ board edits remain invalid.
- ## When NOT to use
+ ## Related owners
- - Promoting workflow follow-ups in bulk → that is the harvest
- (`<plugin-root>/includes/harvest.md`), which calls this writer for you.
- - Reading the board / counts → `/ca-status` (read-only).
- - Archiving long-settled done items → `/ca-standup` owns the sweep (D-2,
- resolved 2026-07-31). It proposes dated done items strictly more than 14 calendar
- days old and requires a separate yes for each item before invoking
- the same installed `taskwrite.py` with `archive <id>`. This is the helper's
- archive verb, not a new public `/ca-task archive` mode. Undated done items are never
- proposed automatically; standup's explicit-request and `--allow-undated` rules
- apply. Declined items stay on the board.
- - Filing a separate `chore(board)` PR just to flip a task state → task-board transitions
- (`[x]` done-flip, `[~]` start-flip, new `[ ]` add) ride the **work commit** via
- commit-gate, co-located atomically with the code that completes, starts, or spawns the
- task (ADR-0008). A lagging board-only PR is the anti-pattern this design eliminates.
+ - Harvest promotes selected follow-ups through the current work owner.
+ - `/ca-standup` owns archival. It uses selected native work or the
+ legacy writer as appropriate and preserves undated historical rows.
+ - Work lifecycle changes ride their associated work commit under ADR-0008;
+ do not open a separate board-only PR to make progress appear complete.
## Hard gate
- - MUST write the board only through `taskwrite.py` (the pure transforms), never a
- free-hand Edit that can malform the schema.
- - `start` MUST stamp a started date — never leave a dateless `[~]`.
- - `done` MUST target an in-progress task — a queued task must go through `start` first.
- - MUST NOT delete a task to "complete" it — mark it `done` so the record survives.
+ - Never hand-edit the legacy board or a native work model.
+ - Never write two work owners for one action or silently adopt a board.
+ - Preserve the selected identity, real host stop, exact change check, and
+ original request ID on an uncertain retry.
+ - Do not equate local completion with passed checks, remote sync, or delivery.