feat(goals): add domain/repo goal tracking and update_workstream MCP tool

- Migration c5d6e7f8a9b0: domain_goals and repo_goals tables, repo_goal_id FK on workstreams
- DomainGoal: one active per domain (partial unique index), status active/archived/superseded
- RepoGoal: integer priority, status active/paused/completed/archived, optional domain_goal_id link
- WorkstreamUpdate schema and router extended with repo_goal_id and repo_goal_id filter
- 6 new MCP goal tools: create_domain_goal, get_domain_goals, activate_domain_goal, create_repo_goal, get_repo_goals, update_repo_goal
- update_workstream MCP tool: patch any subset of workstream fields (title, description, owner, due_date, repo_goal_id, status)
- get_domain_summary extended with goal_guidance (needs_workplan, alignment_warnings) signals
- Dashboard goals.md page and docs/goals.md reference page
- CLAUDE.md template updated to act on goal_guidance signals at session start
- CUST-WP-0010 workplan for this feature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 00:15:29 +01:00
parent 4ab56494ad
commit 651df73e3a
20 changed files with 1212 additions and 10 deletions

136
dashboard/src/docs/goals.md Normal file
View File

@@ -0,0 +1,136 @@
---
title: Goals — Reference
---
# Goals — Reference
The Goals page shows strategic intent at two levels — **domain** and **repository** — and how they relate. It provides context for why workstreams exist and what they collectively deliver.
---
## The two goal levels
### Domain Goal
A domain goal captures the **high-level strategic intent** for an entire domain (e.g., railiance, markitect). It answers the question: *"What are we ultimately trying to achieve here?"*
Key properties:
- Only **one domain goal can be active** per domain at any time.
- When a new goal is activated, the previous one is automatically marked **superseded** — it is retained as history, not deleted.
- Goals can also be manually set to **archived** to park them permanently.
### Repository Goal
A repository goal refines a domain goal into **actionable scope** for a specific repository. It answers: *"What does this repo need to deliver to advance the domain goal?"*
Key properties:
- A repo can have **multiple active goals** with different **priorities**.
- Priority is an integer — lower number means higher priority (e.g., `10` takes precedence over `100`).
- Each repo goal should be linked to its parent domain goal via `domain_goal_id`, though unlinked goals are also supported.
- Goals can shift between `active`, `paused`, `completed`, and `archived` as work evolves.
---
## Status lifecycle
### Domain goals
```
active ──→ superseded (auto, when a newer goal is activated)
active ──→ archived (manual, via PATCH /domain-goals/{id})
```
Only one goal per domain can hold `active` status. Activating a goal via `POST /domain-goals/{id}/activate` supersedes whatever was active before.
### Repository goals
```
active ──→ paused (work deprioritised, not abandoned)
active ──→ completed (the goal was achieved)
active ──→ archived (scope dropped or obsolete)
paused ──→ active (work resumed)
```
Completed and archived goals are preserved as history. They appear in the secondary accordion on the Goals page under the domain goal they were linked to.
---
## Page layout
The Goals page groups everything by domain:
```
┌─ railiance ──────────────────────────────────────────────────────┐
│ ┌─ Domain Goal ──────────────────────────── [active] ─────────┐ │
│ │ Three-Phoenix Secure Kubernetes Infrastructure │ │
│ │ Improve the railiance repositories so that I can … │ │
│ │ ───────────────────────────────────────────────────────── │ │
│ │ Repository Goals │ │
│ │ ┌─ #10 railiance-bootstrap ─────────── [active] ────────┐ │ │
│ │ │ Secure Single-Server Bootstrap at HostEurope │ │ │
│ │ │ Bootstrap a new server securely at hosteurope … │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ▶ 0 secondary goals │
└────────────────────────────────────────────────────────────────────┘
```
- The **active domain goal** is the primary card with a green left border.
- **Repository goals** are nested inside it, sorted by priority (lowest number first).
- **Secondary goals** (superseded and archived domain goals, with their repo goals) are collapsed into an accordion below the active goal. Click to expand.
- Domains that have no active goal are shown at the bottom and highlighted amber in the KPI box.
- **Unlinked repository goals** — active repo goals not associated with any domain goal — appear in a separate section at the bottom of the page.
---
## KPI sidebar
| Metric | Meaning |
|---|---|
| **domains with active goal** | How many of your active domains have a current strategic intent set |
| **active repo goals** | Total active repo goals across all repos |
| **no active goal** | Domains missing a goal — shown in amber when non-zero |
---
## MCP tools
| Tool | Description |
|---|---|
| `create_domain_goal(domain_slug, title, description)` | Create a new active goal for a domain (supersedes previous active) |
| `get_domain_goals(domain_slug, status?)` | List domain goals, optionally filtered by status |
| `activate_domain_goal(goal_id)` | Make an existing goal active, superseding the current one |
| `create_repo_goal(repo_slug, title, description, domain_goal_id?, priority?)` | Create a repo goal, optionally linked to a domain goal |
| `get_repo_goals(repo_slug, status?)` | List repo goals for a repository |
| `update_repo_goal(goal_id, ...)` | Update title, description, priority, status, or domain link |
---
## REST endpoints
| Method | Path | Effect |
|---|---|---|
| `GET` | `/domain-goals/` | List domain goals (filter: `domain_slug`, `status`) |
| `POST` | `/domain-goals/` | Create a domain goal |
| `GET` | `/domain-goals/{id}` | Get a single domain goal |
| `PATCH` | `/domain-goals/{id}` | Update title, description, or status |
| `POST` | `/domain-goals/{id}/activate` | Activate a goal (supersedes current active) |
| `GET` | `/repo-goals/` | List repo goals (filter: `repo_slug`, `domain_goal_id`, `status`) |
| `POST` | `/repo-goals/` | Create a repo goal |
| `GET` | `/repo-goals/{id}` | Get a single repo goal |
| `PATCH` | `/repo-goals/{id}` | Update any field |
---
## Linking workstreams to repo goals
Workstreams carry an optional `repo_goal_id` field. Setting it traces *why* a workstream exists — which specific repo goal it contributes to. This connection is currently recorded in the DB but is not yet visualised in the Workstreams page.
To set the link when creating a workstream via `create_workstream`, pass `repo_goal_id`. To update an existing one, use `PATCH /workstreams/{id}/` with `{"repo_goal_id": "<uuid>"}`.
---
## Design rationale
Goals are intentionally separate from workstreams. A workstream is a unit of *deliverable work*; a goal is a statement of *strategic intent*. Goals are stable and long-lived; workstreams are created, completed, and replaced as work advances. The goal hierarchy (domain → repo → workstream) provides the context needed to understand why any given piece of work exists.