refactor!: drop the wiki and page layers

The plugin is issues and nothing else now. `skills/page` (the page-tree
domain) and `skills/wiki` (its bridge to a Gitea wiki) are gone, and
with them the issue domain's `wiki:` field — page titles were the only
thing that tied the two domains together, and a field the tracker has
no column for never came back from a pull anyway.

What is left is the shape AGENTS.md already claimed for the rest of the
repo: one domain, one bridge, one transport. The docs, the plugin
manifest, and tea-runner's skill table now say so too, and
test_payload_root walks the one script directory that remains.

Also removes openspec/config.yaml; nothing in the repo referenced it.

378 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
naudachu
2026-08-10 22:29:55 +05:00
parent 81119a3bd9
commit 5a8bd1c299
26 changed files with 53 additions and 2551 deletions
+1 -4
View File
@@ -3,8 +3,7 @@
Canonical format for every issue in this project, whether it ever reaches a
tracker or not. Designed to be unambiguous for both humans and LLMs: fixed
English section headers in a fixed order, verifiable acceptance criteria, one
issue = one deliverable. Source spec: the project wiki
([Issues-Workflow](https://git.noodles.cam/claude-skills/tea/wiki/Issues-Workflow)).
issue = one deliverable.
Nothing here depends on Gitea. How these files are mapped onto a tracker is the
sync layer's business — see `/tea:sync`.
@@ -42,7 +41,6 @@ labels: [type/task, tech/sql]
assignees: [naudachu]
milestone: v0.2
depends: [migrate-schema]
wiki: [Simple Chains/Ideas/Chain core]
origin: gitea
branch: feat/wire-sqlc
gitea: claude-skills/tea#42
@@ -64,7 +62,6 @@ url: https://git.noodles.cam/claude-skills/tea/issues/42
| `assignees` | domain | logins; may be empty |
| `milestone` | domain | title, or `none` |
| `depends` | domain | ids this issue depends on — **the authoritative graph** |
| `wiki` | domain | page **titles** this issue is written up in; may be empty. Titles, not URLs — a title is a name for a document and stays in this layer, a URL is tracker bookkeeping. `/tea:page` owns what those titles mean; `page_ls.py --titles` prints them. Set it with `issue_new.py --wiki "<title>"` (repeatable) or by editing the line. The tracker has no field for it, so it is never sent — and a pull, which merges nothing but checkbox state, does not bring it back |
| `origin` | domain | `local`, or the name of a tracker this also lives in |
| `gitea` | sync | the handle in that tracker: `owner/repo#N` |
| `branch` | sync | the tracker's branch link (Gitea `ref`); push fills an empty one with the current git branch, and never overwrites a filled one |
+4 -10
View File
@@ -25,7 +25,6 @@ domain has. The file name is the id:
assignees: [naudachu]
milestone: v0.2
depends: [migrate-schema]
wiki: [Simple Chains/Ideas/Chain core]
origin: gitea
gitea: owner/repo#42
synced: 2026-08-07T18:40:00Z
@@ -115,8 +114,8 @@ ISSUE_ROOT = store_root()
# Domain-owned metadata, in render order. Foreign keys render after these,
# sorted, so the sync layer can add fields without touching this list.
DOMAIN_KEYS = ["id", "state", "labels", "assignees", "milestone", "depends",
"wiki", "origin"]
LIST_KEYS = {"labels", "assignees", "depends", "wiki"}
"origin"]
LIST_KEYS = {"labels", "assignees", "depends"}
STATES = ("open", "closed")
# `origin` is "does this issue exist anywhere but here" — a fact about the
@@ -249,7 +248,7 @@ class Issue(object):
"""One unit of work. `extra` holds metadata this layer does not own."""
def __init__(self, id="", title="", body="", state="open", labels=None,
assignees=None, milestone="", depends=None, wiki=None,
assignees=None, milestone="", depends=None,
origin=LOCAL, extra=None):
self.id = id
self.title = title
@@ -259,10 +258,6 @@ class Issue(object):
self.assignees = list(assignees or [])
self.milestone = milestone or ""
self.depends = list(depends or [])
# Page TITLES this work is written up in — names for documents, which
# is why they are domain-owned. What a title resolves to is /tea:page's
# business, and this layer never asks: no path, no URL, no lookup.
self.wiki = list(wiki or [])
self.origin = origin or LOCAL
self.extra = dict(extra or {})
@@ -308,7 +303,7 @@ class Issue(object):
state=meta.get("state") or "open",
labels=lst("labels"), assignees=lst("assignees"),
milestone="" if ms == "none" else ms,
depends=lst("depends"), wiki=lst("wiki"),
depends=lst("depends"),
origin=meta.get("origin") or LOCAL, extra=extra)
def to_text(self):
@@ -320,7 +315,6 @@ class Issue(object):
"assignees": self.assignees,
"milestone": self.milestone or "none",
"depends": self.depends,
"wiki": self.wiki,
"origin": self.origin,
})
body = self.body.strip() or "(no body)"
+1 -3
View File
@@ -155,8 +155,6 @@ def main():
ap.add_argument("--assignee", action="append", default=[], help="assignee; repeat")
ap.add_argument("--depends", action="append", default=[],
help="id this issue depends on; repeat")
ap.add_argument("--wiki", action="append", default=[],
help="page title this work is written up in; repeat")
ap.add_argument("--out", default=issue.ISSUE_ROOT,
help="store root (default: <repo>/tmp/issues)")
args = ap.parse_args()
@@ -182,7 +180,7 @@ def main():
id=id, title=args.title,
body=with_depends(TEMPLATES[args.type], args.depends),
labels=labels, assignees=args.assignee, milestone=args.milestone,
depends=args.depends, wiki=args.wiki)
depends=args.depends)
# The first issue in a fresh checkout has to create the store, but it says
# so — and it says where, because the path is absolute.