Skip to content

feat: task-board lifecycle + /ca:task writer and follow-up harvest#118

Merged
SUaDtL merged 3 commits into
mainfrom
feat/task-board-lifecycle
Jun 22, 2026
Merged

feat: task-board lifecycle + /ca:task writer and follow-up harvest#118
SUaDtL merged 3 commits into
mainfrom
feat/task-board-lifecycle

Conversation

@SUaDtL

@SUaDtL SUaDtL commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Two related features for the task board (.codearbiter/open-tasks.md).

1. Task-board lifecycle

Gives the backlog a parseable schema and fixes a live miscount: the SessionStart hook and statusline counted every - bullet, so completed work inflated the "in-flight tasks" number (24 vs the real 4 in this repo). Tasks now carry a lifecycle marker ([ ] queued, [~] in-progress, [x] done), a content-bearing group.type.seq ID, and Desc / Done-when / Boundaries fields. A stale in-progress task raises a SessionStart nudge; a lint_board pass surfaces malformed or undated entries so a task cannot silently drop off the map; an oversize board degrades instead of stalling startup.

2. /ca:task writer and follow-up harvest (resolves D-1)

/ca:task add|start|done is the sanctioned board mutator, a thin taskwrite.py over pure _taskboardlib transforms. start always stamps a date, so a task can never become a dateless [~]. Each gated workflow's terminal step harvests its un-actioned residue (NEEDS-TRIAGE markers, the checkpoint DEFERRABLE table, low-confidence sprint decisions) into the durable backlog instead of leaving it in a write-once artifact. Work routes to open-tasks.md, decisions to open-questions.md, deduped by (from <origin>) back-ref, batch-confirmed interactively or SMARTS-logged under /sprint. A blocking decision escalates rather than landing in the non-gating section.

Why

Closes the governance loop: gate run, residue, durable backlog, surfaced next session, groomed via standup. Before this, follow-ups languished in plan files and checkpoint docs nobody re-read.

Test plan

  • python .github/scripts/test_taskboardlib.py (39 tests: count, parse, validate, stale, lint, oversize, reader integration, repo-board conformance)
  • python .github/scripts/test_taskwriter.py (30 tests: writer transforms, the three extractors, promote routing and modes, CLI bad-date and dash-arg)
  • Full CI hook suite and check-plugin-refs.py ca green; session-start and statusline reader regressions green.

Review

Two five-agent review passes ran pre-merge (linkage, functions, docs, security, drop-off) plus a coverage audit. They caught and this fixes: a crash that took down SessionStart on a malformed board; the checkpoint harvest source reading the wrong format (table vs bullets); validation functions that were not wired to any human-visible surface. The security reviewer cleared both features with no critical, high, or medium findings.

Deferred (recorded in open-questions.md, all non-blocking)

D-1 is resolved here. D-2 (archival sweep), D-3 (stale threshold), D-4 (standup harvest backstop), and D-5 (sprint low-confidence threshold) remain open.

Ref: specs/task-board-lifecycle.md, specs/task-writer-harvest.md

https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

SUaDtL added 3 commits June 21, 2026 20:22
open-tasks.md had no schema: the SessionStart hook and statusline counted
every "- " bullet, so completed work under "## Done" inflated the "in-flight
tasks" number (24 vs the real 4 in this repo), and work started-but-unfinished
left no durable trace across a session crash.

Adds _taskboardlib.py — one pure, fixture-tested helper both readers route
through. Tasks carry a lifecycle marker ([ ] queued / [~] in-progress / [x]
done), a content-bearing <group>.<type>.<seq> ID, and Desc / Done-when /
Boundaries fields. The count excludes done; a stale in-progress task surfaces
a SessionStart nudge; an oversize board degrades instead of stalling startup.
The repo's own board is migrated to the schema. Test wired into CI + tech-stack.

CHANGELOG: open-tasks.md gains a kanban-style lifecycle (queued/in-progress/
done) with a corrected in-flight count and a stale-work nudge at session start.

