Skip to content
Merged
11 changes: 11 additions & 0 deletions specs/024-docs-feature-list-refresh/OPEN-DECISIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Open Decisions: 024-docs-feature-list-refresh

Unsettled items. Do not treat any of the below as decided until a maintainer rules on it here.

## Settled (user, 2026-10-12)
OD-1 (FR-001): the feature catalog is a root `FEATURES.md` next to `README.md`; the website gets a features docs page with the same content, and the README links to it.
OD-2 (FR-005, FR-013): the roadmap has an "In progress" section with one line per open spec (002, 009, 013, 019, 021, 023 at the time of writing), each with its plain-words status and blocker.
OD-3 (FR-009): the website change is docs-page text only (new features page, roadmap page, stale-fact fixes); the landing page is untouched.
OD-4 (plan Constitution Check, Principle I): no Go e2e test; this spec takes the documented docs exception spec 012 used, verified by the sync check's fixture tests and the existing doc gates in CI.

No open decisions remain.
35 changes: 35 additions & 0 deletions specs/024-docs-feature-list-refresh/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Specification Quality Checklist: Documentation Refresh, Feature Catalog, and Roadmap Status

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-10-12
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- All three scope decisions are settled in `OPEN-DECISIONS.md` (OD-1 root `FEATURES.md`, OD-2 every open spec on the roadmap, OD-3 website docs text only). Ready for `/speckit-plan`.
- File paths (`docs/roadmap.md`, `README.md`) appear because the user named them; they are deliverables, not implementation choices.
40 changes: 40 additions & 0 deletions specs/024-docs-feature-list-refresh/contracts/features-catalog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Contract: Feature catalog format

Applies to `FEATURES.md` (main repo root) and `src/content/docs/features.mdx` (website). The sync check ([features-sync-check.md](./features-sync-check.md)) relies on this grammar.

## FEATURES.md

```markdown
# Gameplane features

<intro: what the labels mean (Clarification Q1), status date, link to docs/roadmap.md>

## <Area name>

| Capability | Maturity | Default | Description | Docs |
|---|---|---|---|---|
| <name> | <stable|beta|experimental|planned|in progress> | <on|off|n/a> | <one sentence> | [<text>](<relative link>) |
```

Rules:
- Area headings are level-2 (`## `) and appear in the same order in both files. Level-1 and level-3+ headings are ignored by the check.
- Exactly one catalog table per area, header row exactly as above (column names and order). Any other table in the file is outside an area heading or is ignored only if it does not use this header.
- Cell values for Maturity and Default are lower-case, from the fixed sets, with no extra text or markup.
- Capability cells are plain text: no links, no backticks, no `|`.
- Rows appear in the same order in both files.

## features.mdx (website)

Frontmatter (website content schema):

```yaml
title: Features
description: Every Gameplane capability with its maturity and default.
section: reference
group: releases-roadmap
order: 0
icon: list # an icon already in src/components/icons.ts
eyebrow: DOCUMENTATION
```

Body: same intro meaning, then the same `##` area headings and tables with the same Capability, Maturity and Default cells. Description and Docs cells may differ (website links are relative docs links per the website CLAUDE.md). MDX imports and components are allowed outside the tables.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Contract: features sync check

## Command

```sh
make check-features-sync # runs hack/check-features-sync.sh
make test-features-sync # runs hack/test-check-features-sync.sh (fixture tests)
```

| Env var | Default | Purpose |
|---|---|---|
| `FEATURES_MD` | `FEATURES.md` | Repo catalog path (fixtures override). |
| `FEATURES_MDX` | `website/src/content/docs/features.mdx` | Website page path (fixtures override). |

## Behaviour

1. If either file is missing, exit 2 with `features-sync: missing <path>` (a missing website submodule checkout is an error, never a pass).
2. Parse each file into an ordered list of `(area, capability, maturity, default)` per the [catalog format](./features-catalog.md). Lines inside fenced code blocks are skipped.
3. Validate each row: maturity and default in their fixed sets; `stable` with `default` other than `on` is an error.
4. Compare the two lists in order. Report every difference, not just the first.
5. Exit 0 when both files parse, validate and match; exit 1 otherwise.

## Output on failure (one line per problem)

