From ed6945d308cd9b9a0e58c7acc18534dc6afd619f Mon Sep 17 00:00:00 2001 From: vickydotbat Date: Fri, 24 Jul 2026 18:43:31 +0000 Subject: [PATCH] Adopt workspace-wide agent standards; retire sow-docs (#51) Part of the workspace-wide standards rollout. Establishes where work lives (issues vs ADRs vs standing law), scaffolds `docs/agents/` for the engineering skills, and adopts ADR-0001 locally. See `sow-platform` ADR-0021 for the `sow-docs` retirement.Reviewed-on: https://git.westgate.pw/ShadowsOverWestgate/sow-tools/pulls/51 Reviewed-by: xtul Co-authored-by: vickydotbat --- AGENTS.md | 18 ++++ .../0001-markdown-is-reference-or-law-only.md | 55 ++++++++++++ ...02-sow-tools-becomes-the-crucible-suite.md | 12 +++ ...t-standalone-shims-fail-closed-scaffold.md | 29 +++++++ ...built-oci-images-start-server-side-with.md | 24 ++++++ docs/agents/domain.md | 51 +++++++++++ docs/agents/issue-tracker.md | 84 +++++++++++++++++++ docs/agents/triage-labels.md | 15 ++++ 8 files changed, 288 insertions(+) create mode 100644 docs/adr/0001-markdown-is-reference-or-law-only.md create mode 100644 docs/adr/0002-sow-tools-becomes-the-crucible-suite.md create mode 100644 docs/adr/0003-crucible-binary-contract-standalone-shims-fail-closed-scaffold.md create mode 100644 docs/adr/0004-nix-built-oci-images-start-server-side-with.md create mode 100644 docs/agents/domain.md create mode 100644 docs/agents/issue-tracker.md create mode 100644 docs/agents/triage-labels.md diff --git a/AGENTS.md b/AGENTS.md index 4446b7a..1f6a7f5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -87,3 +87,21 @@ make smoke # assert fail-closed contract ## Tests Tests must survive harmless changes to constants, defaults, wording, ordering, fixture data, and internal implementation details. A test that fails merely because a basic value changed is usually a bad test. Only assert exact values when the value is part of a documented public contract, external protocol, compatibility requirement, security rule, migration, or business rule. + +## Agent skills + +### Issue tracker + +Issues live in Gitea at git.westgate.pw (`ShadowsOverWestgate/sow-tools`), managed with the `tea` CLI. Issues follow ownership — file work in the repo that owns it, not the one you happen to be standing in. See `docs/agents/issue-tracker.md`. + +### Triage labels + +Default label vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`). See `docs/agents/triage-labels.md`. + +### Domain docs + +Single-context: `CONTEXT.md` at the repo root plus `docs/adr/`. See `docs/agents/domain.md`. + +### Where work lives + +Markdown here is **reference, law, or an ADR — nothing else** (`sow-codebase` ADR-0001). Live work -> wayfinder maps + Gitea issues (closeable, assignable, queryable). Settled decisions -> ADR files in `docs/adr/` (immutable, never closed, only superseded). Standing law -> `DOCTRINE.md` / `AGENTS.md` / `CONTEXT.md`. Current-state reference -> docs describing what the code does now. Everything else — plans, specs, concepts, handoffs, trackers — is process: it belongs in a Gitea issue, not a file. Harvest unfinished intent to an issue before deleting a process doc. `sow-docs` is deprecated and read-only. diff --git a/docs/adr/0001-markdown-is-reference-or-law-only.md b/docs/adr/0001-markdown-is-reference-or-law-only.md new file mode 100644 index 0000000..940b6d2 --- /dev/null +++ b/docs/adr/0001-markdown-is-reference-or-law-only.md @@ -0,0 +1,55 @@ +# ADR-0001: Markdown in this repo is reference, law, or an ADR — nothing else + +- **Status:** Accepted +- **Date:** 2026-07-24 +- **Origin:** Adopted workspace-wide from `sow-codebase` ADR-0001, which records + the full context (a `docs/` tree that had grown to 434 files, ~27MB, most of + it dead process artifacts). This repo adopts the same law so the rule is + local, not a cross-repo reference. + +## Context + +Markdown that *claims to describe current state or a plan* rots, because +reality diverges and nobody edits the file. Markdown that claims neither — a +dated, immutable decision record, or a standing rule — does not rot. + +Two different things get conflated: + +- **Rationale** — why a system is shaped the way it is. Worth keeping. +- **Process artifacts** — plans, specs, concepts, handoffs, trackers. A record + of how work happened, not what is true now. + +Left unchecked, every completed effort leaves its planning behind and the repo +accumulates a "historical" pile that agents and humans must route around to +find the few live docs. + +## Decision + +Markdown may exist in this repo only as one of three genres: + +1. **Current-state reference** — describes what the code does now, kept honest + by code review touching it. +2. **Standing law** — `DOCTRINE.md`, root and folder-scoped `AGENTS.md`, + `CONTEXT.md`. States rules and vocabulary, not plans. +3. **Immutable decision record** — ADRs under `docs/adr/`. Append-only; never + edited, only superseded by a later ADR that points back. + +Anything else — implementation plans, design specs, concepts, handoffs, +progress trackers, scratch — is **process** and does not live in the repo. It +lives in Gitea issues and wayfinder maps, where it can be assigned, closed, and +superseded. Small tasks need no written plan at all. + +Deleting a process document is not destroying history: `git log -- ` +recovers it. The exception is *unfinished intent* (a design never built, an +open question still wanted) — that is live, not history, and must be harvested +to a Gitea ticket before its file is deleted. A citation from a living doc or +from code must be resolved before the cited file is deleted. + +## Consequences + +- The documentation map lists only current truth; there is no "historical" pile + to route around. +- No agent, under any plugin or skill, writes process-markdown into the repo. + The rule is plugin-agnostic on purpose — it binds the agent, not a named tool. +- History of deleted process docs is in git; unfinished intent is in the issue + tracker; rationale is in ADRs and law. Each thing has exactly one home. diff --git a/docs/adr/0002-sow-tools-becomes-the-crucible-suite.md b/docs/adr/0002-sow-tools-becomes-the-crucible-suite.md new file mode 100644 index 0000000..c62ee70 --- /dev/null +++ b/docs/adr/0002-sow-tools-becomes-the-crucible-suite.md @@ -0,0 +1,12 @@ +# ADR-0002: `sow-tools` becomes the Crucible suite + +- **Status:** Accepted +- **Date:** 2026-06-11 +- **Migrated from:** `sow-docs` `07-decisions-log.md` entry **D11**, on the + retirement of `sow-docs`. Content is the original decision, unchanged. + +- **Decision:** Rename the future toolchain surface to Crucible: one Go module, + multiple `cmd/` binaries, plus a dispatcher so wrapper commands can stay + stable. +- **Rationale:** Depot, HAK, module, topdata, and wiki tooling share internals + but have different command surfaces. One module avoids premature repo splits. diff --git a/docs/adr/0003-crucible-binary-contract-standalone-shims-fail-closed-scaffold.md b/docs/adr/0003-crucible-binary-contract-standalone-shims-fail-closed-scaffold.md new file mode 100644 index 0000000..151ebd3 --- /dev/null +++ b/docs/adr/0003-crucible-binary-contract-standalone-shims-fail-closed-scaffold.md @@ -0,0 +1,29 @@ +# ADR-0003: Crucible binary contract: standalone shims, fail-closed scaffold, no committed binaries + +- **Status:** Accepted +- **Date:** 2026-06-11 +- **Migrated from:** `sow-docs` `07-decisions-log.md` entry **D19**, on the + retirement of `sow-docs`. Content is the original decision, unchanged. + +- **Decision:** Phase 5 builds `migration/sow-tools` (Crucible, D11) as a + multi-binary Go scaffold: + - One `crucible` dispatcher plus standalone `crucible-{depot,hak,module,topdata,wiki}` + binaries sharing one registry (`internal/dispatch`). The dispatcher is for + humans/CI; the **standalone shims are canonical for consumers** so wrapper + scripts resolve a single-token command and `"$builder" args` quoting stays + correct. + - Consumer resolution order: explicit env override + (`$SOW_MODULE_BUILD`/`$SOW_TOPDATA_BUILD`/`$CRUCIBLE`) → `crucible-` → + legacy `sow--build`. CI runs inside the pinned `crucible:` image. + - Every builder is **unwired** in the scaffold and fails closed (exit 70); + it never fakes an artifact. The `internal/` logic is migrated from + `gitea/sow-tools` by the operator at cutover (hard rule: no source + transplant by tooling). + - **Binaries are never committed** — they are CI artifacts / image layers. + Retires the committed `nwn-tool` / `tools/sow-toolkit`. + - Builders take `NWN_ROOT` only via explicit env/flag; no `$HOME` defaulting. +- **Rationale:** Locks the command surface, container, and CI shape so migrated + logic drops into a stable frame; aligns the three artifact repos onto one + Crucible contract while keeping back-compat with the pre-D11 skeletons. +- **Image name:** `registry.westgate.pw/deployment/crucible:` (the bare + `crucible:` is the local/dev tag). diff --git a/docs/adr/0004-nix-built-oci-images-start-server-side-with.md b/docs/adr/0004-nix-built-oci-images-start-server-side-with.md new file mode 100644 index 0000000..23bd2c8 --- /dev/null +++ b/docs/adr/0004-nix-built-oci-images-start-server-side-with.md @@ -0,0 +1,24 @@ +# ADR-0004: Nix-built OCI images start server-side with Crucible; local Anvil images deferred + +- **Status:** Accepted +- **Date:** 2026-06-12 +- **Migrated from:** `sow-docs` `07-decisions-log.md` entry **D29**, on the + retirement of `sow-docs`. Content is the original decision, unchanged. + +- **Decision:** Introduce Nix-built OCI images as an artifact-production option, + starting with `sow-tools`/Crucible in server-side CI. `sow-tools` will grow a + Nix-built `crucible` package plus `crucible-image`; PR CI builds/smokes it and + `main` publishes the normal pinned OCI image + `registry.westgate.pw/deployment/crucible:`. `docker/Dockerfile` stays during + parity and as the client-compatible fallback. +- **Local rule:** Nix users may get optional wrappers that provide tools and + call the existing Dockerfiles for local Anvil/NWServer testing. A true + `nix build .#nwserver-test-image` is explicitly deferred until real + `sow-codebase/src` exists and the Dockerfile image is proven. +- **Rationale:** Server-side image build shape is harder to change once deploy + promotion and registry gates are active, so prove Nix image builds before + cutover. Crucible is the lowest-risk pilot because it is a Go toolchain image; + NodeBB and Anvil/NWServer depend more heavily on upstream container filesystem + semantics. +- **Non-goals:** no source builds in `sow-platform`; no `nix-sidecar` or + Kubernetes-style runtime cache layer; no removal of client Dockerfiles. diff --git a/docs/agents/domain.md b/docs/agents/domain.md new file mode 100644 index 0000000..b548c53 --- /dev/null +++ b/docs/agents/domain.md @@ -0,0 +1,51 @@ +# Domain Docs + +How the engineering skills should consume this repo's domain documentation when exploring the codebase. + +## Before exploring, read these + +- **`CONTEXT.md`** at the repo root, or +- **`CONTEXT-MAP.md`** at the repo root if it exists — it points at one `CONTEXT.md` per context. Read each one relevant to the topic. +- **`docs/adr/`** — read ADRs that touch the area you're about to work in. In multi-context repos, also check `src//docs/adr/` for context-scoped decisions. + +If any of these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The `/domain-modeling` skill (reached via `/grill-with-docs` and `/improve-codebase-architecture`) creates them lazily when terms or decisions actually get resolved. + +## File structure + +Single-context repo (most repos): + +``` +/ +├── CONTEXT.md +├── docs/adr/ +│ ├── 0001-event-sourced-orders.md +│ └── 0002-postgres-for-write-model.md +└── src/ +``` + +Multi-context repo (presence of `CONTEXT-MAP.md` at the root): + +``` +/ +├── CONTEXT-MAP.md +├── docs/adr/ ← system-wide decisions +└── src/ + ├── ordering/ + │ ├── CONTEXT.md + │ └── docs/adr/ ← context-specific decisions + └── billing/ + ├── CONTEXT.md + └── docs/adr/ +``` + +## Use the glossary's vocabulary + +When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, a test name), use the term as defined in `CONTEXT.md`. Don't drift to synonyms the glossary explicitly avoids. + +If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/domain-modeling`). + +## Flag ADR conflicts + +If your output contradicts an existing ADR, surface it explicitly rather than silently overriding: + +> _Contradicts ADR-0007 (event-sourced orders) — but worth reopening because…_ diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md new file mode 100644 index 0000000..f0be865 --- /dev/null +++ b/docs/agents/issue-tracker.md @@ -0,0 +1,84 @@ +# 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 ` (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 -- ` 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 ` and + `tea api repos/ShadowsOverWestgate/sow-tools/issues//comments` for comments. +- **List issues**: `tea issues list --state open` (add `--labels ...` to filter). +- **Comment**: `tea comment "..."` +- **Apply / remove labels**: `tea api --method PATCH` on the issue, or + `tea api repos/ShadowsOverWestgate/sow-tools/issues//labels` endpoints. +- **Close**: `tea issues close ` + +`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 ` 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 #` at the top of its description, and is also added to a task list in the map body. Labels: `wayfinder:` (`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//dependencies -f owner=ShadowsOverWestgate -f repo=sow-tools -F index=`, where `` 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//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 #`), drop any with an open dependency (per the GET above) or an assignee; first in map order wins. +- **Claim**: `tea issues edit --add-assignees ` — the session's first write. +- **Resolve**: `tea comment ""`, then `tea issues close `, then append a context pointer (gist + link) to the map's Decisions-so-far. diff --git a/docs/agents/triage-labels.md b/docs/agents/triage-labels.md new file mode 100644 index 0000000..d8bfed9 --- /dev/null +++ b/docs/agents/triage-labels.md @@ -0,0 +1,15 @@ +# Triage Labels + +The skills speak in terms of five canonical triage roles. This file maps those roles to the actual label strings used in this repo's issue tracker (Gitea — see `issue-tracker.md` for how to apply labels with `tea`). + +| Label in mattpocock/skills | Label in our tracker | Meaning | +| -------------------------- | -------------------- | ---------------------------------------- | +| `needs-triage` | `needs-triage` | Maintainer needs to evaluate this issue | +| `needs-info` | `needs-info` | Waiting on reporter for more information | +| `ready-for-agent` | `ready-for-agent` | Fully specified, ready for an AFK agent | +| `ready-for-human` | `ready-for-human` | Requires human implementation | +| `wontfix` | `wontfix` | Will not be actioned | + +When a skill mentions a role (e.g. "apply the AFK-ready triage label"), use the corresponding label string from this table. + +Edit the right-hand column to match whatever vocabulary you actually use.