Ref: specs/task-board-lifecycle.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7
Post-commit review fan-out (linkage/functions/docs/security/drop-off) surfaced
one crash and the feature's central gap. Fixes:

- BLOCK: stale_in_progress sorted (age, id) tuples; a same-age tie between an
  ID'd task and a legacy bare [~] bullet (id=None) raised TypeError through
  startup_summary, crashing the entire SessionStart hook. Total-orderable sort
  key + a defensive guard in the hook (fail loud, never dormant).
- Drop-off surfacing (the headline fix): validate_id/duplicate_ids were built
  but never called by the running product, and a one-character slip (indented,
  "-[ ]", "* [ ]") made a real task vanish from the count with no signal. Adds
  lint_board (independent ground-truth: marker-not-at-column-0 + invalid/dup
  IDs) and surfaces it at SessionStart; hardens the CI conformance guard.
- undated_in_progress: a [~] with no started date can never age, so the stale
  nudge missed it forever. Now surfaced as its own startup class.
- statusline import-failure fallback now excludes done (was re-inflating).
- blank "- " / empty "- [ ]" no longer counted; sub-fields no longer leak
  across a ## heading; a decoy "(started ...)" no longer shadows the real date;
  validate_id rejects a trailing newline (\Z).
- docs/linkage: board header points to the schema instead of restating it;
  scaffold vocab aligned; spec seq grammar + "no transition writer" boundary +
  D-2 reference fixed; debug skill writes a schema-conformant queued entry.

CHANGELOG: the task board now actively surfaces malformed/undated entries at
session start so work cannot silently drop off, and a malformed board can no
longer crash session startup.

Ref: specs/task-board-lifecycle.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7
Resolves D-1: /ca:task add|start|done is the sanctioned board mutator (a thin
hooks/taskwrite.py over pure _taskboardlib text-transforms). start ALWAYS
stamps a date, so a task can never become a dateless [~] (the lifecycle hole).

Closes the governance loop: a gated workflow's terminal step now harvests its
un-actioned residue into the durable backlog instead of letting it languish in
a write-once artifact. Three pure extractors (NEEDS-TRIAGE markers, the
checkpoint DEFERRABLE table, sprint low-confidence decisions) feed promote(),
which routes work -> open-tasks.md and decisions -> open-questions.md, dedups
by (from <origin>), batch-confirms interactively / SMARTS-logs under /sprint,
and ESCALATES a blocking decision rather than demoting it to the non-gating
section. Wired at all five terminal steps via one shared includes/harvest.md.

Review fan-out caught and this fixes: the checkpoint source was dead (read
bullets, real section is a table); set_state lost desc text / let a done line
shadow a live task; a bad --date crashed the CLI. Plus the D-1-mandated
routing-table/reference-map registration.

CHANGELOG: new /ca:task command to add/start/done backlog tasks, and an
automatic follow-up harvest that promotes workflow residue (triage notes,
checkpoint deferrals, low-confidence sprint calls) into the backlog so it
cannot silently languish.

