# Forum skills

Task playbooks for working on the GCC **Forum and Help Center** (`app/Forum/`).
Each folder holds a `SKILL.md` with YAML frontmatter (`name`, `description`),
matching the convention used in `app/Admin/Skills/`, `app/api/Skills/` and
`app/.claude/skills/`.

These are **procedures**. The reference material they lean on lives in
[`../docs/`](../docs/), and the standing rules are in
[`../CLAUDE.md`](../CLAUDE.md).

| Skill | Use it when |
|---|---|
| [`forum-section`](forum-section/SKILL.md) | Adding, renaming, regrouping or retiring a section on either board |
| [`forum-access-rule`](forum-access-rule/SKILL.md) | Changing who can browse, create, read or reply — **read this before touching any permission** |
| [`forum-acl-section`](forum-acl-section/SKILL.md) | Making a level configurable: registering a capability in `aclRegistry()` and gating on `aclCap()` |
| [`forum-page`](forum-page/SKILL.md) | Adding a page or changing a view: routing, chrome, board-awareness, output encoding |
| [`forum-migration`](forum-migration/SKILL.md) | Any schema change — new `forum_*` table, index, or section seed |
| [`forum-verify`](forum-verify/SKILL.md) | **Before every commit** — drive the real pages, assert both directions of every gate, clean up |

## Suggested order

Adding a section → `forum-migration` (the seed row), then `forum-section`, then
`forum-verify`.

Adding a page → `forum-page`, then `forum-verify`.

Anything touching permissions → `forum-access-rule` **first**, then
`forum-verify` with assertions in both directions.

## The three things to internalise

**1. `he_type` is the source of truth for access.** `forum_section` holds
placement and presentation only. If you find yourself putting an access level in
`forum_section`, stop — you are creating a second answer to a question that must
have one. The one sanctioned override is `gcc.forum_acl`, read through
`aclLevel()` alongside `he_type` — `he_type` says where a level *starts*, that
table says where it has been *moved to*, and both go through the same function
so they cannot drift.

**2. Viewing, creating and reading are three different permissions.** A player
who cannot browse Abuse › Re-Activate must still be able to file an appeal there
and read the reply. Announcements carry `access = 5` and are readable by
everyone — that 5 is who may *post*. See
[`../docs/ACCESS-CONTROL.md`](../docs/ACCESS-CONTROL.md).

**3. Nothing here owns a post.** The board reads `he`/`hef`/`he2`/`hef2` in
place. Every `forum_*` table is additive; drop them all and no thread is lost.
A change that needs to alter or delete a legacy row is the wrong change.

## Two standing rules

- **Every `.sql` file starts with a `USE`** (or fully qualifies every object).
  Forum tables are in `gcc`; the folder they live in is `app/Admin/sql/`, which
  biases you toward `gcc_admin`.
- **Never commit a scratch harness.** `git status --short app/Forum` before
  every commit.

## Related skills elsewhere

- `app/Admin/Skills/` — the staff panel. Similar shape, separate application and
  auth; do not carry assumptions across.
- `app/api/Skills/` — the public player API. Its `USE`-in-every-migration rule
  is the same one.
- `app/.claude/skills/game-changelog` — a player-facing forum change belongs in
  the public changelog.
- `app/.claude/skills/patch-forum-threads` — the auto-generated Help Center
  threads behind patch notes (`ca=200`), driven by `s_patch_threads.cfm`. That
  writes into `he` type 200, which this board now renders.