```
features-sync: <file>:<line>: invalid maturity "<value>"
features-sync: <file>:<line>: stable row must have default "on"
features-sync: area mismatch at position <n>: "<repo area>" vs "<website area>"
features-sync: only in FEATURES.md: <area> / <capability>
features-sync: only in features.mdx: <area> / <capability>
features-sync: <area> / <capability>: maturity "<repo>" vs "<website>"
features-sync: <area> / <capability>: default "<repo>" vs "<website>"
features-sync: <area> / <capability>: order differs
```

## Fixture tests (FR-015, SC-005)

`hack/testdata/check-features-sync/` holds one directory per case with a `FEATURES.md`, a `features.mdx` and, for failing cases, an `.expected` file containing the expected output lines.

- `pass/in-sync`: matching files with differing Description and Docs cells (must pass).
- `pass/code-fence`: a table-looking block inside a code fence is ignored.
- `fail/missing-row-website`, `fail/missing-row-repo`, `fail/maturity-mismatch`, `fail/default-mismatch`, `fail/area-mismatch`, `fail/order-differs`, `fail/invalid-label`, `fail/stable-off`, `fail/missing-file`.

## CI wiring

- `docs and repository checks` job: new step `git submodule update --init website` (only the website submodule), then `make check-features-sync` and `make test-features-sync`.
- `docs` path filter adds `FEATURES.md`, `website`, `hack/check-features-sync.sh`, `hack/test-check-features-sync.sh`, `hack/testdata/check-features-sync/**`.
- `make lint` gains `check-features-sync`.
- If spec 023's change-based selection has landed, the same paths are mapped to the docs job there.
41 changes: 41 additions & 0 deletions specs/024-docs-feature-list-refresh/data-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Data Model: 024 Documentation Refresh, Feature Catalog, and Roadmap Status

No runtime data. The "entities" are structured documentation records.

## Feature catalog entry (row in `FEATURES.md` and `features.mdx`)

