build-binaries / build-binaries (push) Successful in 2m27s
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>
113 lines
6.9 KiB
Markdown
113 lines
6.9 KiB
Markdown
# Issue tracker: Gitea (via tea)
|
|
|
|
Issues for this repo live in Gitea at `git.westgate.pw`, repo
|
|
`ShadowsOverWestgate/sow-tools`. Use the `tea` CLI for all operations —
|
|
`gh` does not work here. For anything `tea` lacks a subcommand for, use
|
|
`tea api <endpoint>` (Gitea's API mirrors GitHub's closely).
|
|
|
|
Authenticate with your own `tea` login (`tea login add`); never commit tokens
|
|
or tea config into this repo. Note Gitea blocks self-review, so approving a PR
|
|
needs a different account than the one that opened it.
|
|
|
|
## Where work lives
|
|
|
|
Markdown in this repo is **reference, law, or an ADR — nothing else**
|
|
(`sow-codebase` ADR-0001). Four homes, no overlap:
|
|
|
|
- **Live work** → wayfinder maps + Gitea issues. Closeable, assignable,
|
|
queryable. Never a markdown file.
|
|
- **Settled decisions** → ADR files in `docs/adr/`. Immutable, findable, never
|
|
closed, never edited — only superseded by a later ADR pointing back. When an
|
|
issue ends in a durable decision, write the ADR, then close the issue
|
|
pointing at it. Decisions spanning repos go to `sow-platform/docs/adr/`.
|
|
- **Standing law** → `DOCTRINE.md`, `AGENTS.md`, `CONTEXT.md`. Rules that are
|
|
always true and vocabulary everyone shares — not the record of one decision.
|
|
- **Current-state reference** → docs describing what the code does now, kept
|
|
honest by review touching them.
|
|
|
|
Anything else — implementation plans, design specs, concepts, handoffs,
|
|
progress trackers, scratch — is **process**. It does not live in this repo. It
|
|
lives in a Gitea issue or a wayfinder map, where it can be assigned, closed,
|
|
and superseded. Small tasks need no written plan at all.
|
|
|
|
Deleting a process doc is not destroying history — `git log -- <path>` recovers
|
|
it. But *unfinished intent* (a design never built, an open question still
|
|
wanted) is live, not history: harvest it to a Gitea issue before deleting.
|
|
|
|
`sow-docs` is deprecated and read-only. Never add to it, never send work there.
|
|
|
|
## Which repo gets the issue
|
|
|
|
Issues follow ownership. File the issue in the repo that **owns the work** —
|
|
see the Repo/Owns/Produces table in the workspace root `AGENTS.md`. Standing
|
|
in one repo is not a reason to file there.
|
|
|
|
If work spans repos, file it in the repo that owns the *outcome* and reference
|
|
the others from it. A wrong-repo issue is a routing bug, not a filing
|
|
preference — move it.
|
|
|
|
## Conventions
|
|
|
|
- **Create an issue**: `tea issues create --title "..." --description "..."`
|
|
- **Read an issue**: `tea issues <number>` and
|
|
`tea api repos/ShadowsOverWestgate/sow-tools/issues/<number>/comments` for comments.
|
|
- **List issues**: `tea issues list --state open` (add `--labels ...` to filter).
|
|
- **Comment**: `tea comment <number> "..." </dev/null`
|
|
Always redirect stdin. `tea` reads stdin to EOF and appends it to the body,
|
|
so any non-interactive shell (every agent) hangs forever without
|
|
`</dev/null`. Same trap on `tea issues create --description` and
|
|
`tea pr create`.
|
|
- **Apply / remove labels**: `tea issues edit <number> --add-labels "Kind/Bug"`
|
|
(and `--remove-labels`). This handles org-level labels (`Kind/*`,
|
|
`Priority/*`, `Reviewed/*`, `Status/*`) from tea 0.15 onwards. On 0.14 it did
|
|
not: name resolution searched only this repo's own label set, so an org label
|
|
matched nothing and the command exited 0, printed the issue, and changed
|
|
nothing. Upstream fixed it in v0.15 (`modules/task/labels.go` also queries
|
|
`ListOrgLabels`). Note `tea labels` lists repo labels only and will not show
|
|
you the org set — `tea api orgs/ShadowsOverWestgate/labels` does.
|
|
- **`tea api` needs a token in the login; SSH auth is not enough.** It sends
|
|
only the login's `token:` field and does not sign requests with your SSH key,
|
|
so an SSH-key-only login gets `{"message":"token is required"}` on every call
|
|
that needs auth. Reads against these public repos still succeed anonymously,
|
|
which hides the gap until the first write. Add a token to the login in
|
|
`~/.config/tea/config.yml` (Settings > Applications; `write:issue` covers
|
|
labels, comments and dependencies) and `tea api` works for reads and writes
|
|
alike. The `tea issues` / `tea pr` subcommands authenticate either way, so
|
|
they keep working with no token at all — that asymmetry is what makes this
|
|
confusing to diagnose.
|
|
- **Verify every label change by re-reading it.** A label command exiting 0 is
|
|
not evidence it applied — that is exactly how the 0.14 silent no-op above hid
|
|
for so long, and assuming otherwise has already cost one investigation
|
|
several wrong turns. Read the resulting set back with
|
|
`tea api repos/ShadowsOverWestgate/sow-tools/issues/<number>` and check its
|
|
`labels` field, or `tea issues ls -o json`. The read-back reflects the write
|
|
immediately; if it comes back empty, the write genuinely failed. Do not
|
|
explain an empty read-back away as replication lag.
|
|
- **Close**: `tea issues close <number>`
|
|
|
|
`tea` infers the repo from the git remote when run inside the clone.
|
|
Gitea shares one number space across issues and PRs.
|
|
|
|
## Pull requests as a triage surface
|
|
|
|
**PRs as a request surface: no.**
|
|
|
|
## When a skill says "publish to the issue tracker"
|
|
|
|
Create a Gitea issue with `tea issues create`.
|
|
|
|
## When a skill says "fetch the relevant ticket"
|
|
|
|
Run `tea issues <number>` plus the comments API call above.
|
|
|
|
## Wayfinding operations
|
|
|
|
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
|
|
|
|
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `tea issues create --title "..." --description "..." --labels wayfinder:map`.
|
|
- **Child ticket**: this Gitea instance (v1.27) has no native sub-issue hierarchy, so a child issue carries `Part of #<map>` at the top of its description, and is also added to a task list in the map body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
|
|
- **Blocking**: Gitea's **native dependencies API** — the canonical, UI-visible representation (shows as "Depends on" / "Blocks" on the issue page). Add an edge with `tea api -X POST repos/ShadowsOverWestgate/sow-tools/issues/<child>/dependencies -f owner=ShadowsOverWestgate -f repo=sow-tools -F index=<blocker>`, where `<blocker>` is the blocker's issue **index** (its `#number` — Gitea's dependency API takes the index directly, unlike GitHub's numeric database id). Check status with `tea api repos/ShadowsOverWestgate/sow-tools/issues/<child>/dependencies` (GET) — a ticket is unblocked when every returned issue's `state` is `closed`.
|
|
- **Frontier query**: list the map's open children (`tea issues list --state open`, keep the ones whose description contains `Part of #<map>`), drop any with an open dependency (per the GET above) or an assignee; first in map order wins.
|
|
- **Claim**: `tea issues edit <n> --add-assignees <username>` — the session's first write.
|
|
- **Resolve**: `tea comment <n> "<answer>" </dev/null`, then `tea issues close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.
|