Add planning baseline: BC, SA, PP and two gateways
Create the Business Case, Stakeholder Analysis (S01 course participant, S02 Udemy coursists, S03 GitHub viewers), Project Plan and the milestone documents MIL-001 (project setup, 6 tasks) and MIL-002 (game implementation, 8 tasks) for the console Blackjack game. Register PP and MIL in the artifact registry, set the PO language to en, and link the synced Gitea milestones in the Gateway Schedule. Refs #1 Refs #2 Refs #3 Refs #4 Refs #5 Refs #6 Refs #7 Refs #8 Refs #9 Refs #10 Refs #11 Refs #12 Refs #13 Refs #14
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
---
|
||||
name: project-planning
|
||||
description: Plan a project (or a new phase of one) in phases with tasks, and sync those phases and tasks to Gitea or GitHub as Milestones and Issues. Use when starting a new project, adding or updating a phase/gateway, breaking a phase down into tasks, deciding whether a task needs its own use case or user story, or asked to create/update project milestones or issues on the git host.
|
||||
---
|
||||
|
||||
# Project Planning
|
||||
|
||||
Plans a project as phases (gateways), each phase as a set of tasks, and
|
||||
keeps those phases and tasks in sync with the git host's own project
|
||||
management (Milestones and Issues). It builds on the `artifact` skill's
|
||||
`PP` (Project Plan) and `MIL` (Milestone/Gateway) types.
|
||||
|
||||
## Domain language first
|
||||
|
||||
Before planning, find the Product Owner's (PO's) domain language. Take it from
|
||||
the first of these that states it:
|
||||
|
||||
1. the user's prompt;
|
||||
2. a file the user included or that the project already has (the `Languages`
|
||||
section of `docs/artifact-registry.md`).
|
||||
|
||||
If none states it, **ask the user for it** and stop planning until it is
|
||||
answered; never assume one. Record the answer in the registry's `Languages`
|
||||
section. If it differs from the project's working language, the high-level
|
||||
artifacts are also kept in it (see the registry's translation list).
|
||||
|
||||
## Start here
|
||||
|
||||
Before planning or building anything, check that the baseline exists (the
|
||||
`docs/artifact-registry.md` rows and files): the Business Case (`BC`), the
|
||||
Stakeholder Analysis (`SA`), the Project Plan (`PP`) and at least one
|
||||
milestone (`MIL`). If one is missing, create it first, in that order, with
|
||||
`new-artifact.sh` (it refuses when a type in the catalog's `Requires` column
|
||||
is missing).
|
||||
|
||||
A "build X" request is planning-first. Produce the phases, tasks and issues,
|
||||
show the dry run of `sync-project.sh`, and ask for a go-ahead before any code
|
||||
is written; running `--apply` is the user's decision. Only the user can waive
|
||||
the plan, in chat, for that request; the waiver does not carry over. The rule
|
||||
is defined in `framework/process/plan-first-gate.md`.
|
||||
|
||||
## The hierarchy
|
||||
|
||||
```
|
||||
Business goal → Feature/requirement → Use case/user story → Tasks
|
||||
```
|
||||
|
||||
The use case/user story explains **why** a feature exists; tasks explain
|
||||
**how** the team implements it. Not every task needs a use case:
|
||||
|
||||
- **Needs a use case/user story** — the task is something a user, or
|
||||
another system, actually does: "User resets password", "Admin exports
|
||||
customer report", "Payment service processes refund".
|
||||
- **Plain task, no use case** — purely technical/implementation work:
|
||||
"Refactor authentication middleware", "Add database index", "Upgrade
|
||||
React version", "Fix null-pointer bug", "Add unit tests", "Configure CI
|
||||
pipeline", "Optimize SQL query".
|
||||
|
||||
When in doubt, ask: does this row describe a goal an actor is pursuing, or
|
||||
a step the team takes to build something? Goals get a use case; steps stay
|
||||
a plain task.
|
||||
|
||||
## Use cases get their own folder
|
||||
|
||||
Each use case lives in `docs/uc-NNN/` (`UC-001` → `docs/uc-001/`), together
|
||||
with the artifacts that belong to it. Nothing about a use case goes in a
|
||||
shared `docs/use-cases/` folder.
|
||||
|
||||
1. **Create the folder and the use case:**
|
||||
`bash framework/scripts/new-artifact.sh UC --file docs/uc-001/uc.md`.
|
||||
2. **Create only the artifacts this use case affects,** in this order, each in
|
||||
the same folder with a fixed file name. Skip any it does not touch (no
|
||||
`erd.md` if nothing is stored; no `dm.md` if it adds no concept).
|
||||
|
||||
| Order | Type | File | Create when the use case… |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | `SSD` | `ssd.md` | has system interaction to show (almost always) |
|
||||
| 2 | `DM` | `dm.md` | introduces or changes domain concepts |
|
||||
| 3 | `OC` | `oc.md` | has system operations that change state |
|
||||
| 4 | `SD` | `sd.md` | needs a collaboration design for an operation |
|
||||
| 5 | `DCD` | `dcd.md` | adds or changes design classes |
|
||||
| 6 | `ERD` | `erd.md` | adds or changes persisted data |
|
||||
|
||||
```bash
|
||||
bash framework/scripts/new-artifact.sh SSD --file docs/uc-001/ssd.md
|
||||
bash framework/scripts/new-artifact.sh DM --file docs/uc-001/dm.md --cite UC-001=docs/uc-001/uc.md
|
||||
```
|
||||
|
||||
`new-artifact.sh` cites only the artifacts in the same use-case folder
|
||||
(and project-level ones); for `DM`, `DCD` and `ERD`, add the use case and
|
||||
sibling artifacts by hand with `--cite`. Each gets its own ID (the next
|
||||
version in the registry, e.g. `DM-002`) and its own `RC-*` review.
|
||||
3. **Reconcile with the project models.** The use-case artifacts are a scoped
|
||||
view; the project-level `docs/domain-model.md`, `docs/dcd.md` and
|
||||
`docs/erd.md` are the consolidated truth. When the use case's `DM`, `DCD`
|
||||
or `ERD` are done, compare each with its project-level document:
|
||||
- add the new concepts, classes, attributes and entities; change the ones
|
||||
the use case modified;
|
||||
- keep names identical to the existing ones, and resolve any conflict
|
||||
with another use case's model instead of duplicating the element;
|
||||
- give each project-level document a new `## Version History` row (Change:
|
||||
which use case caused it), and create it from the first use case's
|
||||
document if it does not exist yet;
|
||||
- if nothing needs to change, say so in the use case's task and PR
|
||||
description ("project DM/DCD/ERD unchanged: <reason>").
|
||||
|
||||
## Planning a project (or a new phase)
|
||||
|
||||
1. **Phases are gateways.** Each phase is a `MIL-*` document (the `artifact`
|
||||
skill's `MIL` type): purpose, deliverable, Go/No-Go criteria, dependencies,
|
||||
ownership, target date. Create one with
|
||||
`bash framework/scripts/new-artifact.sh MIL --file docs/milestones/mil-<NNN>-<slug>.md`.
|
||||
2. **The plan schedules the phases.** `docs/project-plan.md` (the `artifact`
|
||||
skill's `PP` type) lists every phase with its window and owner, and holds
|
||||
the overall timeline diagram. Create it once with
|
||||
`bash framework/scripts/new-artifact.sh PP`.
|
||||
3. **Break each phase into tasks.** In the phase's `## Tasks` section, add
|
||||
one row per task using the hierarchy rule above. Tasks that need a use
|
||||
case or user story get one created first (`UC`/`US` types; a use case
|
||||
follows "Use cases get their own folder" below), then are referenced from
|
||||
the Tasks row; plain tasks just describe the work.
|
||||
4. **Sync to the git host.** Run the sync tool (below) to create or update
|
||||
the corresponding Milestones and Issues. Do this whenever a phase or its
|
||||
tasks change — the tool is idempotent (matches by title, never creates a
|
||||
duplicate).
|
||||
|
||||
## Syncing to Gitea/GitHub
|
||||
|
||||
```bash
|
||||
bash framework/scripts/sync-project.sh # prints the plan only — no network calls
|
||||
bash framework/scripts/sync-project.sh --milestone MIL-002 # limit to one phase
|
||||
bash framework/scripts/sync-project.sh --apply # actually create/update on the git host
|
||||
```
|
||||
|
||||
- **Default is a dry run**: it parses `docs/milestones/mil-*.md` and prints
|
||||
what would be created or updated. Nothing is sent anywhere.
|
||||
- **`--apply`** performs the real requests. It needs:
|
||||
- **Gitea** (default — detected from `origin`'s hostname): `GITEA_TOKEN`
|
||||
env var, a personal access token. This is an HTTP API call (milestones,
|
||||
issues) — a deploy key cannot be used, since deploy keys only
|
||||
authenticate SSH git transport (clone/fetch/push), not the REST API.
|
||||
Scope the token to issues only if your Gitea version supports scoped
|
||||
tokens, rather than a full-account one.
|
||||
- **GitHub** (detected when `origin` is on github.com, or pass
|
||||
`--host github`): the `gh` CLI, already logged in (`gh auth login`).
|
||||
- **`--with-project`** additionally tries to create/attach a Kanban Project
|
||||
board. This is best-effort: some Gitea versions (confirmed on 1.27.3) show
|
||||
Projects/Kanban only in the web UI and expose **no REST API for it at
|
||||
all**, so this always fails there — check your server's own
|
||||
`https://<host>/swagger.v1.json` for any `project` path if unsure. GitHub
|
||||
Projects (v2) needs `gh` with the `project` scope. Either way the script
|
||||
warns and continues; Milestones and Issues are unaffected. Where there's
|
||||
no API, create the board by hand at `https://<host>/<owner>/<repo>/projects`.
|
||||
- Read the script's header comment for the full flag list, including
|
||||
`--owner`, `--repo`, `--api-base` to override auto-detection.
|
||||
|
||||
`--apply` is an outward-facing, hard-to-reverse action (it creates real
|
||||
Milestones/Issues on the git host) — run it yourself once you're ready, or
|
||||
ask explicitly for it to be run.
|
||||
|
||||
## Branching before commits
|
||||
|
||||
**Never commit, push or open a PR unless the user asks.** The user reviews
|
||||
the working-tree changes first; finish the edits, summarise them and stop.
|
||||
Everything below (branching, closing keywords, resolving commit links, the
|
||||
PR) describes how to do those steps once the user has asked for them; it is
|
||||
not permission to start them.
|
||||
|
||||
Never commit directly on `main`. This is enforced locally by a pre-commit
|
||||
hook (`framework/githooks/pre-commit`) once
|
||||
`bash framework/scripts/install-git-hooks.sh` has been run in this clone —
|
||||
run it once per clone; it points `core.hooksPath` at the versioned
|
||||
`framework/githooks/` instead of the per-clone, untracked `.git/hooks/`.
|
||||
The hook refuses the commit with a pointer back to this section; a rare,
|
||||
deliberate exception can bypass it with `ALLOW_MAIN_COMMIT=1 git commit`.
|
||||
|
||||
Before the first commit of a piece of work, create and switch to a new
|
||||
branch, then commit there:
|
||||
|
||||
```bash
|
||||
git checkout -b <branch-name>
|
||||
# ... commits ...
|
||||
git push -u origin <branch-name>
|
||||
```
|
||||
|
||||
- Name the branch for the gateway/task it covers, kebab-case, e.g.
|
||||
`g2-kpi-bmc-bpmn` or `mil-002-kpi-baseline` — short enough to read in a
|
||||
PR list, specific enough to say what it's for.
|
||||
- Open a PR (`gh pr create` on GitHub, or the Gitea equivalent) instead of
|
||||
merging straight to `main`; this project's own history is a merged PR
|
||||
per phase (e.g. "Merge pull request 'Close G1 inception baseline...'"),
|
||||
so keep following that pattern.
|
||||
- This applies to every commit, not just gateway/task work — if in doubt
|
||||
whether the current branch is `main`, check (`git branch --show-current`)
|
||||
before committing.
|
||||
|
||||
## Closing tasks from commits
|
||||
|
||||
When a commit finishes the work for a task that `sync-project.sh` has
|
||||
already synced as an Issue, reference that Issue number in the commit
|
||||
message so Gitea/GitHub auto-closes it once that commit lands on the
|
||||
default branch (`main`) — via the PR merge required by "Branching before
|
||||
commits" above, not by pushing the closing keyword to a feature branch.
|
||||
Use `Refs #N` instead when the commit only touches the task without
|
||||
finishing it — that links the commit without closing.
|
||||
|
||||
- **One issue per commit:** use `Closes #5`.
|
||||
- **Several issues closed by the same commit:** put one `Closes #N` per
|
||||
line, not a comma-separated list (`Closes #5, #6, #7` only closed `#5` on
|
||||
a confirmed live Gitea instance — the comma form is not reliably parsed):
|
||||
|
||||
```
|
||||
Closes #5
|
||||
Closes #6
|
||||
Closes #7
|
||||
```
|
||||
- Get each issue number either from the most recent `sync-project.sh` /
|
||||
`sync-project.sh --apply` output (it prints `updated issue #N` /
|
||||
`created issue #N` per task) or, if that's not at hand, from the git
|
||||
host's issue list for the milestone.
|
||||
- Match commits to issues by the task row they implement — one task row in
|
||||
a `MIL-*` document's `## Tasks` section is one Issue, so a commit that
|
||||
completes that row's work closes that Issue.
|
||||
- Don't guess an issue number; if it isn't known from a recent sync or a
|
||||
lookup, ask rather than omit or fabricate one.
|
||||
- **After pushing a multi-issue closing commit, verify** each issue's state
|
||||
came back `closed` (e.g. `GET /repos/<owner>/<repo>/issues/<N>` with
|
||||
`GITEA_TOKEN`) rather than assuming the whole list closed; close any that
|
||||
didn't with a direct `PATCH .../issues/<N>` `{"state":"closed"}` call.
|
||||
|
||||
## Pull requests close the issues they complete
|
||||
|
||||
Every PR must close the Issues its work finishes, so the board matches
|
||||
reality once it merges. Before opening (or updating) a PR:
|
||||
|
||||
1. **List the issues the branch completes.** Go through the task rows the
|
||||
branch implements (`git log main..HEAD`, plus the `## Tasks` of the
|
||||
`MIL-*` it belongs to) and get each Issue number as described in "Closing
|
||||
tasks from commits".
|
||||
2. **Put one closing line per issue in the PR description**, one per line,
|
||||
never comma-separated:
|
||||
|
||||
```
|
||||
Closes #5
|
||||
Closes #6
|
||||
```
|
||||
|
||||
Use `Refs #N` for an issue the PR only touches. A PR that finishes no
|
||||
issue says so explicitly ("No issue closed: <reason>") instead of saying
|
||||
nothing.
|
||||
3. **Ask, don't guess.** If an issue number is unknown or a task is only
|
||||
partly done, ask rather than omit or invent one. Leave a partly done task
|
||||
open and note what remains.
|
||||
4. **After the merge, verify** that each issue is `closed` (the check in
|
||||
"Closing tasks from commits") and close any stragglers by hand. Also make
|
||||
sure the finished task rows are reflected in the `MIL-*` document and, when
|
||||
every task of a phase is closed, that the Milestone is closed too.
|
||||
|
||||
5. **Resolve pending commit links before the PR** (see "Version History rule"
|
||||
in the `artifact` skill): commit, run
|
||||
`bash framework/scripts/resolve-pending-commits.sh <changed docs>`, then
|
||||
commit the result as a follow-up commit.
|
||||
6. **Never ask for, offer or perform the merge.** A PR needs a reviewer: ask
|
||||
the user to open the PR / request a review, and stop there. Merging,
|
||||
enabling auto-merge and "shall I merge?" are not yours to do.
|
||||
|
||||
Closing keywords in the PR description and in commit messages both count on
|
||||
Gitea and GitHub; they only take effect when the PR merges into the default
|
||||
branch.
|
||||
|
||||
## Files this skill touches
|
||||
|
||||
- `docs/project-plan.md` — `PP`, via the `artifact` skill.
|
||||
- `docs/milestones/mil-*.md` — `MIL`, via the `artifact` skill, each with a
|
||||
`## Tasks` section.
|
||||
- `docs/uc-NNN/*.md` (the use case and its `SSD`, `DM`, `OC`, `SD`, `DCD`, `ERD`), `docs/user-stories.md` — only for tasks that need one; plus `docs/domain-model.md`, `docs/dcd.md`, `docs/erd.md` when reconciling.
|
||||
- `framework/scripts/sync-project.sh` — never edited per project; propose
|
||||
changes upstream in the framework.
|
||||
Reference in New Issue
Block a user