Ref: specs/task-writer-harvest.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7
@SUaDtL
SUaDtL merged commit 5441556 into main Jun 22, 2026
19 checks passed
@SUaDtL
SUaDtL deleted the feat/task-board-lifecycle branch June 22, 2026 03:42
SUaDtL added a commit that referenced this pull request Jun 22, 2026
The 2.5.0 section listed only #116/#117. Adds the task-board lifecycle + /ca:task
feature (#118) under Added, and a Fixed group for the farm setup-doc dead-link
(#119) and the crypto/secret gate hardening (#120), rolled from each commit's
CHANGELOG footer. Dates the section to the release day. Project-state-only
changes (.codearbiter/) stay out of the log per its stated scope.

Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>
@SUaDtL SUaDtL mentioned this pull request Jun 22, 2026
SUaDtL added a commit that referenced this pull request Jun 22, 2026
* docs(changelog): roll up #118/#119/#120 into the 2.5.0 section

The 2.5.0 section listed only #116/#117. Adds the task-board lifecycle + /ca:task
feature (#118) under Added, and a Fixed group for the farm setup-doc dead-link
(#119) and the crypto/secret gate hardening (#120), rolled from each commit's
CHANGELOG footer. Dates the section to the release day. Project-state-only
changes (.codearbiter/) stay out of the log per its stated scope.

Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

* feat(site): docs site polish — bespoke landing, Feature Forge, anti-slop copy (#122)

* feat(site): bespoke landing, Feature Forge surfacing, anti-slop copy

The #94 --farm artifact built a working docs site but it read as a
scaffold: stock Starlight chrome, four generic cards, and a landing
that printed `/ca:sprint --farm` while explaining neither --farm nor
the Feature Forge anywhere on the site.

This polish pass makes the site earn a first-time visitor's
understanding within one screen:
- A bespoke landing with a CSS-only animated gate-catch terminal that
  shows a gate blocking a banned crypto primitive, then clearing — the
  actual conversion mechanic, not an assertion. Honors
  prefers-reduced-motion with a static full transcript; the transcript
  is real DOM text.
- Feature Forge surfaced as the differentiator: a landing showcase, a
  Concepts section with the two-axis labelling model, and preview
  badges driven by a site-side generator allowlist (no plugins/ca
  change). --farm is now linked to its explanation.
- Three hand-authored SVG diagrams (lane-flow, two-axis, gate model)
  and custom callouts across the inner pages.
- Copy de-slopped: em-dashes cut from 7/16/10 to 0/0/0 in body prose,
  plus removal of templated phrasing and LLM-tell vocabulary.
- Functional: logo/favicon/social wired, base-safe internal links,
  Pagefind verified in dist.

Reviewed via multi-agent build with adversarial verify (visual design,
link/base-path, copy anti-slop); 4 blocking findings caught and fixed.
Crypto-compliance gate passed (demo transcript text, no operational
crypto). Site suite green: typecheck clean, 104 tests, build 77 pages.

CHANGELOG: Public docs site redesigned — bespoke landing with a live
gate-catch demo, Feature Forge showcase + preview badges, and a copy
anti-slop pass.
Ref: .codearbiter/specs/docs-site-polish.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

* docs(governance): record docs-site-polish spec + harvest follow-ups

Persist the approved spec that drove the feat(site) docs overhaul and
record the two follow-ups its build surfaced, so the out-of-scope work
isn't lost:
- Allowlist-drift reconciler: a CI/doctor check that the site-side
  Feature Forge preview allowlist matches real preview status.
- Base-path img-href convention: unify the relative vs BASE_URL forms
  used for diagram/image sources across the site.

Ref: .codearbiter/specs/docs-site-polish.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

* docs(governance): harvest coverage-auditor follow-ups for docs site

The PR coverage audit confirmed the build green but flagged two spec
acceptance criteria the build delivered as content without the
automated assertion the spec promised (AC-9 diagram titles, AC-13
Concepts forge section), plus an untested defensive path in
forge-status. Record them so the spec's testability promise is honored
rather than quietly dropped.

Ref: .codearbiter/specs/docs-site-polish.md
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

---------

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>

* fix(site): use Starlight 0.33+ array syntax for the social config (#124)

CI's clean `npm ci` installs the pinned Starlight ^0.40.0, which
rejects the legacy `social: { github: ... }` object form and fails the
docs build at config:setup. The dev tree masked this: local
node_modules held a stale Starlight 0.32.6 that still accepted the
object form, so the local build passed while CI went red. Convert to
the array-of-link-items syntax 0.33+ requires.

Verified against a clean install (Starlight 0.40.0): build exits 0
(77 pages), typecheck clean, 104 tests pass.

CHANGELOG: Docs site builds again on the pinned Starlight; the GitHub
social link renders in the site header.
Closes: docs deploy build failure on PR #123
Claude-Session: https://claude.ai/code/session_016NVNTNAPKXzWD8bmmjVHP7

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>

---------

Co-authored-by: SUaDtL <SUaDtL@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant