diff --git a/custom/agents/smiley.agent.md b/custom/agents/smiley.agent.md index 6b8daa4..f9d78e2 100644 --- a/custom/agents/smiley.agent.md +++ b/custom/agents/smiley.agent.md @@ -1,7 +1,7 @@ --- kind: watchdog id: curabis-smiley -version: 4 +version: 5 title: Smiley — Session Watchdog description: > Always-active session observer. Shapes Claude's behavior from within. @@ -113,6 +113,14 @@ Enforces the four lifecycle rules: `development-requires-bc-task`, `one-task-in-progress-at-a-time`, `testcase-must-fail-before-implementation`, `release-must-update-app-version`. +**2026-08-03 — every transition below also writes a state checkpoint.** +See `[[task-state-lives-in-the-mandatory-artifact]]`: a `[CURABIS-STATE]` +BC task comment for PTE, a checked line in the draft PR description for +AppSource. This is additive to the gates, not a replacement for any of +them — the gates still enforce; the checkpoint just makes where things +stand readable by the operator and resumable after a machine or operator +change, without inventing a new state store. + **Start gate — activate on the outcome, not the phrasing:** The trigger is **"Claude is about to write or modify AL code that changes @@ -134,41 +142,47 @@ all of them mean AL code is about to change. - Customer app (`app.json` idRanges within 50000–99999): a BC task MUST exist. None found via BC MCP → Claude registers it first (create-task workflow), - naturally, before any branch exists. AppSource app: offer, never block. + naturally, before any branch exists. AppSource app: offer, never block — + but open the draft PR now regardless, since it's the AppSource state carrier. - Then, in order: feature branch created → BC `gitHubDevStatus = "In Progress"` - → test case written (including missing fields/setup the scenario needs) - → test run red. + → state checkpoint `TASK_STARTED` → test case written (including missing + fields/setup the scenario needs) → test run red. - **The red result is a human checkpoint.** Claude shows the failing run and waits for the developer to confirm red before writing implementation code. Claude never self-certifies red. This pause is not optional and not undercover — it surfaces as a natural "testen fejler som forventet — bekræft, så bygger jeg." + Once confirmed: state checkpoint `RED_CONFIRMED`. **Focus gate — activate when new work arrives mid-task:** - One task in progress at a time. A "hurtigt lige" request while a task is open → Claude naturally offers the binary choice: finish first, or park (BC `On Hold` + WIP commit). Never a second branch on top of an open task. + Parking writes state checkpoint `ON_HOLD` with the reason — always why, + never just the label. - Break-fix overrides this gate, as always — a broken build interrupts. **Close gate — activate when a task is about to be finished:** -- Test case green (actually run, not assumed) → **independent review** - (`al-review.agent.md` — Torvalds & Winters, 2026-07-31) → merge to the - declared track branch → BC `Done`. Red test = the task cannot close, no - exceptions. A BLOCK verdict from the independent review is the same kind - of hard stop as a red test — green tests prove the requirement is met, - not that the change is well-built. +- Test case green (actually run, not assumed) → state checkpoint + `GREEN_CONFIRMED` → **independent review** (`al-review.agent.md` — + Torvalds & Winters, 2026-07-31) → state checkpoint `REVIEW: ` → + merge to the declared track branch → BC `Done` / PR merged → state + checkpoint `MERGED`. Red test = the task cannot close, no exceptions. A + BLOCK verdict from the independent review is the same kind of hard stop + as a red test — green tests prove the requirement is met, not that the + change is well-built. - At release (track branch → main, tag, AppSource submission): app.json version consciously bumped before the merge. **The chain:** ``` Task requested - → BC task exists? (mandatory 50000–99999, optional AppSource) - → branch + BC "In Progress" - → test case written → RED confirmed by developer + → BC task exists? (mandatory 50000–99999) / draft PR opened (AppSource) + → branch + BC "In Progress" [state: TASK_STARTED] + → test case written → RED confirmed by developer [state: RED_CONFIRMED] → implementation - → test GREEN - → independent review (al-review: Torvalds + Winters lenses) → APPROVE(-WITH-NOTES) - → merge to track branch → BC "Done" + → test GREEN [state: GREEN_CONFIRMED] + → independent review (al-review: Torvalds + Winters) [state: REVIEW: ] + → merge to track branch → BC "Done" / PR merged [state: MERGED] → at release: version bump ``` diff --git a/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md b/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md new file mode 100644 index 0000000..acad3d3 --- /dev/null +++ b/custom/knowledge/architecture/task-state-lives-in-the-mandatory-artifact.md @@ -0,0 +1,108 @@ +--- +bc-version: [all] +domain: architecture +keywords: [task-state, persistence, resumability, bc-task, pull-request, pte, appsource, lifecycle, operator-handoff] +technologies: [al, mcp] +countries: [w1] +application-area: [all] +--- + +# Task State Lives in the Mandatory Artifact — Never a New Store + +## Description + +A task's progress through the lifecycle gates (start, red, green, review, +merge) must be readable by both the operator and Claude, must survive a +machine change, and must survive an **operator change** — a different +developer picking up where the last one stopped. That rules out anything +machine-local (a gitignored file, session memory). + +The correct home is not a new, bespoke state store — it's whichever +artifact is **already mandatory** for that task's flow: + +- **PTE** (`app.json` idRange 50000–99999): a BC sub-task always exists + before development starts (`[[development-requires-bc-task]]`, no + exceptions). The sub-task's comments (`taskComments`, PAG6102902) ARE the + state store. Nothing new to build — just a disciplined format for what + gets written there. +- **AppSource**: no BC task is mandatory today (`[[one-task-in-progress-at-a-time]]` + — "AppSource app: offer, never block"). The mandatory artifact instead is + the pull request. Open it as a draft early — at the start gate, not only + when work is ready for review — and its description carries the state as + a checklist. + +Do not build a third mechanism (a community example: a dedicated +`workflowSessionManager` with its own session IDs) when a task already has +a mandatory home. Building a parallel store means two sources of truth that +can drift; the artifact the flow already requires cannot drift from itself. + +## State vocabulary (both flows use the same stages) + +``` +TASK_STARTED branch created, BC gitHubDevStatus = In Progress (PTE only) +RED_CONFIRMED test written, developer confirmed the failing run +GREEN_CONFIRMED test passes, developer/CI has actually run it +REVIEW: APPROVE | APPROVE_WITH_NOTES | BLOCK al-review's verdict +ON_HOLD parked mid-task (Focus gate) — always includes why +MERGED track branch merged, BC Done (PTE) / PR merged (AppSource) +``` + +## PTE format — a tagged comment per transition + +Write one `[CURABIS-STATE]` comment per transition via `Create_TaskComment_PAG6102902` +(new) or `Modify_TaskComment_PAG6102902` (correcting the same transition, never +silently editing history — see Anti-Pattern). Keep it one line, machine-parseable: + + [CURABIS-STATE] RED_CONFIRMED — 2026-08-03, mid + +To resume: call `List_TaskComments_PAG6102902` scoped to `projectNo` + +`subTaskNo`, filter for `[CURABIS-STATE]` lines, the last one is current +state. Never infer state from `gitHubDevStatus` alone — that enum only has +four values (Backlog/In Progress/Done/On Hold) and cannot distinguish +"red confirmed" from "green confirmed" from "blocked in review". + +## AppSource format — a checklist in the PR description + +Open the PR as a draft at the start gate (not when work is ready), title and +branch as normal, description containing: + + ## CURABIS Task State + - [x] Branch created — 2026-08-03, mid + - [x] Test written, RED confirmed — 2026-08-03, mid + - [ ] Implementation + - [ ] Test GREEN confirmed + - [ ] Independent review (al-review) + - [ ] Merged + +Update via `gh pr edit --body`, checking boxes as gates pass — never remove +or reorder completed lines, only append the next checked box. To resume: +`gh pr view --json body` and read which boxes are checked. + +## Why not adopt a dedicated session-state tool + +The community pattern this generalizes from (`workflow_start`/`workflow_next`/ +`workflow_status`, etc.) has real persisted, queryable state — genuinely +worth having — but enforces **no gating whatsoever**: the tool hands back a +natural-language instruction and trusts the calling agent to follow it, with +no human checkpoint anywhere in the mechanism. CURABIS's actual advantage is +the opposite property — RED_CONFIRMED and BLOCK are hard stops, not +suggestions (`[[testcase-must-fail-before-implementation]]`). Building a +parallel state store without also rebuilding that discipline would trade a +real strength for a shinier mechanism. This rule adds the persistence +without touching the gating. + +## Anti-Pattern + + // WRONG: editing a state comment's text after the fact to "fix" the record + Modify_TaskComment_PAG6102902(commentId, "[CURABIS-STATE] GREEN_CONFIRMED — 2026-08-03") + // on a comment that previously said RED_CONFIRMED — this destroys the + // audit trail. Append a new comment for the new state; only use Modify + // to correct a typo in the SAME transition, never to change which + // transition it records. + +## Scope + +Applies to every task on every CURABIS-owned or customer repo, PTE and +AppSource alike, from the moment `[[development-requires-bc-task]]` or the +AppSource equivalent activates. Wired into Smiley's Task Lifecycle gates — +see `smiley.agent.md`. diff --git a/custom/setup/templates/al-review.agent.md b/custom/setup/templates/al-review.agent.md index 86d93d3..df16230 100644 --- a/custom/setup/templates/al-review.agent.md +++ b/custom/setup/templates/al-review.agent.md @@ -1,7 +1,7 @@ --- kind: action-skill id: curabis-al-review -version: 1 +version: 2 title: CURABIS AL independent review (Torvalds & Winters) description: Independent per-change code reviewer. Runs after the TDD green gate and before merge — the fourth checkpoint, separate from the implementer and from portfolio-level rule governance (Rømer/Immanuel/Court, who ask "is the ruleset healthy", not "is THIS change good"). Two lenses - Linus Torvalds (BC/AL domain-technical correctness, backward compatibility, performance, security) and Titus Winters (general software-engineering maintainability, architecture, complexity over time). inputs: [diff, task-description] @@ -122,6 +122,13 @@ remember to request. See `smiley.agent.md`. missing standing rule, not just a one-off) - **BLOCK** — must be addressed before merge, no exceptions negotiated by authority or deadline pressure (Linus's rule, not just a suggestion) +6. **Record the verdict as a state checkpoint** — `REVIEW: ` — in + whichever artifact carries this task's state (BC task comment for PTE, + the draft PR description for AppSource). See + `[[task-state-lives-in-the-mandatory-artifact]]`. The verdict is not + findings-only in this one respect: it's the record that this checkpoint + happened at all, so a resumed session doesn't re-run a review that + already passed, or silently skip one that hasn't happened yet. ## Output format diff --git a/custom/setup/templates/bc-mcp.agent.md b/custom/setup/templates/bc-mcp.agent.md index 161c6df..a6482d2 100644 --- a/custom/setup/templates/bc-mcp.agent.md +++ b/custom/setup/templates/bc-mcp.agent.md @@ -1,9 +1,9 @@ --- kind: action-skill id: curabis-bc-mcp -version: 2 +version: 3 title: CURABIS Business Central MCP usage -description: How to use the CURABIS Business Central MCP server to read project-management work from BC and write GitHub dev status back. Company-default workflow for syncing Claude Code / GitHub work with BC tasks. v2 (2026-07-30) - BC MCP switched from Dynamic to Static Tool Mode; 14 directly-named tools replace the old search/describe/invoke indirection. +description: How to use the CURABIS Business Central MCP server to read project-management work from BC and write GitHub dev status back. Company-default workflow for syncing Claude Code / GitHub work with BC tasks. v2 (2026-07-30) - BC MCP switched from Dynamic to Static Tool Mode; 14 directly-named tools replace the old search/describe/invoke indirection. v3 (2026-08-03) - task-comment state checkpoints for resumability across machine/operator changes. inputs: [project-no, task-no, branch, dev-status, comment] outputs: [task-list, updated-task, posted-comment] bc-version: [all] @@ -125,6 +125,18 @@ Moving to `Accepted` requires `Starting date`, `Estimated time` and `Expected De 4. **Finish.** Set `gitHubDevStatus = Done` automatically when branch is merged to main. Set `On Hold` if the branch is parked. +**State checkpoints (2026-08-03):** at each Smiley Task Lifecycle transition +(see `smiley.agent.md`), call `Create_TaskComment_PAG6102902` with a one-line +`[CURABIS-STATE] — , ` comment — +`TASK_STARTED`/`RED_CONFIRMED`/`ON_HOLD: `/`GREEN_CONFIRMED`/ +`REVIEW: `/`MERGED`. This is what makes the task resumable by a +different developer or a different machine without re-deriving where things +stood from `gitHubDevStatus` alone (that enum only has four values and can't +distinguish "red confirmed" from "blocked in review"). To resume: call +`List_TaskComments_PAG6102902` scoped to the task, filter for +`[CURABIS-STATE]`, the last one is current. See +`[[task-state-lives-in-the-mandatory-artifact]]`. + ## Create task workflow (PAG6102905) Use `Create_NewTask_PAG6102905` when a developer wants to register a new task from VS Code.