mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-10-05 14:46:55 +01:00
Merge pull request #25 from Curabis/feat/persisted-task-state
Persisteret opgave-tilstand: BC-kommentar (PTE) / draft PR (AppSource)
This commit is contained in:
commit
bfc2c59cc9
4 changed files with 160 additions and 19 deletions
|
|
@ -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: <verdict>` →
|
||||
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: <verdict>]
|
||||
→ merge to track branch → BC "Done" / PR merged [state: MERGED]
|
||||
→ at release: version bump
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <number> --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`.
|
||||
|
|
@ -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: <verdict>` — 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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] <STAGE> — <date>, <developer>` comment —
|
||||
`TASK_STARTED`/`RED_CONFIRMED`/`ON_HOLD: <why>`/`GREEN_CONFIRMED`/
|
||||
`REVIEW: <verdict>`/`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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue