@nurix/etna 0.2.1 → 0.3.2
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/bin/etna.js +17 -3
- package/data/harnesses/code/CLAUDE.md +77 -114
- package/data/harnesses/code/agents/boundary-mapper.md +91 -0
- package/data/harnesses/code/agents/brainstorm.md +110 -0
- package/data/harnesses/code/agents/change-review.md +13 -12
- package/data/harnesses/code/agents/contract-monitor.md +15 -14
- package/data/harnesses/code/agents/dep-health.md +1 -0
- package/data/harnesses/code/agents/git-history.md +1 -0
- package/data/harnesses/code/agents/maintenance.md +4 -3
- package/data/harnesses/code/agents/review.md +1 -0
- package/data/harnesses/code/agents/spec-mode.md +1 -0
- package/data/harnesses/code/rules/general.md +1 -0
- package/data/harnesses/code/rules/nomenclature.md +1 -0
- package/data/harnesses/code/scripts/build-ownership-index.sh +1 -0
- package/data/harnesses/code/scripts/check-doc-drift.sh +1 -0
- package/data/harnesses/code/skills/boundaries/SKILL.md +86 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +21 -17
- package/data/harnesses/code/skills/documentation/references/templates.md +36 -48
- package/data/harnesses/code/skills/introspect/SKILL.md +24 -23
- package/data/harnesses/code/skills/technical-brainstorm/README.md +287 -0
- package/data/harnesses/code/skills/technical-brainstorm/SKILL.md +601 -0
- package/data/harnesses/code/skills/technical-brainstorm/greenfield.md +99 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/backlog.md +39 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/decisions.md +42 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/doctrine.md +31 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/glossary.md +19 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/inventory.md +44 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/milestones.md +43 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/non-goals.md +21 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/plan-doc.md +61 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/questions.md +84 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/references.md +28 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/rejected.md +29 -0
- package/data/harnesses/code/skills/technical-brainstorm/templates/state.md +8 -0
- package/data/harnesses/code/skills/workflow-mapper/SKILL.md +1 -0
- package/data/harnesses/kb-agi/CLAUDE.md +16 -1
- package/data/harnesses/kb-agi/agents/kb-agi-init.md +3 -2
- package/data/harnesses/kb-agi/agents/kb-catch-stale.md +2 -1
- package/data/harnesses/kb-agi/agents/kb-find-gaps.md +3 -2
- package/data/harnesses/kb-agi/agents/kb-fix-links.md +2 -1
- package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +2 -1
- package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +2 -1
- package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +2 -1
- package/data/harnesses/kb-agi/rules/kb.md +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Greenfield writing doctrine
|
|
2
|
+
|
|
3
|
+
> **The reader has no past.** They've never seen an earlier version of the system, never heard of the alternative you considered, never knew about the repo you were going to fold in. Write for them.
|
|
4
|
+
|
|
5
|
+
For projects with nothing built yet — no production deploys, no users, no legacy code — architecture docs describe the system as it **will be**, in present tense. The temptation to narrate the design journey ("we considered X, chose Y, dropped Z") produces documents full of phantoms — references to things the reader has no way to imagine.
|
|
6
|
+
|
|
7
|
+
These rules apply equally to the first draft and to subsequent edits. After every design decision, the architecture doc should look as though the chosen option was always the plan.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Describe what the system **is** (or will be — same thing in greenfield). Never describe what it isn't, used to be, replaces, supersedes, or is migrating from.
|
|
14
|
+
|
|
15
|
+
There is no past tense in a doc for software that doesn't exist yet.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Banned patterns
|
|
20
|
+
|
|
21
|
+
| Don't write | Why it's wrong | Write instead |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| "X replaces Y" / "X supersedes Y" | Reader doesn't know Y. | "X is the [role]." |
|
|
24
|
+
| "Previously planned" / "originally proposed" / "we used to" | There is no previous. | Describe the current plan. |
|
|
25
|
+
| "What was dropped" / "What we ruled out" sections | Only useful when readers carry a stale model. | Move reasoning to `decisions.md` if load-bearing; otherwise delete. |
|
|
26
|
+
| `~~strike-through~~` text | Tracks edits for live readers; pollutes fresh docs. | Delete the struck text. Keep the surviving prose. |
|
|
27
|
+
| "ex-Foo", "from ex-Bar" annotations on packages | Repo-fold bookkeeping. | Just name the package. |
|
|
28
|
+
| "Folded into monorepo" / `import-legacy.sh` / migration scripts | Migration mechanic, not architecture. | Describe the monorepo as the steady state. |
|
|
29
|
+
| "v1 vs v2" / "future migration target" | Implies one is becoming the other. | Describe v1. Phase-2 ideas can be a "future scope" subsection without "migration" framing. |
|
|
30
|
+
| "(existing — `~/dev/foo`)" / "no build needed" markers | Differentiates from non-existing; in greenfield everything is to-build. | Just list the service. |
|
|
31
|
+
| "There is no foo_table" / "we don't have a foo service" | Reader didn't expect one. | Don't mention it. |
|
|
32
|
+
| "Per Decision-N resolution" inline citations on every paragraph | Architecture doc isn't a decision log. | Plain prose. One cross-ref per section, only when the *why* is non-obvious. |
|
|
33
|
+
| "Resolved (was: open question)" / "(retired)" markers | Edit-history bookkeeping. | Delete — the resolution **is** the doc now. |
|
|
34
|
+
| "What this kills" / "Trade-off accepted" headings | Decision-capture format leaking into architecture. | Keep these in `decisions.md` only. |
|
|
35
|
+
| "We no longer X" / "X is no longer needed" | Reader had no expectation that X existed. | Don't mention X. |
|
|
36
|
+
| "Renamed from foo to bar" / "(formerly known as …)" | The rename doesn't matter — only the current name does. | Use the current name. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Smell-words grep
|
|
41
|
+
|
|
42
|
+
`stop` runs this automatically. Manual invocation:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
grep -rEni \
|
|
46
|
+
'replaces|supersedes|superseded|previously|formerly|originally proposed|what was dropped|fully retired|~~|ex-[a-z-]+|folded in|import-legacy|migration target|migrate from|no longer|we used to|resolved per|renamed from|formerly known' \
|
|
47
|
+
plan/
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
In a clean greenfield architecture doc, this should return no hits in `01–NN` numbered docs.
|
|
51
|
+
|
|
52
|
+
Hits **are** acceptable in:
|
|
53
|
+
- `decisions.md` — scoped to a specific decision-capture entry.
|
|
54
|
+
- `rejected.md` — scoped to a rejected alternative.
|
|
55
|
+
- `references.md` — describing external prior art.
|
|
56
|
+
- Commit messages and PR descriptions.
|
|
57
|
+
- `./plan/sources/` — copies of input documents (not authored under these rules).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Where the past DOES belong
|
|
62
|
+
|
|
63
|
+
- `decisions.md` — alternatives + why the chosen option won, **only** when the reasoning isn't obvious from the architecture itself.
|
|
64
|
+
- `rejected.md` — paths considered and rejected.
|
|
65
|
+
- `references.md` — external prior art.
|
|
66
|
+
- Commit messages, PR descriptions — what changed and why; lives in git, not docs.
|
|
67
|
+
|
|
68
|
+
These are the only four places. Architecture docs (`01-foo.md`, `02-bar.md`, ...) are present-tense.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## What's still allowed (don't over-correct)
|
|
73
|
+
|
|
74
|
+
- **Forward planning that names a phase** ("ships in M7 so the bus already knows about `lead.created` when CRM sync arrives") — describes a positive future, not a past.
|
|
75
|
+
- **Constraint statements** ("we accept a 5-second tile lag for predictable server load") — current tradeoffs, stated as facts. Live in `decisions.md`, not architecture.
|
|
76
|
+
- **Cross-refs** ("see `04 §4.3`") — pointers, not history.
|
|
77
|
+
- **Negative assertions about external systems** ("the upstream service has no native fan-in") — describing a real third-party limitation is fine.
|
|
78
|
+
- **Future-scope subsections** ("Phase 2 considerations") — labelled clearly, not framed as migrations.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Before merging an architecture doc, ask
|
|
83
|
+
|
|
84
|
+
1. If a brand-new collaborator read this section cold, would they need to know about the alternative I'm comparing to? If no, delete the comparison.
|
|
85
|
+
2. Does the section read as present-tense description, or as a story of "we went from X to Y"? Rewrite the story form.
|
|
86
|
+
3. Are there strike-throughs? Delete them.
|
|
87
|
+
4. Does an open-questions list still contain resolved items? Move them to `decisions.md` and drop from the list.
|
|
88
|
+
5. Are there inline "(per Decision-X)" citations sprinkled through the prose? Strip — keep at most one cross-ref per section.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Why this matters
|
|
93
|
+
|
|
94
|
+
A greenfield doc that reads like a migration guide signals two things to a new reader:
|
|
95
|
+
|
|
96
|
+
1. **There is hidden context I don't have.** Every "previously" / "replaces" makes them wonder what they're missing.
|
|
97
|
+
2. **The author is still in the middle of deciding.** Strike-throughs and "(resolved)" markers feel provisional.
|
|
98
|
+
|
|
99
|
+
Both undermine the doc's authority. A clean greenfield doc reads as an act of architecture, not an act of revision.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Backlog
|
|
2
|
+
|
|
3
|
+
This file is the **forward-looking list of deferred-but-planned items** — work the team intends to build, but not in the current scope. It complements `non-goals.md` (which holds the scope-creep guards: things we are **not** building) and `rejected.md` (which holds paths we considered and chose against). Use the right pillar:
|
|
4
|
+
|
|
5
|
+
| Pillar | Semantics |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `backlog.md` (this file) | "We **will** build this, just **later**." Deferred to a known future milestone. Roadmap forward. |
|
|
8
|
+
| `non-goals.md` | "We deliberately are **not** building this." Scope guard. May never be built. |
|
|
9
|
+
| `rejected.md` | "We considered this path and chose another." Past-tense alternative. |
|
|
10
|
+
|
|
11
|
+
If you can't tell which file an item belongs in, ask: *"Is the plan to build this eventually?"* If yes → backlog. If no but could change → non-goals. If we already weighed it against an alternative → rejected.
|
|
12
|
+
|
|
13
|
+
Backlog items carry four load-bearing fields. **Target milestone** names the future bucket (`v1.1`, `M2`, `TBD`); **Why deferred** explains the reason it isn't in the current scope (commonly: scope cut, depends on something else, waiting for user feedback, lower priority than current work); **Scope** sketches what the item actually includes — enough that a future planner can pick it up cold; **Re-evaluate when** is the trigger that promotes it from backlog to active work.
|
|
14
|
+
|
|
15
|
+
When a backlog item is promoted (its milestone comes due), **delete it from this file** and either (a) seed a new round of intake questions in `questions.md` for the new scope, or (b) move the spec into a plan doc if the design is already mostly clear. Don't strikethrough, don't leave a "(promoted)" marker — same hygiene as resolved questions and triggered non-goals.
|
|
16
|
+
|
|
17
|
+
If a backlog item turns out to be unworkable or unneeded, move it to `rejected.md` (not deleted silently) with the reason.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## B1 — [Title]
|
|
22
|
+
|
|
23
|
+
**Target milestone.** [v1.1 / M2 / TBD]
|
|
24
|
+
|
|
25
|
+
**Why deferred.** [The reason it isn't in current scope. Be specific: "scope cut to ship M0 by Q3"; "depends on X landing first"; "waiting for user feedback on whether this is actually needed"; "lower priority than the M0 critical path".]
|
|
26
|
+
|
|
27
|
+
**Scope.** [What this item actually includes when it eventually gets built. Sketch enough that a future planner can pick it up cold. Bullet points are fine.]
|
|
28
|
+
|
|
29
|
+
**Depends on.** [Optional. Other backlog items, milestones, or upstream features that need to land first. Drop the field if nothing.]
|
|
30
|
+
|
|
31
|
+
**Re-evaluate when.** [The trigger that promotes this from backlog to active work. Tie to a milestone boundary, a metric, or an external event.]
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## B2 — [Title]
|
|
36
|
+
|
|
37
|
+
(same format)
|
|
38
|
+
|
|
39
|
+
---
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Decisions
|
|
2
|
+
|
|
3
|
+
This file is the **append-only ledger of resolved decisions**. Every decision the brainstorm produces lands here, with the reasoning that future-you will need to judge edge cases.
|
|
4
|
+
|
|
5
|
+
Each entry has these load-bearing fields:
|
|
6
|
+
|
|
7
|
+
- **Status** — `tentative | committed | rescinded`. New decisions land as `tentative` (no cascade dispatched, question stays open in `questions.md`). User explicitly says "commit" to lock in (cascade fires, question deletes). User explicitly says "rescind" to reverse (cascade reversals if previously committed, question restored if needed).
|
|
8
|
+
- **Decision** — what was decided, in one or two sentences.
|
|
9
|
+
- **Why** — the motivation: a past incident, a constraint, a deadline, a stakeholder ask. Without the *why*, decisions decay into rules no one understands.
|
|
10
|
+
- **How to apply** — when and where this decision should shape future work. Without it, decisions get ignored at the boundaries where they matter most.
|
|
11
|
+
|
|
12
|
+
This file is **append-only**. If a decision is reversed, mark it `STATUS: rescinded` with the reason — do not delete the entry. The ledger is a record of what was true (or proposed) when it was written. It is one of the four places inside the brainstorm folder where past tense is permitted (the others: `rejected.md`, `references.md`, git history).
|
|
13
|
+
|
|
14
|
+
When a question in `questions.md` is resolved, the question is **NOT** immediately deleted — it is marked tentatively-answered (referenced by the new decision's `Resolves Q-N` field). The question is deleted only when the decision transitions to `committed`. This gives the user space to reverse a tentative call without restoring text by hand.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## D1 — [Title]
|
|
19
|
+
|
|
20
|
+
**Status.** tentative
|
|
21
|
+
|
|
22
|
+
**Decision.** [What was decided, in one or two sentences.]
|
|
23
|
+
|
|
24
|
+
**Why.** [The motivation — past incident, constraint, deadline, stakeholder ask. The reason future-you needs to judge edge cases.]
|
|
25
|
+
|
|
26
|
+
**How to apply.** [When and where this decision shapes future work. Be specific — name the files, layers, or situations where this rule kicks in.]
|
|
27
|
+
|
|
28
|
+
**Resolves.** Q1 (deleted from `questions.md` on commit).
|
|
29
|
+
|
|
30
|
+
**Alternatives considered.** [Optional. Reference `rejected.md` entries if substantial. Skip if obvious.]
|
|
31
|
+
|
|
32
|
+
**Committed on.** [YYYY-MM-DD — filled when STATUS transitions to committed. Omit until then.]
|
|
33
|
+
|
|
34
|
+
**Rescinded on.** [YYYY-MM-DD with one-line reason — filled when STATUS transitions to rescinded. Omit until then.]
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## D2 — [Title]
|
|
39
|
+
|
|
40
|
+
(same format)
|
|
41
|
+
|
|
42
|
+
---
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Doctrine
|
|
2
|
+
|
|
3
|
+
This file holds **stable principles that pre-answer future questions**. When a new question arises during a brainstorm, check here first — the doctrine may already settle it without a full debate.
|
|
4
|
+
|
|
5
|
+
Doctrine entries should be **rare and durable**. They are not preferences ("I like Postgres") and not one-off picks ("we picked Temporal for this project"). They are statements that apply across many decisions: *"we never self-host stateful services in M0–M3 because operating burden outweighs cost savings at our scale."* A doctrine that gets revised every other week isn't doctrine — it's a preference in disguise. Demote it to `decisions.md`.
|
|
6
|
+
|
|
7
|
+
Add to doctrine only when a principle has either (a) been validated across multiple decisions in this project or others, or (b) is imposed from outside (compliance, vendor lock-in, team size) and won't change without a major shift. Doctrine pre-empts argument; if you're not confident the principle will hold for the next six months, don't write it here.
|
|
8
|
+
|
|
9
|
+
Each entry carries **Principle** (the one-line statement), **Why** (the reason this is principle, not preference — often a past incident, a hard constraint, or an accepted tradeoff), and **Applies when** (the triggers, so a reader recognizes "ah, this is a doctrine question" rather than re-debating from scratch). An optional **Exceptions** field is allowed but suspicious — if a principle has many exceptions, it's mis-stated.
|
|
10
|
+
|
|
11
|
+
Examples of real doctrine entries from past projects: *"Temporal IS the trace — no separate APM tool."* — *"No Terraform; deploys are wrangler + GitHub Actions only."* — *"Secrets only via wrangler, never in code or env files."* — *"Buy-not-build for non-core capabilities until paying-customer signal justifies otherwise."*
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## P1 — [Principle name]
|
|
16
|
+
|
|
17
|
+
**Principle.** [One-line statement of the rule.]
|
|
18
|
+
|
|
19
|
+
**Why.** [The reason this is a principle, not a preference. Often a past incident, a hard constraint, or a tradeoff the team has already accepted.]
|
|
20
|
+
|
|
21
|
+
**Applies when.** [Triggers — situations where this principle should be invoked.]
|
|
22
|
+
|
|
23
|
+
**Exceptions.** [Optional. Cases where the principle deliberately does not apply. If you find yourself listing many exceptions, the principle is probably mis-stated.]
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## P2 — [Principle name]
|
|
28
|
+
|
|
29
|
+
(same format)
|
|
30
|
+
|
|
31
|
+
---
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
This file collects **terms with project-specific meaning** — words whose definition in this project diverges from their general industry sense, or whose meaning is short and opaque enough that re-explaining it across docs wastes time.
|
|
4
|
+
|
|
5
|
+
The glossary exists to prevent the quietest and most expensive kind of design drift: two collaborators using the same word for different things. By the time you notice — usually mid-implementation — the cost of resolving the ambiguity is much higher than the cost of writing the entry that would have prevented it. So when you catch yourself saying "by X I mean…" for the second time, add the entry.
|
|
6
|
+
|
|
7
|
+
Do **not** catalog every term. Add to the glossary only when:
|
|
8
|
+
- A term has been used to mean two different things in the same session.
|
|
9
|
+
- A term's meaning here diverges from the standard industry sense (e.g., `subscriber` meaning a webhook destination rather than a pub/sub consumer).
|
|
10
|
+
- A short term names a specific concept that would otherwise need re-defining across docs (e.g., a node category name, an internal product term).
|
|
11
|
+
|
|
12
|
+
Entries are intentionally terse: one term, one line of meaning. Long explanations belong in plan docs or `decisions.md`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
| Term | Meaning |
|
|
17
|
+
|---|---|
|
|
18
|
+
| (example: `studio`) | the canonical task queue for non-publish work — see `04-runtime.md` |
|
|
19
|
+
| (example: `subscriber`) | a webhook destination registered against an event kind, distinct from a `webhook` which is the inbound side |
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Inventory
|
|
2
|
+
|
|
3
|
+
This file is the **authoritative list of components in scope** — services, repos, packages, databases, external integrations. It answers the question "what are we actually building?" and stops the team from inventing services that already exist or "folding in" things that should stay separate.
|
|
4
|
+
|
|
5
|
+
The inventory is grouped by category (application monorepo, edge services, shared packages, managed externals, reference-only prior art). Each entry carries a **status**:
|
|
6
|
+
|
|
7
|
+
- **build** — in scope, we're constructing this in this project.
|
|
8
|
+
- **external** — managed elsewhere (third-party SaaS, another team's service). We integrate with it but don't own it.
|
|
9
|
+
- **reference** — prior art we read or copy patterns from but do not deploy.
|
|
10
|
+
|
|
11
|
+
Do **not** mark items as "retired", "deprecated", or "previously planned" — if it's not being built or used, omit it. (See the greenfield doctrine.) The inventory describes the steady state, not the history of how the steady state was arrived at.
|
|
12
|
+
|
|
13
|
+
When scope changes (a service moves from "build" to "external", a non-goal flips to a build, a planned component gets dropped), update this file immediately and run a semantic sweep across plan docs.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## A. Application monorepo
|
|
18
|
+
|
|
19
|
+
| Name | Status | Notes |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| (example: `apps/gateway`) | build | (one-line role) |
|
|
22
|
+
| (example: `apps/web`) | build | (one-line role) |
|
|
23
|
+
|
|
24
|
+
## B. Edge services
|
|
25
|
+
|
|
26
|
+
| Name | Status | Notes |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
|
|
29
|
+
## C. Shared packages
|
|
30
|
+
|
|
31
|
+
| Name | Status | Notes |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
|
|
34
|
+
## D. Managed externals
|
|
35
|
+
|
|
36
|
+
| Name | Status | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| (example: Temporal Cloud) | external | (one-line — what we use it for) |
|
|
39
|
+
|
|
40
|
+
## E. Reference / prior art
|
|
41
|
+
|
|
42
|
+
| Name | Status | Notes |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| (example: `~/dev/vibe/foo-poc`) | reference | (what pattern we borrow from it) |
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Milestones
|
|
2
|
+
|
|
3
|
+
This file holds **sequencing only** — what ships in what order, with the dependencies that justify the order. Scope of each milestone lives in the plan docs; this file is the schedule.
|
|
4
|
+
|
|
5
|
+
Every milestone names three things: a **Goal** (one line — what this milestone proves or unlocks), **Depends on** (the prior milestones, or "nothing" for M0), and **Open questions** (Q-numbers from `questions.md` that must be resolved before this milestone can start). The open-questions list is what makes a milestone "ready to start" — when the list is empty, the milestone is unblocked.
|
|
6
|
+
|
|
7
|
+
The **Ships** field captures the concrete artifact: "auth + empty dashboard deployed to staging" is useful; "MVP foundation" is not. Concrete ship definitions make it visible when a milestone has crept.
|
|
8
|
+
|
|
9
|
+
Order matters and the order is enforced by `Depends on`. If you ever notice that M3 could ship before M2, the sequencing is wrong — fix it here. Milestones do not exist to chunk work into nice-sized bites; they exist to make dependency order explicit so the team can parallelize what's parallelizable and serialize what isn't.
|
|
10
|
+
|
|
11
|
+
When a milestone ships, do **not** mark it "complete" with a strikethrough or "(shipped)" marker. The plan docs for that milestone should already describe the steady state in present tense; the milestone entry stays here as schedule, not as history. (Git tags and PR history capture "what shipped when" — this file is forward-looking.)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## M0 — [Name]
|
|
16
|
+
|
|
17
|
+
**Goal.** [One-line — what this milestone proves or unlocks.]
|
|
18
|
+
|
|
19
|
+
**Depends on.** Nothing (this is the start).
|
|
20
|
+
|
|
21
|
+
**Open questions.** Q1, Q2, Q3 — see `questions.md`.
|
|
22
|
+
|
|
23
|
+
**Ships.** [Concrete deployed artifact.]
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## M1 — [Name]
|
|
28
|
+
|
|
29
|
+
**Goal.** [One-line.]
|
|
30
|
+
|
|
31
|
+
**Depends on.** M0.
|
|
32
|
+
|
|
33
|
+
**Open questions.** Q4, Q5 — see `questions.md`.
|
|
34
|
+
|
|
35
|
+
**Ships.** [Concrete deployed artifact.]
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## M2 — [Name]
|
|
40
|
+
|
|
41
|
+
(same format)
|
|
42
|
+
|
|
43
|
+
---
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Non-goals
|
|
2
|
+
|
|
3
|
+
This file is the **explicit list of things we are not building** in the current scope, with the reason for each. It is the mirror of `inventory.md`: where inventory says "this is in scope", non-goals say "this looked plausible but is deliberately out".
|
|
4
|
+
|
|
5
|
+
Non-goals carry real weight. Every entry here is a constraint that future decisions should respect — a scope-creep guard. The reason field is load-bearing: without it, a non-goal looks like an arbitrary "no" that future-you will second-guess at the first complication. With the reason, future-you knows whether the non-goal still holds when circumstances change.
|
|
6
|
+
|
|
7
|
+
Each non-goal should include a **Re-evaluate when** clause where applicable. Non-goals are not permanent vows; they are scope decisions tied to current constraints. When the constraint changes (a customer signs in a new region, a competitor ships the feature, infrastructure costs drop), the non-goal may move into scope. The re-evaluate clause names the trigger so the team doesn't carry a stale non-goal forever.
|
|
8
|
+
|
|
9
|
+
At milestone boundaries, scan this file. If a non-goal's re-evaluate trigger has fired, move the item to `inventory.md` with status `build` and delete the non-goal entry here — do not strikethrough, do not leave a "(promoted)" marker.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
- **No multi-region writes in M0.**
|
|
14
|
+
*Reason:* cost > benefit until 3+ paying customers in distinct regions.
|
|
15
|
+
*Re-evaluate when:* second paying customer signs in a non-primary region.
|
|
16
|
+
|
|
17
|
+
- **No mobile app.**
|
|
18
|
+
*Reason:* product hypothesis is desktop-first; no validated mobile demand.
|
|
19
|
+
*Re-evaluate when:* >20% of dashboard sessions are mobile UA.
|
|
20
|
+
|
|
21
|
+
- (add more here)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# NN — [Domain name]
|
|
2
|
+
|
|
3
|
+
> This is a **plan doc**, not a pillar. It describes one domain of the system (e.g., runtime, storage, ingress) in present tense, as if the chosen design were always the plan. Plan docs do not host their own "open questions" sections — those live in `pillars/questions.md`. Plan docs do not narrate the design journey — that lives in `pillars/decisions.md` and `pillars/rejected.md`. Plan docs describe what the system is.
|
|
4
|
+
>
|
|
5
|
+
> Number plan docs sequentially: `01-foo.md`, `02-bar.md`, ... Each plan doc owns one domain. If a section grows past ~500 lines, split it into two plan docs rather than letting it sprawl.
|
|
6
|
+
>
|
|
7
|
+
> Cross-reference other plan docs with `see 04 §3.2` — pointer, not duplicated content.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## On versioning iterations
|
|
12
|
+
|
|
13
|
+
If this plan doc goes through a substantial rewrite (decision reversal, structural shift, ≥3 sections change together), preserve the evolution by saving a new version as `NN-domain-v0.X.md` rather than overwriting. Examples:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
01-architecture-v0.1.md ← initial draft
|
|
17
|
+
01-architecture-v0.2.md ← second draft after architecture change
|
|
18
|
+
01-architecture-v0.3.md ← current draft (the one to read)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Each version stays in the folder. Readers can follow v0.1 → v0.2 → v0.3 in order to see exactly how the design evolved. The current version's top-of-file frontmatter or first line notes its status:
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
# 01 — Architecture (v0.3)
|
|
25
|
+
|
|
26
|
+
> **Status:** Current draft. Supersedes v0.1 and v0.2. v0.4 will narrow content.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Skip versioning for small edits (typos, single-section polish, find-and-replace). The versioning pattern is for substantial rewrites that warrant a separate readable artifact.
|
|
30
|
+
|
|
31
|
+
The `stop` step in the brainstorm offers to prune older versions if you want to simplify the final handoff. Keeping them preserves the design rationale across long sessions; pruning them produces a clean steady-state.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 1. What this is
|
|
36
|
+
|
|
37
|
+
[One paragraph in present tense describing what this domain is, what it does, and who depends on it. No "we decided" framing, no comparisons to alternatives.]
|
|
38
|
+
|
|
39
|
+
## 2. Components
|
|
40
|
+
|
|
41
|
+
[Subsystems, services, or modules inside this domain. Each gets a subsection with: name, role, what it owns, what it depends on. Diagrams are OK if they help.]
|
|
42
|
+
|
|
43
|
+
## 3. Interfaces
|
|
44
|
+
|
|
45
|
+
[How other domains interact with this one. APIs, queues, events, file formats. Stable contracts only — speculative ones go in `pillars/questions.md`.]
|
|
46
|
+
|
|
47
|
+
## 4. Constraints accepted
|
|
48
|
+
|
|
49
|
+
[Tradeoffs that shape the design. Phrased as current fact: "we accept a 5-second lag for predictable throughput", not "we considered streaming but chose batch".]
|
|
50
|
+
|
|
51
|
+
## 5. Future scope (optional)
|
|
52
|
+
|
|
53
|
+
[Cleanly labelled phase-2 ideas. Not framed as migrations. Skip the section if there's nothing here.]
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Open questions for this domain
|
|
58
|
+
|
|
59
|
+
See [`pillars/questions.md`](./pillars/questions.md): Q-N, Q-M, ...
|
|
60
|
+
|
|
61
|
+
(One line, never more. The plan doc never hosts question bodies.)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Open Questions
|
|
2
|
+
|
|
3
|
+
This file is the **live ledger of unresolved concerns and pending decisions**. Every open design question or worry lives here, and only here — plan docs never host their own questions, they link back to this file with the relevant Q-numbers.
|
|
4
|
+
|
|
5
|
+
Each question is **self-contained**: full text, optional options, optional lean, and where the resolution lands. You should be able to read any question and understand it without opening another doc. Duplicating one paragraph of context is much cheaper than the cognitive cost of context-switching.
|
|
6
|
+
|
|
7
|
+
**In Explore mode**, questions land here in the user's framing — possibly just a concern stated in prose, without Options or Lean. That is fine. Captured concerns are valid questions even when their shape is fuzzy. Resist the urge to immediately structure them into A/B/C/D choices; that happens when the user invites decide-mode for a specific question.
|
|
8
|
+
|
|
9
|
+
When a question transitions through a decision flow:
|
|
10
|
+
1. User signals "let's resolve Q-N" → enter decide mode for this Q.
|
|
11
|
+
2. Decision lands in `decisions.md` with `STATUS: tentative`. **The question stays here**, in a tentatively-answered state (cross-reference the D-N).
|
|
12
|
+
3. User says "commit D-N" → the question is **deleted** from this file. No strikethrough, no "(resolved)" marker.
|
|
13
|
+
4. User says "rescind D-N" before commit → the question stays, the decision is marked rescinded.
|
|
14
|
+
|
|
15
|
+
When you add a new question, fill in fields the user has actually given you. Leave others blank. The dependency graph (`Blocks.` field) is computed only when the user moves into decide mode and needs sequencing.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Conventions
|
|
20
|
+
|
|
21
|
+
**Group questions by domain** when the list grows past ~10 entries. Use `## Category` headers (e.g. `## Data & Schema`, `## Runtime`, `## Connectors`). Categories are project-specific.
|
|
22
|
+
|
|
23
|
+
**Question ID** is `QN` where N is the next free integer. IDs are stable for as long as the question is open. On commit-delete, the ID disappears with the question — do not reuse it.
|
|
24
|
+
|
|
25
|
+
**Question body fields** (per entry):
|
|
26
|
+
|
|
27
|
+
- **Question.** Full prose, may be multi-paragraph. Repeat context if needed. Use the user's words when capturing in Explore mode.
|
|
28
|
+
- **Options.** *(optional)* Lettered list (A / B / C ...) with one-line description per option. Add only when the user has named alternatives, or when entering decide mode for this question.
|
|
29
|
+
- **Lean.** *(optional)* The user's current preference, one line. Drop the field entirely if no lean exists yet — don't write "none yet". This field reflects the user's lean, not the skill's.
|
|
30
|
+
- **Claude's take.** *(optional, OPT-IN ONLY)* The skill's recommendation. **Default: do not write this field.** Emit only when the user explicitly asks "what would you recommend?" / "what's your take?" / similar on this specific question. Phrase as a clear pick + one-line reason. If the field becomes stale (options change, scope shifts), delete it.
|
|
31
|
+
- **Tentatively answered by.** *(only when a tentative D-N exists)* Cross-reference to `decisions.md`. Marks the question as in-flight rather than fully open.
|
|
32
|
+
- **Resolution lands in.** *(optional)* Target doc + section (e.g. `04-runtime.md §3.2`). Tells the resolver where to absorb the answer.
|
|
33
|
+
- **Blocks.** *(optional)* Milestone (`M0`) or other Q-numbers (`Q5, Q7`) that depend on this. Empty = "nothing yet".
|
|
34
|
+
|
|
35
|
+
**Extension sections** beyond plain questions are allowed:
|
|
36
|
+
|
|
37
|
+
- `## Upstream feature requests` — items that aren't questions we own; they're features we need from upstream services. Use IDs like `U-foo-1`.
|
|
38
|
+
- `## Doc completeness follow-ups` — work items that aren't decisions but should not be forgotten. Use IDs like `F1`, `F2`.
|
|
39
|
+
|
|
40
|
+
Resolved upstream-feature items and completed follow-ups get **deleted**, same rule as questions.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Q1 — [Title]
|
|
45
|
+
|
|
46
|
+
**Question.** [Full text. Repeat context if needed — a future reader should be able to read this without leaving the doc. In Explore mode, capture in the user's words.]
|
|
47
|
+
|
|
48
|
+
**Options.** *(optional — only when named by the user or entering decide mode)*
|
|
49
|
+
- A. [Option A — what it means in one line]
|
|
50
|
+
- B. [Option B]
|
|
51
|
+
- C. [Option C]
|
|
52
|
+
|
|
53
|
+
**Lean.** *(optional, user's lean)*
|
|
54
|
+
|
|
55
|
+
**Tentatively answered by.** *(only if a tentative D-N exists)*
|
|
56
|
+
|
|
57
|
+
**Resolution lands in.** *(optional)* `XX-foo.md` §N
|
|
58
|
+
|
|
59
|
+
**Blocks.** *(optional)* [Milestone (e.g., M0) or other Q-numbers.]
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Q2 — [Title]
|
|
64
|
+
|
|
65
|
+
(same format)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Upstream feature requests *(optional section)*
|
|
70
|
+
|
|
71
|
+
### U-foo-1 — [Title]
|
|
72
|
+
|
|
73
|
+
[What we want from the upstream service.]
|
|
74
|
+
|
|
75
|
+
**Why we want it.** [Reason — usually a current workaround that's costing us something.]
|
|
76
|
+
|
|
77
|
+
[Current status: filed, tracked, ETA, etc.]
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Doc completeness follow-ups *(optional section)*
|
|
82
|
+
|
|
83
|
+
- **F1** — [Doc name + one-line scope]. [What triggers writing it.] [Which milestone it must precede.]
|
|
84
|
+
- **F2** — [Doc name + one-line scope]. [What triggers writing it.] [Which milestone it must precede.]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# References
|
|
2
|
+
|
|
3
|
+
This file collects **external prior art** — repos, docs, papers, talks — with one-line pointers to what we use each for. Reference implementations beat invented solutions: if someone has already solved the problem you're about to design, the right move is to link it here and use it, not re-derive.
|
|
4
|
+
|
|
5
|
+
References are not bookmarks. Every entry should answer the question "what specific pattern, idea, or implementation do we lift from this?" A reference without that grounding decays into noise. If you can't write the one-line "what we use it for", you probably don't need the entry.
|
|
6
|
+
|
|
7
|
+
References to **source materials** copied into `./plan/sources/` during the session also live here — point at the local copy, not the original location. This keeps the brainstorm self-contained.
|
|
8
|
+
|
|
9
|
+
When a referenced thing changes (renames, moves, deprecation), **update or remove the entry**. A stale reference that no longer points at what the description claims is worse than no reference — it teaches the reader to distrust the file.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Internal repos / paths
|
|
14
|
+
|
|
15
|
+
- `~/path/to/repo` — [what pattern we borrow]
|
|
16
|
+
- `~/path/to/another` — [what pattern we borrow]
|
|
17
|
+
|
|
18
|
+
## Source materials (this session)
|
|
19
|
+
|
|
20
|
+
- `./plan/sources/[file]` — [original location, why it's relevant]
|
|
21
|
+
|
|
22
|
+
## External docs
|
|
23
|
+
|
|
24
|
+
- `https://example.com/foo` — [what we use it for]
|
|
25
|
+
|
|
26
|
+
## Papers / talks
|
|
27
|
+
|
|
28
|
+
- [Title] — [link or citation] — [the specific idea we're applying]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Rejected alternatives
|
|
2
|
+
|
|
3
|
+
This file captures **paths that were considered and rejected**, with the reason for rejection. Its purpose is to prevent re-litigation: when someone proposes the same alternative six weeks later, this file answers "we already looked at that; here's why we didn't go that way."
|
|
4
|
+
|
|
5
|
+
Each entry needs three load-bearing parts: **Considered** (what was proposed, in concrete terms), **Rejected because** (the specific reason — "didn't fit" is useless to future-you; name the constraint, the cost, the risk), and **Re-evaluate if** (what would need to change for the rejected path to become viable again). The re-evaluate field stops the rejection from looking permanent when it isn't — most rejections are scope-conditional, not absolute.
|
|
6
|
+
|
|
7
|
+
This is one of the four places inside the brainstorm folder where past tense and "we considered X" framing is permitted (the others: `decisions.md`, `references.md`, git history). The whole point of this file is to capture the path-not-taken so future architects don't have to re-discover it.
|
|
8
|
+
|
|
9
|
+
If circumstances change and a rejected path becomes attractive again, **do not silently revive it**. Add a new question to `questions.md` that references the rejection here, and resolve it explicitly. The new decision can override the rejection — but it should override, not pretend the rejection never happened.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## R1 — [Rejected option]
|
|
14
|
+
|
|
15
|
+
**Considered.** [What was proposed.]
|
|
16
|
+
|
|
17
|
+
**Rejected because.** [The reason. Be specific.]
|
|
18
|
+
|
|
19
|
+
**Re-evaluate if.** [What would change to make this viable.]
|
|
20
|
+
|
|
21
|
+
**Came up during.** [Q-number or D-number for context.]
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## R2 — [Rejected option]
|
|
26
|
+
|
|
27
|
+
(same format)
|
|
28
|
+
|
|
29
|
+
---
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow-mapper
|
|
3
3
|
description: Discover and document all major workflows in a codebase by tracing call chains from user action to database/external system. Produces mermaid sequence diagrams and markdown documentation. Use when the user asks to map workflows, trace flows, document sequences, understand how features work end-to-end, or generate architecture diagrams. Triggers on "map workflows", "trace workflows", "workflow diagram", "sequence diagram", "how does X work end-to-end", "document flows", "codebase workflows", "how does this feature work", "trace the request flow", "show me the call chain", "what happens when a user does X", "end-to-end flow".
|
|
4
|
+
plugins: [nurix-harness]
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Workflow Mapper Skill
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: kb-agi
|
|
3
|
+
description: Self-improving knowledge-base harness — a CLAUDE.md router (interview → ask/contribute) over a flat Obsidian note-vault, with single-intent upkeep agents that keep the vault trustworthy and grow it from its own query logs.
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
keywords:
|
|
6
|
+
- harness
|
|
7
|
+
- knowledge-base
|
|
8
|
+
- obsidian
|
|
9
|
+
- vault
|
|
10
|
+
- self-improving
|
|
11
|
+
- kb
|
|
12
|
+
- nurix
|
|
13
|
+
plugin: kb-agi
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# nuStack Knowledge Hub — router
|
|
2
17
|
|
|
3
18
|
This repo is a flat Obsidian vault that you read on the user's behalf. It's the bridge from the front (positioning, claims) to the back (product and service specs); detailed execution lives downstream in the service repos.
|
|
4
19
|
|
|
@@ -3,6 +3,7 @@ name: kb-agi-init
|
|
|
3
3
|
description: Initializes a kb-agi vault by scaffolding the meta/ control plane — the contract (guidance.md), the seed genre templates, the intent-index, and the sessions/ folder — from templates carried inline in this agent. Use on a fresh vault, or when the router reports that meta/guidance.md is missing. Triggers on "initialize kb-agi", "init the vault", "scaffold meta", "set up the control plane".
|
|
4
4
|
tools: Read, Glob, Bash, Write
|
|
5
5
|
model: inherit
|
|
6
|
+
plugins: [kb-agi]
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
You are the **kb-agi-init** agent. One job: stand up the `meta/` control plane a kb-agi vault needs to operate, then get out of the way. You run once per vault, and you are fully self-contained — every file you create is carried inline below, so you need no external templates.
|
|
@@ -150,7 +151,7 @@ Upkeep is run by the kb-agi agents (invoked by name); there is no `meta/goals/`
|
|
|
150
151
|
````markdown
|
|
151
152
|
# genre — Sales
|
|
152
153
|
|
|
153
|
-
The reader is positioning
|
|
154
|
+
The reader is positioning nuStack to someone else: a prospect, a partner, a teammate who needs the pitch. They want the claim and the proof behind it, not the implementation.
|
|
154
155
|
|
|
155
156
|
**Default depth.** Start crisp. Lead with the answer in one or two sentences — what we can do, what makes it different — then offer the supporting detail rather than front-loading it. Go deeper only when the question reaches for it ("how exactly…", "what's underneath…").
|
|
156
157
|
|
|
@@ -212,7 +213,7 @@ This is a living index. It is hand-maintained today and kept fresh by the `kb-re
|
|
|
212
213
|
---
|
|
213
214
|
|
|
214
215
|
## "I want to understand the product"
|
|
215
|
-
_What
|
|
216
|
+
_What nuStack is, what it can do, the claims and their proof._
|
|
216
217
|
|
|
217
218
|
- _populated on migration_
|
|
218
219
|
|
|
@@ -3,9 +3,10 @@ name: kb-catch-stale
|
|
|
3
3
|
description: Finds notes that have drifted out of date — a canonical note superseded by a newer one but never demoted, or a summary whose linked-down sources changed after it. Use to audit freshness. Reports by default; demotes/flags only when explicitly asked.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
5
|
model: inherit
|
|
6
|
+
plugins: [kb-agi]
|
|
6
7
|
---
|
|
7
8
|
|
|
8
|
-
You are the **kb-catch-stale** goal-agent for the
|
|
9
|
+
You are the **kb-catch-stale** goal-agent for the nuStack knowledge hub. One job: surface notes that have drifted out of date.
|
|
9
10
|
|
|
10
11
|
**Read first:** `meta/guidance.md` (the note model, `maturity` + `canonical` hints) — the contract that governs you. The procedure below is this agent's full, self-contained definition.
|
|
11
12
|
|