| Field | Rule |
|---|---|
| area | The `##` heading the row sits under; one of the areas in [research R6](./research.md#r6-building-the-capability-inventory). |
| capability | Short name of one thing a user or operator can do. Unique within its area. Plain text, no links, no pipe character. |
| maturity | Exactly one of `stable`, `beta`, `experimental`, `planned`, `in progress`. |
| default | `on`, `off` (opt-in), or `n/a` (planned / in progress / tooling with no install default). |
| description | One sentence. May differ between repo and website. |
| docs | Link to the page documenting it. Repo: relative path (`docs/x.md#anchor`). Website: relative docs link (`./x/`). Planned and in-progress rows link to the roadmap. |

Validation (from spec FR-002, Clarification Q1):
- `stable` requires `default = on` and a bucketed e2e test (recorded in `feature-evidence.md`).
- `default = off` forbids `stable`.
- `planned` / `in progress` require `default = n/a` and a roadmap link.
- A withdrawn feature has no row.

## Feature evidence record (`feature-evidence.md`, review aid)

area, capability, maturity, e2e test name or `none`, default source (`values.yaml` key, build tag, module field), notes. One record per catalog row.

## Roadmap item (`docs/roadmap.md`, website `roadmap.mdx`)

| Field | Rule |
|---|---|
| title | Plain words. |
| status | `shipped (<release>)`, `in progress`, `blocked`, `planned`, `out of scope`. |
| reference | Release, spec folder or PR. |
| blocker | Required when status is `blocked`: what blocks it and what unblocks it. |

The roadmap carries one status date. Sections in order: current release and status date; shipped in v0.3.0 and since; in progress (one line per open spec, OD-2); blocking v1; wanted for v1; known gaps; out of scope; join protocol coverage. Historical entries keep their `doc-versions: historical` markers.

State transitions: `planned → in progress → shipped`; `in progress ↔ blocked`; any → `out of scope` only on a maintainer decision.

## Stale fact record (`stale-facts.md`, review aid)

page (repo and path), old value, new value, confirming source (file:line, command output or spec). One record per correction (FR-012).
110 changes: 110 additions & 0 deletions specs/024-docs-feature-list-refresh/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Implementation Plan: Documentation Refresh, Feature Catalog, and Roadmap Status

**Branch**: `claude/project-thread-6pzhf7` | **Date**: 2026-10-12 | **Spec**: [spec.md](./spec.md)

**Input**: Feature specification from `specs/024-docs-feature-list-refresh/spec.md`

## Summary

Write a root `FEATURES.md` that lists every Gameplane capability, one row per capability, grouped by area, each with an evidence-based maturity label, its install default and a docs link. Mirror it as a website docs page and add a CI check that fails when the two drift. Refresh `docs/roadmap.md` (and the website roadmap page) to the current release, with what shipped in `v0.3.0` and since, and one line per open spec. Sweep the README, `docs/`, component READMEs, the module README and the website docs for stale facts. Website changes are docs text only. Research: [research.md](./research.md).

## Technical Context

**Language/Version**: Markdown (GFM) in the main and module repos; MDX in the website (Astro, strict TypeScript); Bash + awk for the sync check

**Primary Dependencies**: existing doc gates `hack/check-links.sh`, `hack/check-doc-versions.sh`; website content collection schema `src/content.config.ts` and nav `src/lib/docs-nav.ts`; GitHub Actions `ci.yaml` `docs and repository checks` job

**Storage**: N/A

**Testing**: fixture tests `hack/test-check-features-sync.sh` (`make test-features-sync`) in CI; existing `make check-links`, `make check-doc-versions` in CI; website CI `npm run lint`, `check`, `build`. No `test/e2e/` test: Principle I docs exception (OD-4).

**Target Platform**: GitHub (rendered Markdown), GitHub Pages website, GitHub Actions `ubuntu-latest`

**Project Type**: documentation plus one repository tooling script

**Performance Goals**: sync check runs in a few seconds inside the existing 10-minute docs job

**Constraints**: no doc gate relaxed (FR-011); competitor comparison columns unchanged (FR-014); CHANGELOG not rewritten; no `.pen` edits and no landing page change (OD-3); only compile/build checks locally (rule 8); submodule pointers bumped only after their PRs merge

**Scale/Scope**: about 100 to 150 catalog rows across ~18 areas; 22 `docs/*.md` files, root README, 4 component READMEs, the module README, ~90 website docs pages (only those carrying stale facts change, plus new `features.mdx` and `roadmap.mdx`); 6 open specs on the roadmap

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

| Principle | Status | Notes |
|---|---|---|
| I. E2E-Tested Delivery | PASS-WITH-JUSTIFICATION | Docs feature plus a CI-only text check. valgul ruled OD-4 (2026-10-12): no Go e2e test; the spec 012 docs exception applies, verified by the sync check's fixture tests and the existing doc gates in CI (see Complexity Tracking). |
| II. Design-First | PASS | No dashboard change. Website change is docs-page text only (OD-3); a new docs page is frontmatter-only per the website CLAUDE.md, so no `website.pen` change. No `.pen` file is read or touched. |
| III. Ecosystem Best Practice | PASS | Bash script follows the sibling doc gates; no suppressions; no lint config change. |
| IV. Spec-Driven | PASS | spec → clarify → plan done; tasks next. No module behaviour changes, so no `specs.md` updates. Archive to `done_024` after all PRs merge. |
| V. Delegate | PASS | Inventory and stale-fact sweep run as a Workflow: one `haiku` scout per area/fact class writes rows and evidence, one `sonnet` reviewer checks the combined diff against sources; every `agent()` sets `model`. |
| VI. CI Bears the Load | PASS | Sync check, its fixtures and doc gates are verified in CI only. Locally: website `npm run build`/`check` only. |

## Project Structure

### Documentation (this feature)

```text
specs/024-docs-feature-list-refresh/
├── spec.md
├── OPEN-DECISIONS.md
├── plan.md # this file
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ ├── features-catalog.md
│ └── features-sync-check.md
├── checklists/requirements.md
├── feature-evidence.md # implementation output: evidence per catalog row
├── stale-facts.md # implementation output: one record per correction
└── tasks.md # /speckit-tasks
```

### Source files touched

```text
GameplanePanel/Gameplane
├── FEATURES.md # NEW catalog (OD-1)
├── README.md # stale facts; Features → summary + link
├── docs/roadmap.md # status refresh (OD-2)
├── docs/*.md # stale-fact fixes where found
├── audit-syslog-bridge/README.md, containers/README.md,
│ mcp-server/README.md, telemetry-receiver/README.md
├── hack/check-features-sync.sh # NEW (FR-015)
├── hack/test-check-features-sync.sh # NEW fixture runner
├── hack/testdata/check-features-sync/{pass,fail}/ # NEW fixtures
├── hack/check-links.sh, hack/check-doc-versions.sh # add FEATURES.md to audited lists
├── Makefile # check-features-sync, test-features-sync, lint
├── .github/workflows/ci.yaml # docs job: init website submodule, run check; path filter
└── website, modules # submodule pointer bumps (after their PRs merge)

GameplanePanel/website
├── src/content/docs/features.mdx # NEW mirror page
├── src/content/docs/roadmap.mdx # status refresh
└── src/content/docs/*.mdx # stale-fact fixes where found

GameplanePanel/module
└── README.md # only if module list/count is stale
```

**Structure Decision**: no new code project; one Bash tool joins the existing `hack/` doc gates, and content changes land in the three existing repos.

## Delivery

1. Spec docs PR (spec, plan, tasks) to `master`.
2. Draft `FEATURES.md`, `feature-evidence.md` and `stale-facts.md` on the main branch (not yet merged).
3. Module repo PR if needed; website PR with `features.mdx` copied from the draft catalog, roadmap page and stale fixes. Both merge first.
4. Main repo PR: everything else plus both pointer bumps. CI runs the sync check against the merged website page.
5. Archive `specs/024-…` to `specs/done_024-…` after merge.

Coordination: spec 023 is reshaping CI job selection; whichever lands second maps the new files into the other's structure (research R10).

## Complexity Tracking

| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| Principle I exception (OD-4, ruled 2026-10-12) | The feature changes no runtime path: catalog, roadmap and doc fixes describe shipped code, and the sync check is a repo lint that has no cluster behaviour to exercise. Verification is the fixture tests (every mismatch kind rejected, in-sync accepted) plus the existing doc gates in CI. | A Go e2e test in `test/e2e/` would boot a kind cluster to run a text comparison; it would test nothing the fixture tests do not. Same reasoning as `specs/done_012-docs-refresh-and-outreach/plan.md`. |

**Constitution re-check (post-Phase 1)**: Principles I–VI satisfied; the Principle I exception is ruled (OD-4) and recorded above. No other violations.
19 changes: 19 additions & 0 deletions specs/024-docs-feature-list-refresh/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Quickstart: validating spec 024

Local work is limited to compile/build checks (CLAUDE.md rule 8; website: `npm run build` / `npm run check` only). Everything below marked **CI** is verified by the pushed PR's CI run, not locally.

## Prerequisites

- Main repo branch with `FEATURES.md`, refreshed docs and the sync check.
- Website PR merged to `main`, and the main repo `website` pointer bumped to it.

## Scenarios

1. **Catalog is complete and correct (SC-001)**: pick 10 random rows of `FEATURES.md`; for each, confirm the matching record in `feature-evidence.md` names real evidence (bucketed e2e test or `none`, default source) and that the label follows [data-model.md](./data-model.md) validation; follow the Docs link and confirm it documents the capability.
2. **Roadmap matches the specs (SC-002)**: for every folder in `specs/` without `done_`, find its line in the "In progress" section of `docs/roadmap.md`; compare with that spec's `tasks.md` on `master` on the status date.
3. **No stale counts (SC-003)**: `grep -rn "30 ready\|30 game\|30 templates" README.md docs website/src` from the GP root (website submodule initialised) finds nothing; every module count equals the number of game directories in the module repo; every registry count equals the registries in the code. Each fix is listed in `stale-facts.md`.
4. **Repo and website agree (SC-004)** **CI**: `make check-features-sync` passes in the `docs and repository checks` job; the website roadmap page and `docs/roadmap.md` list the same items with the same statuses (manual comparison).
5. **Sync check catches drift (SC-005)** **CI**: `make test-features-sync` passes, meaning every `fail/` fixture in [contracts/features-sync-check.md](./contracts/features-sync-check.md) is rejected with its expected message and every `pass/` fixture is accepted.
6. **Existing doc gates still pass (FR-011)** **CI**: `make check-links` and `make check-doc-versions` pass with `FEATURES.md` added to their audited lists; no rule in either script was relaxed (review the diff).
7. **Website builds** (local allowed): `npm run build` in the website repo succeeds and the Features page appears in the Reference → Releases & Roadmap sidebar group. Website CI (`npm run lint`, `check`, `build`) is green on its PR.
8. **README points to the catalog (US3)**: README Features section is a short summary with a link to `FEATURES.md`; the comparison table's competitor columns are unchanged (`git diff` shows only Gameplane-column edits).
Loading
Loading