@freetesh/zeno 0.0.0-stage → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +14 -0
- package/.claude-plugin/plugin.json +10 -0
- package/LICENSE +21 -0
- package/README.md +175 -2
- package/cli/dist/checks/architecture.js +126 -0
- package/cli/dist/checks/canonical-values.js +46 -0
- package/cli/dist/checks/context-layout.js +41 -0
- package/cli/dist/checks/copies.js +73 -0
- package/cli/dist/checks/external.js +30 -0
- package/cli/dist/checks/index.js +15 -0
- package/cli/dist/checks/types.js +1 -0
- package/cli/dist/checks/wiki-frontmatter.js +71 -0
- package/cli/dist/commands/add.js +24 -0
- package/cli/dist/commands/check.js +19 -0
- package/cli/dist/commands/doctor.js +16 -0
- package/cli/dist/commands/env.js +6 -0
- package/cli/dist/commands/init.js +78 -0
- package/cli/dist/commands/learn.js +35 -0
- package/cli/dist/commands/standards.js +26 -0
- package/cli/dist/commands/status.js +11 -0
- package/cli/dist/commands/sync.js +23 -0
- package/cli/dist/commands/ui.js +64 -0
- package/cli/dist/commands/weigh.js +16 -0
- package/cli/dist/config/load.js +93 -0
- package/cli/dist/config/schema.js +43 -0
- package/cli/dist/doctor.js +31 -0
- package/cli/dist/format.js +37 -0
- package/cli/dist/index.js +36 -0
- package/cli/dist/init.js +120 -0
- package/cli/dist/learn.js +69 -0
- package/cli/dist/lib/files.js +23 -0
- package/cli/dist/lib/frontmatter.js +16 -0
- package/cli/dist/lib/system.js +19 -0
- package/cli/dist/packs.js +85 -0
- package/cli/dist/run.js +45 -0
- package/cli/dist/standards.js +42 -0
- package/cli/dist/status.js +27 -0
- package/cli/dist/sync.js +30 -0
- package/cli/dist/ui.js +69 -0
- package/package.json +50 -4
- package/packs/expo/pack.yaml +5 -0
- package/packs/firebase/pack.yaml +5 -0
- package/packs/nextjs/pack.yaml +5 -0
- package/packs/react/pack.yaml +5 -0
- package/packs/revenuecat/pack.yaml +5 -0
- package/packs/uniwind/pack.yaml +5 -0
- package/skills/ask/SKILL.md +42 -0
- package/skills/decision/SKILL.md +33 -0
- package/skills/ingest/SKILL.md +44 -0
- package/skills/standards/SKILL.md +16 -0
- package/skills/weigh/SKILL.md +102 -0
- package/skills/wiki-lint/SKILL.md +69 -0
- package/standards/README.md +13 -0
- package/standards/agent-contract.md +40 -0
- package/standards/constitution.md +89 -0
- package/standards/context-layout.md +112 -0
- package/standards/wiki-schema.md +249 -0
- package/templates/dependency-cruiser/app.cjs +23 -0
- package/templates/dependency-cruiser/base.cjs +52 -0
- package/templates/dependency-cruiser/package.cjs +31 -0
- package/templates/dependency-cruiser/root.cjs +15 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ask
|
|
3
|
+
description: Answer a question from the wiki only. Searches .context/wiki/ pages and returns a cited answer with [[wikilinks]] to every page used. Never reads .context/raw/ directly — synthesis must be written down. Usage `/ask <question>`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are answering a question using ONLY `.context/wiki/` as the knowledge source.
|
|
7
|
+
|
|
8
|
+
Question: `$ARGUMENTS`
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. **Search first.** If the `qmd` MCP tool is available, run a `query` for the question against this product's wiki collection (`<product>-wiki`). Its hits are the first candidates.
|
|
13
|
+
|
|
14
|
+
2. **Read `.context/wiki/index.md`** and **identify candidate pages** by matching the question against page titles, IDs, and the index entries. Prefer:
|
|
15
|
+
- `entity` pages for "what is the value / price / name of X"
|
|
16
|
+
- `synthesis` pages for cross-cutting summaries (use these before chasing individual entities)
|
|
17
|
+
- `concept` pages for "why" or "what does X mean" questions
|
|
18
|
+
- `surface` pages for "what does this screen do"
|
|
19
|
+
- `flow` pages for "how does the user get from A to B"
|
|
20
|
+
- `decision` pages for "why did we choose X over Y"
|
|
21
|
+
|
|
22
|
+
3. **Read the candidate pages.** Follow `[[wikilinks]]` one hop if the answer is incomplete. Stop at two hops — if you need three, the wiki is missing a synthesis page; say so.
|
|
23
|
+
|
|
24
|
+
4. **Answer the question** in the product's own voice:
|
|
25
|
+
- Follow the copy rules in the root `CLAUDE.md` — plain words, short sentences, active voice.
|
|
26
|
+
- Write numbers, prices and dates the way the product writes them to a user.
|
|
27
|
+
- Cite every claim with a `[[wikilink]]` to the source page.
|
|
28
|
+
- If two pages disagree, surface the contradiction explicitly — don't pick a winner. `/wiki-lint` will flag it; the user resolves it via `/decision`.
|
|
29
|
+
|
|
30
|
+
5. **If the wiki cannot answer:**
|
|
31
|
+
- Say so plainly.
|
|
32
|
+
- List the pages you checked.
|
|
33
|
+
- Suggest what's missing: "no entity page exists for `<thing>`", "no synthesis page combines `<X>` and `<Y>`", etc.
|
|
34
|
+
- Recommend the user run `/ingest <raw-source>` to fill the gap.
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- **Never read `.context/raw/` or `.context/designs/` from this skill.** If the answer requires raw inspection, refuse and recommend `/ingest`.
|
|
39
|
+
- **Never invent facts.** If a canonical value isn't in an `entity` page, say "not in the wiki".
|
|
40
|
+
- **Every cited page must actually exist.** Don't fabricate a `[[wikilink]]` to make the answer look authoritative.
|
|
41
|
+
- A page with `status: superseded` is not canonical — follow `superseded-by` to the current page.
|
|
42
|
+
- A page with `last-verified` > 90 days is stale — flag it in the answer ("last verified 2025-11-04 — may be out of date").
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision
|
|
3
|
+
description: Record a product or technical decision as a new ADR page in .context/wiki/decisions/. Usage `/decision <title> — <body>`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are logging a decision as a new `.context/wiki/decisions/<YYYY-MM-DD>-<slug>.md` page.
|
|
7
|
+
|
|
8
|
+
Decision to record: `$ARGUMENTS`
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. Read the wiki schema (`../../standards/wiki-schema.md`, relative to this skill) § "`decision`" for the frontmatter and the required sections. If `.context/wiki/decisions/` already holds pages, open a recent one and match it.
|
|
13
|
+
|
|
14
|
+
2. Parse `$ARGUMENTS`:
|
|
15
|
+
- If it contains ` — ` (em-dash with spaces), split on the first occurrence: left = title, right = body.
|
|
16
|
+
- Otherwise treat the whole string as the title; body = "(no detail provided)".
|
|
17
|
+
|
|
18
|
+
3. Derive the filename:
|
|
19
|
+
- Date = today's `currentDate` from the session context (`YYYY-MM-DD`).
|
|
20
|
+
- Slug = kebab-case of the title, lower-cased, alphanumerics + hyphens only, ≤ 60 chars.
|
|
21
|
+
- Path = `.context/wiki/decisions/<date>-<slug>.md`. If a file at that path already exists, append `-2`, `-3`, etc.
|
|
22
|
+
|
|
23
|
+
4. Write the new ADR with the standard frontmatter and the body the user provided. Do not summarise or shorten the body.
|
|
24
|
+
|
|
25
|
+
5. Add the page to `.context/wiki/index.md` under Decisions.
|
|
26
|
+
|
|
27
|
+
6. Confirm: `decision logged: "<title>" → <path>`.
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
- One decision per file. Never append to an existing ADR.
|
|
32
|
+
- Do not edit any other wiki page in the same command — if cross-references are needed, surface them in the body as `[[wikilinks]]`, but leave the target pages alone.
|
|
33
|
+
- The wiki is the only source of truth for decisions. There is no monolithic decision log.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ingest
|
|
3
|
+
description: Read a raw source (wireframe, meeting note, research doc) and draft the wiki page(s) that summarise it. Adds frontmatter, [[wikilinks]], and updates .context/wiki/index.md. Usage `/ingest <path-to-raw-file>`.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are ingesting a raw source into the wiki at `.context/wiki/`.
|
|
7
|
+
|
|
8
|
+
Source to ingest: `$ARGUMENTS`
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. **Read the wiki schema (`../../standards/wiki-schema.md`, relative to this skill) first.** It defines page types, frontmatter, required sections, ID conventions, and lint rules. Every page you write must conform.
|
|
13
|
+
|
|
14
|
+
2. **Read the raw source** at the path in `$ARGUMENTS`. Accepted: anything under `.context/raw/` or `.context/designs/`, and application source in this repository. Refuse paths outside the repo.
|
|
15
|
+
|
|
16
|
+
3. **Classify** the source into one or more wiki page types:
|
|
17
|
+
- HTML wireframe → `surface` page
|
|
18
|
+
- Decision note → `decision` page
|
|
19
|
+
- Research doc / interview → typically `concept` pages (split if it covers multiple ideas), or one `synthesis` page for a brief that draws a conclusion
|
|
20
|
+
- A new tier / product / canonical value → `entity` page
|
|
21
|
+
- A user journey description → `flow` page
|
|
22
|
+
- Don't force one source into one page — a meeting note can produce multiple pages.
|
|
23
|
+
|
|
24
|
+
4. **For each page you will create:**
|
|
25
|
+
- Pick the ID per the wiki schema (`../../standards/wiki-schema.md`, relative to this skill) § "ID conventions". IDs are uppercase, dot-separated, never change.
|
|
26
|
+
- Pick the filename: the slug portion of the ID, lowercase, kebab-case, `.md` extension.
|
|
27
|
+
- Check whether the page already exists. If yes, **update** rather than overwrite: preserve `id`, `supersedes`, `superseded-by`; refresh `last-verified` to today.
|
|
28
|
+
- Use the required sections for that page type — verbatim from the wiki schema (`../../standards/wiki-schema.md`, relative to this skill). Missing a required section is a lint failure.
|
|
29
|
+
- Fill `Related` with at least two `[[wikilinks]]`. A link to a page that doesn't exist yet is OK — `/wiki-lint` will flag it as a TODO.
|
|
30
|
+
- List the source path under `Sources`, so a future `/wiki-lint` can tell which raw files nothing has read.
|
|
31
|
+
|
|
32
|
+
5. **Update `.context/wiki/index.md`:** add the new page under the right type heading, in alphabetical order by slug. Don't reformat existing entries.
|
|
33
|
+
|
|
34
|
+
6. **Leave the source where it is.** `.context/raw/` is immutable: a source is "processed" when a wiki page lists it under `Sources`, not when it moves.
|
|
35
|
+
|
|
36
|
+
7. **Report**: list each page created or updated with its ID and path. Flag any `[[wikilinks]]` to non-existent pages as "TODO targets".
|
|
37
|
+
|
|
38
|
+
## Rules
|
|
39
|
+
|
|
40
|
+
- Never edit anything under `.context/raw/` or `.context/designs/`.
|
|
41
|
+
- Never delete or rename an existing wiki page from this skill — use a `decision` page to log a rename, then run again.
|
|
42
|
+
- Never invent canonical values. If the source has a price/string/enum, copy it verbatim; if it's ambiguous, ask the user before writing.
|
|
43
|
+
- Follow the copy rules from the root `CLAUDE.md` for any user-facing strings you transcribe.
|
|
44
|
+
- Today's date is in the session context — use it for `last-verified`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: standards
|
|
3
|
+
description: Load the standards that cover the work before doing it — the repo's design rules, code standards, .context layout, wiki schema, agent contract, and any team-specific rules. Use before creating or changing designs, code, .context/ files, wiki pages, store listings, or anything a team rule might govern, and when asked "what are the rules for…".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Load the standards that apply
|
|
7
|
+
|
|
8
|
+
1. List them: run `zeno standards` in the repo. It prints every standard that
|
|
9
|
+
applies — zeno's defaults, then the team's and the repo's own (a team file
|
|
10
|
+
with the same name replaces zeno's). If the `zeno` CLI is not installed, use
|
|
11
|
+
the files in `../../standards/` (relative to this skill).
|
|
12
|
+
2. Read only the ones that cover this work: designs, code, `.context/`, wiki,
|
|
13
|
+
listing, secrets — judge from the file names, then their first lines.
|
|
14
|
+
3. Follow them. Where two disagree, the more specific one (the repo's, then the
|
|
15
|
+
team's, then zeno's) wins; say which one you followed.
|
|
16
|
+
4. Before calling the work done, run `zeno check` and report its result.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weigh
|
|
3
|
+
description: Decision gate run BEFORE acting on a non-trivial request in a product repo — a new feature, screen or product, a new dependency or library, a migration or rewrite, a schema, money, pricing or store change, a release or deploy, deleting something, or any change touching more than one file or more than one product. Weighs the request against the zeno constitution, the product's wiki and ADRs, existing features and tasks, cost vs value, and writing less code, then returns do it / do it differently / push back with citations. Also use when the user types /weigh or asks "should we…", "is it worth…", "does this make sense".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Weigh before acting
|
|
7
|
+
|
|
8
|
+
You are deciding whether and how to do a request — not doing it yet.
|
|
9
|
+
Request: `$ARGUMENTS` (empty = the user's latest request in this conversation).
|
|
10
|
+
|
|
11
|
+
## Skip the gate when it is trivial
|
|
12
|
+
|
|
13
|
+
Answer and act directly, with no verdict block, when **all** are true: one file,
|
|
14
|
+
no new dependency, no schema / money / store / release / delete, and the change is
|
|
15
|
+
fully specified (a typo, a spacing fix, a copy edit the user dictated). A
|
|
16
|
+
product's `.claude/zeno.yaml` may tighten this under `weigh.trivial`.
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
1. **Restate the goal** in one line — what outcome the user wants, not the
|
|
21
|
+
mechanism they named. A named mechanism ("use library X", "move to Firebase")
|
|
22
|
+
is a proposal to weigh, not a given.
|
|
23
|
+
|
|
24
|
+
2. **Rules.** Run `zeno standards --constitution` for the principle titles
|
|
25
|
+
(zeno's and any the team added), and read the constitution files that
|
|
26
|
+
`zeno standards` lists — or `../../standards/constitution.md` (relative to
|
|
27
|
+
this skill) if the CLI is not installed. Note every principle the request
|
|
28
|
+
touches, by ID. Read a standard from `zeno standards` only if the request is
|
|
29
|
+
in its area.
|
|
30
|
+
|
|
31
|
+
3. **Domain.** Search before you judge. Run `mcp__plugin_zeno_qmd__query` with
|
|
32
|
+
the goal in plain words, then the key nouns (product name + topic). Read the
|
|
33
|
+
top hits with `mcp__plugin_zeno_qmd__get`. Look for: an ADR that already
|
|
34
|
+
decided this, a canonical value it would change, a concept it would break.
|
|
35
|
+
If qmd is unavailable, read `.context/wiki/index.md` and `decisions/`.
|
|
36
|
+
**Architecture:** if `.claude/zeno.yaml` lists the `architecture` module, read
|
|
37
|
+
the repo's `.dependency-cruiser.cjs` and its wiki architecture concept page.
|
|
38
|
+
A request whose code would need an import a rule forbids is DO IT
|
|
39
|
+
DIFFERENTLY (name the allowed path) or PUSH BACK; one that changes a rule
|
|
40
|
+
is **too-large** unless a decision page already approves it. Cite the rule
|
|
41
|
+
by its `name`.
|
|
42
|
+
|
|
43
|
+
4. **Duplicates and conflicts.** Check `.context/features/` and `.context/tasks.md`
|
|
44
|
+
of this product, and the features collections of sibling products in qmd:
|
|
45
|
+
is this already planned, built, shelved, or in progress elsewhere? Would it
|
|
46
|
+
conflict with something in `## Now`?
|
|
47
|
+
|
|
48
|
+
5. **Cost vs value.**
|
|
49
|
+
- Size: **small** (1 file, < 50 lines) · **medium** (2–5 files, < 200 lines) ·
|
|
50
|
+
**large** (5+ files) · **too-large** (architecture change — split it).
|
|
51
|
+
- Ongoing cost: new dependency, new service bill, more to maintain, more to
|
|
52
|
+
test, store review risk.
|
|
53
|
+
- Value: name the user or the metric it moves (`metrics/definitions.yml` if
|
|
54
|
+
the product has one). If neither can be named, say "value unproven".
|
|
55
|
+
|
|
56
|
+
6. **Write less.** Climb the ladder and stop at the first rung that works:
|
|
57
|
+
delete it → reuse something in this repo → reuse from a sibling product or
|
|
58
|
+
shared script → platform or standard library → an existing well-used package
|
|
59
|
+
→ fewer lines → new code. If the `ponytail` plugin is installed, follow its
|
|
60
|
+
ladder for this step.
|
|
61
|
+
|
|
62
|
+
7. **Large or too-large?** Delegate steps 2–6 to the `challenger` agent for an
|
|
63
|
+
independent read — pass it the request, the repo path and the constitution
|
|
64
|
+
and standards paths from step 2 — then reconcile: where you and it disagree,
|
|
65
|
+
show both.
|
|
66
|
+
|
|
67
|
+
## Verdict
|
|
68
|
+
|
|
69
|
+
Reply with exactly this block, then stop or proceed as the verdict says:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Verdict: DO IT | DO IT DIFFERENTLY | PUSH BACK
|
|
73
|
+
Goal: <one line>
|
|
74
|
+
Size: small | medium | large | too-large
|
|
75
|
+
Why:
|
|
76
|
+
- <C-xx> <one line> — <file or wiki page cited>
|
|
77
|
+
- ...
|
|
78
|
+
Instead: <only for DO IT DIFFERENTLY — the cheaper or safer way>
|
|
79
|
+
Open questions: <only if a real ambiguity blocks a good answer>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Every bullet under **Why** cites a principle ID and a source (a wiki page, ADR,
|
|
83
|
+
standard, feature or file). A reason with no source is an opinion — drop it or
|
|
84
|
+
mark it "unverified".
|
|
85
|
+
- **DO IT** → proceed with the work in the same turn.
|
|
86
|
+
- **DO IT DIFFERENTLY** → proceed with the *Instead* version only if the user
|
|
87
|
+
already accepted it; otherwise stop and ask which way.
|
|
88
|
+
- **PUSH BACK** → stop. Do not start the work, not even a part of it. Ask for
|
|
89
|
+
the reason. When the user gives one, log it (below), then proceed as they say.
|
|
90
|
+
|
|
91
|
+
## Logging (push back and overrides)
|
|
92
|
+
|
|
93
|
+
When the user overrides a PUSH BACK or rejects a DO IT DIFFERENTLY, append one
|
|
94
|
+
line to the product's log so zeno can learn from it later:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
node ../../scripts/log-verdict.mjs --verdict push-back --principles C-05,C-06 \
|
|
98
|
+
--request "<one line>" --reason "<the user's reason, verbatim>"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
(path relative to this skill). It writes to `.context/raw/zeno/verdicts.jsonl`
|
|
102
|
+
in the current repo. Never edit or delete existing lines.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wiki-lint
|
|
3
|
+
description: Audit .context/wiki/ for drift — broken [[links]], orphan pages, contradictions between entities, stale last-verified dates, unprocessed raw files. Optionally auto-fix safe issues and regenerate .context/wiki/index.md. Usage `/wiki-lint` (audit) or `/wiki-lint --fix` (audit + auto-fix).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are linting the wiki at `.context/wiki/` against the wiki schema (`../../standards/wiki-schema.md`, relative to this skill).
|
|
7
|
+
|
|
8
|
+
Mode: `$ARGUMENTS` (empty = audit only; `--fix` = audit + auto-fix safe issues).
|
|
9
|
+
|
|
10
|
+
## Steps
|
|
11
|
+
|
|
12
|
+
1. **Read the wiki schema (`../../standards/wiki-schema.md`, relative to this skill)** to refresh schema, ID conventions, required sections, and the lint-rules table.
|
|
13
|
+
|
|
14
|
+
2. **Run `zeno check` first** if the CLI is installed. It checks frontmatter,
|
|
15
|
+
duplicate IDs, staleness and prices held by no entity in under a second,
|
|
16
|
+
plus any checker the repo declares. Start from its output rather than
|
|
17
|
+
re-deriving it.
|
|
18
|
+
|
|
19
|
+
3. **Enumerate pages.** List every `.md` file under `.context/wiki/` (excluding `index.md` and `CLAUDE.md`). For each, parse the frontmatter.
|
|
20
|
+
|
|
21
|
+
4. **Build the graph:**
|
|
22
|
+
- Map `id → file path`.
|
|
23
|
+
- For each page, extract all `[[wikilink]]` tokens from the body.
|
|
24
|
+
- Build inbound and outbound link sets per page.
|
|
25
|
+
|
|
26
|
+
5. **Run the checks below.** Group findings into **Blockers** and **Warnings**.
|
|
27
|
+
|
|
28
|
+
### Blockers (must be fixed)
|
|
29
|
+
|
|
30
|
+
| Check | Rule |
|
|
31
|
+
|---|---|
|
|
32
|
+
| Missing required section | Per the wiki schema (`../../standards/wiki-schema.md`, relative to this skill) § "Page body — required sections" |
|
|
33
|
+
| Broken `[[wikilink]]` | Target page does not exist |
|
|
34
|
+
| Duplicate `id` | Two pages claim the same ID |
|
|
35
|
+
| Contradictory canonical value | Two `entity` pages list the same key with different values |
|
|
36
|
+
| `status: superseded` with no `superseded-by` | Set or remove the status |
|
|
37
|
+
| Filename ↔ id slug mismatch | The filename must match the slug portion of the ID |
|
|
38
|
+
| `type` does not match folder | `type: concept` must live in `concepts/`, etc. |
|
|
39
|
+
|
|
40
|
+
### Warnings
|
|
41
|
+
|
|
42
|
+
| Check | Rule |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Orphan page | Zero inbound `[[wikilinks]]`. Exception: `decision` and `synthesis` pages are commonly orphan-source. |
|
|
45
|
+
| Stale `last-verified` | > 90 days from today. |
|
|
46
|
+
| Unprocessed raw file | A file under `.context/raw/` that no wiki page references in its `Sources`. |
|
|
47
|
+
| Stale synthesis | A `synthesis` page where any `Built from` page was modified after the synthesis's `Last refresh`. |
|
|
48
|
+
| Page missing two outbound links | Body has fewer than two `[[wikilinks]]`. |
|
|
49
|
+
| User-facing string violates copy rules | Check quoted copy against the rules in the root `CLAUDE.md`. Best-effort. |
|
|
50
|
+
|
|
51
|
+
6. **Auto-fix (only if `--fix` is in `$ARGUMENTS`):**
|
|
52
|
+
- Regenerate `.context/wiki/index.md` from scratch: enumerate pages by type, sort alphabetically by slug, keep the structure the file already has.
|
|
53
|
+
- Fix `last-verified` to today's date on any page whose body was edited in the working tree.
|
|
54
|
+
- Fix filename ↔ id slug mismatches (rename the file; do NOT change the ID).
|
|
55
|
+
- **Never** auto-fix: contradictory canonical values, missing required sections, broken `[[wikilinks]]`. These need a human decision.
|
|
56
|
+
|
|
57
|
+
7. **Report.** Print:
|
|
58
|
+
- Counts: pages, blockers, warnings, auto-fixes applied.
|
|
59
|
+
- Per-finding lines: `[BLOCKER|WARN] <path>:<rule> — <detail>`.
|
|
60
|
+
- For each blocker, one suggested fix.
|
|
61
|
+
- For broken `[[wikilinks]]`, list candidate existing pages by name similarity.
|
|
62
|
+
|
|
63
|
+
## Rules
|
|
64
|
+
|
|
65
|
+
- **Never edit pages other than auto-fixes above.** Lint reports; the user (or `/ingest`) fixes.
|
|
66
|
+
- **Never delete pages.** Superseded pages stay on disk with `status: superseded` and `superseded-by: <new-id>`.
|
|
67
|
+
- **Never modify `.context/raw/`** except to warn about unprocessed files.
|
|
68
|
+
- If a blocker resists auto-fix, exit non-zero (in CI mode) but always print the full report first.
|
|
69
|
+
- Today's date is in the session context — use it for staleness math (>90 days).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# standards/
|
|
2
|
+
|
|
3
|
+
zeno's default standards. `zeno standards` lists the ones that apply to a repo:
|
|
4
|
+
these first, then each folder named under `standards:` in the estate's and the
|
|
5
|
+
repo's `.claude/zeno.yaml`. A configured file with the same name as one of these
|
|
6
|
+
replaces it; a configured `constitution.md` adds principles instead.
|
|
7
|
+
|
|
8
|
+
| File | What it holds |
|
|
9
|
+
|---|---|
|
|
10
|
+
| `constitution.md` | The principles a request is weighed against (C-01 to C-13) |
|
|
11
|
+
| `wiki-schema.md` | Wiki page types, frontmatter, required sections, lint rules |
|
|
12
|
+
| `context-layout.md` | The `.context/` ten-folder layout, `features/` and `tasks.md` formats |
|
|
13
|
+
| `agent-contract.md` | What every agent does before, during and after work |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Agent contract
|
|
2
|
+
|
|
3
|
+
What every coding agent working in a zeno repo does. A team can replace this
|
|
4
|
+
file with its own `agent-contract.md` in a configured standards folder.
|
|
5
|
+
|
|
6
|
+
## Before starting
|
|
7
|
+
|
|
8
|
+
- Read the repo's `CLAUDE.md` / `AGENTS.md`: stack, layout, the rules that are
|
|
9
|
+
the repo's own.
|
|
10
|
+
- Read `.context/tasks.md`. It is the ordered queue — the top item of `## Now`
|
|
11
|
+
is the next action. After finishing, tick the task and append a Session Note.
|
|
12
|
+
- For a non-trivial request, run the weigh gate first (`/zeno:weigh`).
|
|
13
|
+
|
|
14
|
+
## Repository rules
|
|
15
|
+
|
|
16
|
+
1. Product material lives in whichever `.context/` folder owns it
|
|
17
|
+
(`context-layout.md`). The wiki is the knowledge base; its schema is
|
|
18
|
+
`wiki-schema.md`.
|
|
19
|
+
2. Do not add top-level `docs/` or `wireframes/` folders, or root `TODO.md`,
|
|
20
|
+
`STATUS.md` or `SETUP.md`. Files a host or tool reads by exact path —
|
|
21
|
+
`README.md`, `LICENSE`, `CHANGELOG.md`, `CONTRIBUTING.md`, `SECURITY.md`,
|
|
22
|
+
`.github/` — stay at the root.
|
|
23
|
+
3. Generated folders are never hand-edited; change their source and regenerate.
|
|
24
|
+
|
|
25
|
+
## Comments
|
|
26
|
+
|
|
27
|
+
Write a comment only to explain **why**. The code already says how.
|
|
28
|
+
|
|
29
|
+
A comment earns its place when it records something the reader cannot recover
|
|
30
|
+
from the code: a constraint, a trade-off, a bug it prevents, or a non-obvious
|
|
31
|
+
consequence. If it restates what the next line does, delete it. No
|
|
32
|
+
section-divider comments, no changelog comments, no comments restating a
|
|
33
|
+
function's own name.
|
|
34
|
+
|
|
35
|
+
## Before calling work done
|
|
36
|
+
|
|
37
|
+
1. Reflect changed behaviour in `CLAUDE.md` and any affected `.context/` page.
|
|
38
|
+
2. Run the repo's own lint, typecheck and tests.
|
|
39
|
+
3. Run `zeno check`. Every checker the repo declares under `commands:` runs
|
|
40
|
+
with it.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Constitution
|
|
2
|
+
|
|
3
|
+
The principles every non-trivial request is weighed against before work starts.
|
|
4
|
+
The other standards say *how* things are done; this file says what wins when a
|
|
5
|
+
request and a rule disagree.
|
|
6
|
+
|
|
7
|
+
Each principle has an ID that verdicts cite (`C-05`). IDs never change; a
|
|
8
|
+
dropped principle is struck through, not reused. IDs C-01 to C-19 are zeno's.
|
|
9
|
+
A team adds its own from C-20 up in a `constitution.md` in one of its configured
|
|
10
|
+
standards folders; zeno reads both.
|
|
11
|
+
|
|
12
|
+
## How a request is weighed
|
|
13
|
+
|
|
14
|
+
Before acting on a non-trivial request, check it against the principles below,
|
|
15
|
+
then answer with one verdict:
|
|
16
|
+
|
|
17
|
+
- **Do it** — no principle is at risk.
|
|
18
|
+
- **Do it differently** — the goal is fine; the way asked breaks a principle.
|
|
19
|
+
Name the principle and give the cheaper or safer way.
|
|
20
|
+
- **Push back** — the request breaks a principle outright, or the cost is
|
|
21
|
+
clearly higher than the value. Stop until the owner gives a reason; log it.
|
|
22
|
+
|
|
23
|
+
Every verdict cites principle IDs and the files (wiki page, ADR, standard) it
|
|
24
|
+
relied on. A verdict with no citation is an opinion, not a verdict.
|
|
25
|
+
|
|
26
|
+
## Principles
|
|
27
|
+
|
|
28
|
+
### C-01 Shipping beats starting
|
|
29
|
+
A request that finishes or unblocks something already in flight outranks one
|
|
30
|
+
that starts something new. Ask: what does this move closer to a user?
|
|
31
|
+
|
|
32
|
+
### C-02 One home per fact
|
|
33
|
+
Every rule, value and artifact has exactly one source; everything else imports,
|
|
34
|
+
links or is generated from it. A second copy is a future contradiction.
|
|
35
|
+
|
|
36
|
+
### C-03 Knowledge is written down, in the repo
|
|
37
|
+
A decision that lives only in chat or in one machine's memory is lost. Decisions
|
|
38
|
+
become ADRs; canonical values become wiki entities; both live in git. Check the
|
|
39
|
+
wiki and ADRs before answering from memory.
|
|
40
|
+
|
|
41
|
+
### C-04 Decided things stay decided — until a new decision says otherwise
|
|
42
|
+
A request that contradicts an ADR is not done silently. Either it follows the
|
|
43
|
+
ADR, or a new ADR supersedes it, with the reason.
|
|
44
|
+
|
|
45
|
+
### C-05 Value must beat cost
|
|
46
|
+
Weigh effort, tokens, money and the maintenance it adds forever against who
|
|
47
|
+
gains and how much. Name the user or the metric it moves; if neither can be
|
|
48
|
+
named, the value is unproven.
|
|
49
|
+
|
|
50
|
+
### C-06 Write less
|
|
51
|
+
Before writing code: can something be deleted, reused from this repo or a
|
|
52
|
+
sibling, done with the platform or standard library, or done in fewer lines?
|
|
53
|
+
New code is the last rung, not the first.
|
|
54
|
+
|
|
55
|
+
### C-07 Tested tools over custom ones
|
|
56
|
+
Use a maintained, widely used tool before building one. Build only what no tool
|
|
57
|
+
covers, and keep it small.
|
|
58
|
+
|
|
59
|
+
### C-08 Products evolve together
|
|
60
|
+
A fix that applies to more than one product goes into the shared standard,
|
|
61
|
+
template or script — not into one product by hand. A product differs from the
|
|
62
|
+
others only with a written reason.
|
|
63
|
+
|
|
64
|
+
### C-09 Hard rules are code
|
|
65
|
+
A rule that must never break is enforced by a linter, a check or a hook, not by
|
|
66
|
+
prose. When prose keeps getting broken, turn it into a check.
|
|
67
|
+
|
|
68
|
+
### C-10 Secrets are never lost and never leaked
|
|
69
|
+
Every credential is backed up the moment it exists; no secret value goes into a
|
|
70
|
+
commit, a Markdown file or a chat reply.
|
|
71
|
+
|
|
72
|
+
### C-11 Verified, one step at a time
|
|
73
|
+
Prove each step works before the next. Report failures as failures. Commit when
|
|
74
|
+
asked; push only when asked.
|
|
75
|
+
|
|
76
|
+
### C-12 Reversible before irreversible
|
|
77
|
+
Prefer the change that can be undone. Deletes, force-pushes, store submissions,
|
|
78
|
+
production deploys and permission changes are confirmed first, every time.
|
|
79
|
+
|
|
80
|
+
### C-13 Users' money and data are handled exactly
|
|
81
|
+
Money in integer minor units; privacy promises match what the code does; store
|
|
82
|
+
claims match the app. Correctness beats speed here.
|
|
83
|
+
|
|
84
|
+
## Weights
|
|
85
|
+
|
|
86
|
+
A repo's `.claude/zeno.yaml` may raise or lower the weight of a principle under
|
|
87
|
+
`weigh.weights` (a game might weigh C-05 higher; a finance product C-13). It may
|
|
88
|
+
not remove one without a written reason, and every override shows up in
|
|
89
|
+
`zeno check`.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# The `.context/` layout
|
|
2
|
+
|
|
3
|
+
Every repo keeps its non-code product material in `.context/`, in the same ten
|
|
4
|
+
folders. Each has one job, and none is a bucket meaning "everything else". A team
|
|
5
|
+
can replace this file with its own `context-layout.md` in a configured standards
|
|
6
|
+
folder.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
<repo>/.context/
|
|
10
|
+
├── README.md what this is, and which folders are absent and why
|
|
11
|
+
├── tasks.md the ordered queue. The top item is the next action.
|
|
12
|
+
├── raw/ sources you didn't write. Immutable.
|
|
13
|
+
├── wiki/ everything you concluded. Schema: wiki-schema.md
|
|
14
|
+
├── features/ what's next.
|
|
15
|
+
├── designs/ what it looks like.
|
|
16
|
+
├── listing/ what the stores show.
|
|
17
|
+
├── marketing/ how it's sold.
|
|
18
|
+
├── metrics/ the numbers.
|
|
19
|
+
├── support/ what you tell users.
|
|
20
|
+
├── legal/ what you promise.
|
|
21
|
+
└── ops/ how you run it.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Rules
|
|
25
|
+
|
|
26
|
+
1. **Ten folders, one job each.** There is no `documents/`, `research/`,
|
|
27
|
+
`architecture/` or `decisions/` folder: a research brief is a wiki synthesis
|
|
28
|
+
page, an architecture note is a wiki concept, an ADR is `wiki/decisions/`.
|
|
29
|
+
2. **`README.md` and `tasks.md` are the only files at `.context/` root.**
|
|
30
|
+
`README.md` lists every absent folder as `n/a — <why>`.
|
|
31
|
+
3. **Nothing is created empty.** A folder appears with its first file — git does
|
|
32
|
+
not track empty folders, so a placeholder disappears on clone. `raw/` is the
|
|
33
|
+
one exception and carries a `.gitkeep`.
|
|
34
|
+
4. **One home per artifact; everything else is an export.** Source art lives in
|
|
35
|
+
`designs/`; store images and press kits are generated from it.
|
|
36
|
+
5. **Authored vs generated is visible.** A generated file is committed but never
|
|
37
|
+
hand-edited.
|
|
38
|
+
|
|
39
|
+
## What a repo is expected to have
|
|
40
|
+
|
|
41
|
+
| Stage | Expected |
|
|
42
|
+
|---|---|
|
|
43
|
+
| any repo | `README.md` · `tasks.md` |
|
|
44
|
+
| uses the `docs` or `knowledge` module | + `raw/` · `wiki/` · `features/` |
|
|
45
|
+
| draws its UI | + `designs/` (optional; an estate can require it with a command) |
|
|
46
|
+
| has a store presence | + `listing/` |
|
|
47
|
+
| is live to users | + `marketing/` · `metrics/` · `support/` · `legal/` |
|
|
48
|
+
| once something runs | + `ops/` |
|
|
49
|
+
|
|
50
|
+
## Naming and frontmatter
|
|
51
|
+
|
|
52
|
+
- Append-only, time-ordered files → ISO date: `YYYY-MM-DD-slug.md`.
|
|
53
|
+
- Files referenced by a stable ID → zero-padded number: `NNNN-slug.md`.
|
|
54
|
+
- Frontmatter follows the wiki schema: `id`, `type`, `status`, `last-verified`,
|
|
55
|
+
`supersedes`, `superseded-by`. Kebab-case keys.
|
|
56
|
+
|
|
57
|
+
## `features/` — what is next
|
|
58
|
+
|
|
59
|
+
One page per feature, `NNNN-<slug>.md`:
|
|
60
|
+
|
|
61
|
+
```markdown
|
|
62
|
+
---
|
|
63
|
+
id: FEAT-0031
|
|
64
|
+
type: feature # feature | experiment | chore | platform
|
|
65
|
+
status: building # planned | building | shipped | shelved | superseded
|
|
66
|
+
last-verified: 2026-04-02
|
|
67
|
+
release: 3.4.0
|
|
68
|
+
---
|
|
69
|
+
## Summary · ## Motivation · ## Acceptance scenarios (Given/When/Then)
|
|
70
|
+
## Out of scope · ## Open questions
|
|
71
|
+
## Store copy
|
|
72
|
+
> One or two sentences users will read in the release notes.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The wiki describes what *is*; `features/` describes what is *next*. A shipped
|
|
76
|
+
feature goes `status: shipped` and is never deleted.
|
|
77
|
+
|
|
78
|
+
## `tasks.md` — the ordered queue
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
---
|
|
82
|
+
updated: 2026-09-29
|
|
83
|
+
horizon: 2026-10-13 # this file is stale after this date
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
# Tasks
|
|
87
|
+
|
|
88
|
+
## Now <!-- position is the dependency; do in order -->
|
|
89
|
+
1. [ ] T001 Add a screenshot mode `feat:0002` ~1d
|
|
90
|
+
2. [ ] T002 Write the capture flows needs:T001 ~3h
|
|
91
|
+
|
|
92
|
+
## Parallel <!-- independent, safe to batch -->
|
|
93
|
+
- [ ] T004 [P] Move the SKU IDs into the wiki ~1h
|
|
94
|
+
|
|
95
|
+
## Blocked
|
|
96
|
+
- [ ] T005 Submit the iOS build
|
|
97
|
+
blocked-by: store account access since:2026-09-16
|
|
98
|
+
unblock: ask for the role next-check:2026-10-06
|
|
99
|
+
|
|
100
|
+
## Waiting <!-- deferred by time, not by a task -->
|
|
101
|
+
- [ ] T006 Second-language listing wait:2026-11-01
|
|
102
|
+
|
|
103
|
+
## Done
|
|
104
|
+
- [x] T000 Set up .context done:2026-09-29
|
|
105
|
+
|
|
106
|
+
## Session Notes
|
|
107
|
+
### 2026-09-29
|
|
108
|
+
- Done: T000. Learned: … Next: T001.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
A blocker with no named unblocking action and no check date is a silent leak.
|
|
112
|
+
A task that needs more than a line and a continuation is a `features/` page.
|