Files
sow-tools/docs/agents/triage-labels.md
T
archvillainette 87feaf96b7
build-binaries / build-binaries (push) Successful in 2m27s
fix(wiki): purge through the plugin page actions and count reset deletions (#101)
Closes #99. Closes #100.

## #99 — purge used the core topic API

`deploy-wiki --stale-policy purge` deleted pages with `DELETE /api/v3/topics/{tid}`. On a NodeBB running `nodebb-plugin-westgate-wiki` that is refused for topics in wiki categories — revision history is plugin-owned — so every purge failed with HTTP 400 and the deploy exited 1.

Purge now goes through the plugin's own page actions:

1. `PUT /api/v3/plugins/westgate-wiki/page/tombstone`
2. `DELETE /api/v3/plugins/westgate-wiki/page/hard-purge`

in that order, because a page must be tombstoned before it can be purged. A page that is already gone answers 404 on the tombstone and is treated as a completed purge, as before.

**Archive was audited and needs no change.** It rewrites the page through `updatePost`, which is an ordinary post edit the plugin allows; only delete, restore, and purge are reserved to the page actions.

**The wiki home topic.** A namespace reset enumerates every topic in the category, including the home page, which the plugin excludes from tombstone, restore, and purge alike. Those are now skipped instead of aborting the reset. NodeBB answers 403 for that and for a token without purge privileges alike, and the response body cannot tell the two apart — what can is scope. A category where nothing at all could be deleted is a privilege problem, so the run still fails there rather than writing a manifest that claims a fresh start over pages that are all still present.

**The fakes.** Every fake NodeBB in `wiki_deploy_test.go` now goes through one constructor that refuses native topic mutation exactly the way the plugin does. The old fakes answered the core API, which is how a purge path that has never worked in production stayed green in CI.

## #100 — `stale: 0` above `purged: 1213`

The reset purge never went through stale computation, so the preview reported zero deletions on a run that would delete every topic in the managed categories.

Reset deletions are now counted in `stale`, which is the number callers word their destructive-policy warning around, and the summary gains a line naming the reset and how many of its targets the manifest has no record of writing:

```
stale:       1213
purged:      1213
namespace reset: 1213 (unrecognized: 13)
  unrecognized pages were not written by this deployer; recreating them is not possible
```

The unrecognized subset is the number worth surfacing, since those are the deletions a re-seed cannot undo. The `--reset-managed-namespaces` help text now says plainly that the flag deletes every page in the managed categories, not only the ones this deployer wrote.

`DeployResult` is exported so the console reads named fields instead of eleven positional ints.

## Verification

`go vet ./...` and `go test ./...` pass. New tests cover the plugin purge order, the already-missing page, the skipped undeletable topic, the per-category privilege failure, and the reset counts.Reviewed-on: #101

Co-authored-by: vickydotbat <vickydotbat@tutamail.com>
2026-08-05 16:01:51 +00:00

4.9 KiB

Issue and PR labels

Labels are org-wide. They are defined once, for the whole ShadowsOverWestgate org, at https://git.westgate.pw/org/ShadowsOverWestgate/settings/labels, and every repo in the org can use them. Never create a per-repo copy of a label that already exists at org level.

The rule

Every issue and every pull request gets exactly one Kind/* label, at the moment it is created. Not later, not "when someone triages it". If you open it, you label it.

An issue with no Kind/* label is untriaged. That is the only meaning of "untriaged" here — there is no needs-triage label.

The other groups are optional, and each one is exclusive: an issue can carry at most one Priority/*, one Status/*, and one Reviewed/*. Gitea enforces this.

# always from inside the owning repo's clone
tea issues create --title "..." --description "..." --labels "Kind/Bug" </dev/null
tea pr create --title "..." --description "..." --labels "Kind/Feature" </dev/null

# add a label to something that already exists (needs tea >= 0.15 for org labels)
tea issues edit <n> --add-labels "Kind/Bug,Priority/High"

# read the result back — exit 0 is not evidence the label applied
tea api "repos/ShadowsOverWestgate/<repo>/issues/<n>"

tea api sends only the login's token: and never your SSH key, so on an SSH-only login every authenticated call fails with {"message":"token is required"} while anonymous reads still work. Add a token to ~/.config/tea/config.yml if you want the raw endpoints. tea issues edit needs no token.

Kind — what this is (pick exactly one)

Label Use it when
Kind/Bug Something that used to work, or is documented to work, does not
Kind/Feature New functionality that does not exist yet
Kind/Enhancement Existing functionality gets better, faster, or nicer
Kind/Documentation Docs, ADRs, runbooks, agent guides
Kind/Testing Tests, CI checks, contract scripts
Kind/Security Secrets, auth, permissions, hardening, a vulnerability

Bug vs Enhancement, when it is unclear: if the current behaviour is wrong, it is a bug. If the current behaviour is right but weak, it is an enhancement.

Priority — how urgent (optional, at most one)

Priority/Critical, Priority/High, Priority/Medium, Priority/Low.

Leave it off if you do not know. A wrong priority is worse than none.

Status — why it is not moving (optional, at most one)

Label Meaning
Status/Blocked Waiting on another issue, PR, or decision
Status/Need More Info Waiting on the reporter or on a human answer
Status/Abandoned Work started and stopped; nobody is on it

Reviewed — the verdict (optional, at most one)

Reviewed/Confirmed, Reviewed/Duplicate, Reviewed/Invalid, Reviewed/Won't Fix. Apply one of these when closing without a fix, so the reason survives.

Compat

Compat/Breaking — add it on top of the Kind/* label when the change breaks something that already works for a player, an operator, or another repo.

Workflow labels (repo-level, not org-level)

These live in the repo, not the org, and are orthogonal to the groups above:

  • ready-for-agent — the spec is complete; an AFK agent may pick this up. No label means it needs a human.
  • wayfinder:map, wayfinder:task, wayfinder:research, wayfinder:prototype, wayfinder:grilling — set by /wayfinder. Leave them alone unless you are running a wayfinder operation.
  • sow-nodebb also has package/* labels naming the plugin or theme a ticket touches.

When a skill names a label we do not have

Skills written elsewhere (mattpocock/skills and friends) use a different vocabulary. Translate it:

Skill says Do this here
needs-triage Nothing — no Kind/* label already means this
needs-info Status/Need More Info
ready-for-agent ready-for-agent
ready-for-human Nothing — absence of ready-for-agent means this
wontfix Reviewed/Won't Fix

Drift check

ops/checks/check-labels.sh in sow-platform runs nightly. It compares the live org labels to ops/policy/labels.yml and lists every open issue and PR in the org that does not have exactly one Kind/* label. That check is the enforcement; this file is the rule.