@nusoft/nuos-build-catalogue 0.12.0 → 0.14.1
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/dist/cli.js +54 -41
- package/dist/commands/init.d.ts +12 -2
- package/dist/commands/init.js +136 -74
- package/dist/commands/plan.d.ts +12 -0
- package/dist/commands/plan.js +83 -0
- package/dist/commands/write.js +16 -5
- package/dist/path-resolution.d.ts +68 -0
- package/dist/path-resolution.js +147 -0
- package/dist/runtime/ac-parse.js +10 -6
- package/dist/runtime/markdown-edit.d.ts +5 -0
- package/dist/runtime/markdown-edit.js +13 -6
- package/dist/runtime/mis-adapter.js +7 -2
- package/package.json +2 -2
- package/templates/hooks/install-hooks.sh +44 -0
- package/templates/hooks/post-commit +96 -0
- package/templates/hooks/pre-commit +162 -0
- package/templates/protocols/end-of-session.md +101 -13
- package/templates/protocols/persona-new.md +64 -30
- package/templates/protocols/plan-orientation.md +122 -0
- package/templates/protocols/start-of-session.md +52 -13
- package/templates/protocols/wu-new.md +75 -50
- package/templates/starter-kit/docs/build/GLOSSARY.md +115 -0
- package/templates/starter-kit/docs/build/STATE.md +30 -16
- package/templates/starter-kit/docs/build/WELCOME.md +79 -0
- package/templates/starter-kit/docs/build/architecture/_index.md +39 -0
- package/templates/starter-kit/docs/build/architecture/module-template.md +47 -0
- package/templates/starter-kit/docs/build/contracts/_index.md +39 -0
- package/templates/starter-kit/docs/build/contracts/contract-template.md +64 -0
- package/templates/starter-kit/docs/build/decisions/_index.md +21 -17
- package/templates/starter-kit/docs/build/design-system/_index.md +57 -0
- package/templates/starter-kit/docs/build/design-system/accessibility.md +77 -0
- package/templates/starter-kit/docs/build/design-system/components/_index.md +29 -0
- package/templates/starter-kit/docs/build/design-system/components/_template.md +60 -0
- package/templates/starter-kit/docs/build/design-system/patterns/_index.md +37 -0
- package/templates/starter-kit/docs/build/design-system/patterns/_template.md +57 -0
- package/templates/starter-kit/docs/build/design-system/tokens-colour.md +52 -0
- package/templates/starter-kit/docs/build/design-system/tokens-motion.md +42 -0
- package/templates/starter-kit/docs/build/design-system/tokens-radius-elevation.md +34 -0
- package/templates/starter-kit/docs/build/design-system/tokens-spacing.md +48 -0
- package/templates/starter-kit/docs/build/design-system/tokens-typography.md +46 -0
- package/templates/starter-kit/docs/build/design-system/voice.md +53 -0
- package/templates/starter-kit/docs/build/maps/01-template.md +15 -112
- package/templates/starter-kit/docs/build/maps/02-template.md +52 -0
- package/templates/starter-kit/docs/build/maps/03-template.md +46 -0
- package/templates/starter-kit/docs/build/maps/99-template-power-user-operational-plan.md +126 -0
- package/templates/starter-kit/docs/build/maps/_index.md +17 -52
- package/templates/starter-kit/docs/build/open-questions/_index.md +27 -13
- package/templates/starter-kit/docs/build/personas/_index.md +26 -60
- package/templates/starter-kit/docs/build/risks/_index.md +20 -13
- package/templates/starter-kit/docs/build/sessions/_index.md +18 -16
- package/templates/starter-kit/docs/build/ui-ux/_index.md +48 -0
- package/templates/starter-kit/docs/build/ui-ux/surface-template.md +72 -0
- package/templates/starter-kit/docs/build/work-units/001-template-simple.md +43 -0
- package/templates/starter-kit/docs/build/work-units/_index.md +18 -20
- package/templates/starter-kit/methodfile.json +19 -8
- /package/templates/starter-kit/docs/build/work-units/{001-template.md → 001-template-full.md} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# NuOS catalogue pre-commit hook (WU 111 enforcement phase).
|
|
4
|
+
#
|
|
5
|
+
# Catches drift before commit. After WU 111's Phase J ship, the
|
|
6
|
+
# accepted-decision rule has flipped from warning → block (per the
|
|
7
|
+
# pack's narrower-than-originally-planned enforcement scope, recorded
|
|
8
|
+
# in WU 111's "Forward-compatibility commitments" section). Other
|
|
9
|
+
# rules described in WU 128's original aggressive list are NOT shipping
|
|
10
|
+
# — distinguishing tool-written from human-written content was deemed
|
|
11
|
+
# overengineering for a planning-artefact catalogue.
|
|
12
|
+
#
|
|
13
|
+
# Active rules:
|
|
14
|
+
# 1. index-drift detection — every WU/decision/open-question/risk file
|
|
15
|
+
# must have a matching row in its _index.md (and vice versa)
|
|
16
|
+
# 2. active-decision modification block — modifying a committed
|
|
17
|
+
# `accepted` decision file is BLOCKED (not just warned). The
|
|
18
|
+
# discipline is to write a superseding D-NNN+1 and link forward.
|
|
19
|
+
# To deliberately fix a typo or link in an accepted decision,
|
|
20
|
+
# use `git commit --no-verify` (CLAUDE.md prohibits this for
|
|
21
|
+
# substantive changes; reserve it for typo-only fixes).
|
|
22
|
+
#
|
|
23
|
+
# Sentinel-protected sections (e.g. STATE.md's `nuos:sentinel`) remain
|
|
24
|
+
# protected via the existing `.claude/hooks/check-catalogue-write.sh`
|
|
25
|
+
# Claude Code hook. That rule continues unchanged at WU 111 ship.
|
|
26
|
+
#
|
|
27
|
+
# Bypass: this hook respects --no-verify like any other. The CLAUDE.md
|
|
28
|
+
# policy explicitly prohibits --no-verify use for substantive changes;
|
|
29
|
+
# the technical block fires at the CI server-side check (a future WU).
|
|
30
|
+
|
|
31
|
+
set -uo pipefail
|
|
32
|
+
|
|
33
|
+
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
34
|
+
ENFORCEMENT_LOG="$REPO_ROOT/.nuos-enforcement.log"
|
|
35
|
+
EXIT_CODE=0
|
|
36
|
+
|
|
37
|
+
red() { printf '\033[31m%s\033[0m\n' "$*"; }
|
|
38
|
+
yellow() { printf '\033[33m%s\033[0m\n' "$*"; }
|
|
39
|
+
green() { printf '\033[32m%s\033[0m\n' "$*"; }
|
|
40
|
+
dim() { printf '\033[2m%s\033[0m\n' "$*"; }
|
|
41
|
+
|
|
42
|
+
log_event() {
|
|
43
|
+
printf '%s | %s | %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$1" "$2" >> "$ENFORCEMENT_LOG"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# ---------- Generic index-drift checker ---------------------------------
|
|
47
|
+
#
|
|
48
|
+
# Args:
|
|
49
|
+
# $1 — kind label (for messages)
|
|
50
|
+
# $2 — directory (relative to repo root)
|
|
51
|
+
# $3 — _index.md path (relative to repo root)
|
|
52
|
+
# $4 — filename regex (matches IDs the directory contains)
|
|
53
|
+
# $5 — index-row ID regex (a Perl-compatible regex that anchors on the
|
|
54
|
+
# leftmost column of an index table row)
|
|
55
|
+
#
|
|
56
|
+
# The two regexes must extract the SAME set of IDs (e.g. "001", "030g",
|
|
57
|
+
# "D042") so set comparison works.
|
|
58
|
+
|
|
59
|
+
check_index_drift() {
|
|
60
|
+
local kind="$1" dir="$2" index="$3" file_regex="$4" row_regex="$5"
|
|
61
|
+
|
|
62
|
+
if [[ ! -d "$REPO_ROOT/$dir" ]]; then return 0; fi
|
|
63
|
+
if [[ ! -f "$REPO_ROOT/$index" ]]; then return 0; fi
|
|
64
|
+
|
|
65
|
+
# IDs extracted from filenames in the directory (top-level + one subdir
|
|
66
|
+
# like done/, resolved/, superseded/)
|
|
67
|
+
local ids_in_tree
|
|
68
|
+
ids_in_tree=$(cd "$REPO_ROOT/$dir" && {
|
|
69
|
+
find . -maxdepth 2 -type f -name "*.md" \
|
|
70
|
+
-not -name "_index.md" \
|
|
71
|
+
-not -name "*-template.md" 2>/dev/null \
|
|
72
|
+
| sed -nE "$file_regex" \
|
|
73
|
+
| sort -u
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
# IDs extracted from leftmost column of table rows in the index
|
|
77
|
+
local ids_in_index
|
|
78
|
+
ids_in_index=$(sed -nE "$row_regex" "$REPO_ROOT/$index" | sort -u)
|
|
79
|
+
|
|
80
|
+
local missing_from_index
|
|
81
|
+
missing_from_index=$(comm -23 <(printf '%s\n' "$ids_in_tree") <(printf '%s\n' "$ids_in_index"))
|
|
82
|
+
|
|
83
|
+
if [[ -n "$missing_from_index" ]]; then
|
|
84
|
+
red "✖ index-drift ($kind): on disk but missing from $index:"
|
|
85
|
+
while IFS= read -r id; do echo " — $id"; done <<< "$missing_from_index"
|
|
86
|
+
log_event "index-drift" "$kind missing from index: $(echo "$missing_from_index" | tr '\n' ',')"
|
|
87
|
+
EXIT_CODE=1
|
|
88
|
+
fi
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
dim "[nuos:pre-commit] index-drift check"
|
|
92
|
+
|
|
93
|
+
# Note: BSD sed (macOS default) is fussy about `|` as both delimiter and
|
|
94
|
+
# regex content. Using `#` as the s/// delimiter sidesteps the collision.
|
|
95
|
+
|
|
96
|
+
# Work units: filenames are NNN-slug.md or NNNa-slug.md (with optional letter).
|
|
97
|
+
# Index rows are `| NNN |` or `| NNNa |` in the leftmost column.
|
|
98
|
+
check_index_drift \
|
|
99
|
+
"work-units" \
|
|
100
|
+
"docs/build/work-units" \
|
|
101
|
+
"docs/build/work-units/_index.md" \
|
|
102
|
+
's#^\./(done/)?([0-9]{3}[a-z]?)-[^/]*\.md$#\2#p' \
|
|
103
|
+
's#^\| ([0-9]{3}[a-z]?) \|.*$#\1#p'
|
|
104
|
+
|
|
105
|
+
# Decisions: filenames are DNNN-slug.md.
|
|
106
|
+
# Index rows: `| DNNN |` or `| [DNNN](...) |`.
|
|
107
|
+
check_index_drift \
|
|
108
|
+
"decisions" \
|
|
109
|
+
"docs/build/decisions" \
|
|
110
|
+
"docs/build/decisions/_index.md" \
|
|
111
|
+
's#^\./(done/|superseded/)?(D[0-9]{3})-[^/]*\.md$#\2#p' \
|
|
112
|
+
's#^\| \[?(D[0-9]{3}).*$#\1#p'
|
|
113
|
+
|
|
114
|
+
# Open questions: filenames are QNNN-slug.md.
|
|
115
|
+
check_index_drift \
|
|
116
|
+
"open-questions" \
|
|
117
|
+
"docs/build/open-questions" \
|
|
118
|
+
"docs/build/open-questions/_index.md" \
|
|
119
|
+
's#^\./(resolved/)?(Q[0-9]{3})-[^/]*\.md$#\2#p' \
|
|
120
|
+
's#^\| \[?(Q[0-9]{3}).*$#\1#p'
|
|
121
|
+
|
|
122
|
+
# Risks: per current convention, individual risk files are inline in
|
|
123
|
+
# risks/_index.md (no per-risk .md files yet). Skip the check entirely
|
|
124
|
+
# until that pattern changes.
|
|
125
|
+
if compgen -G "$REPO_ROOT/docs/build/risks/R[0-9][0-9][0-9]-*.md" > /dev/null; then
|
|
126
|
+
check_index_drift \
|
|
127
|
+
"risks" \
|
|
128
|
+
"docs/build/risks" \
|
|
129
|
+
"docs/build/risks/_index.md" \
|
|
130
|
+
's#^\./(R[0-9]{3})-[^/]*\.md$#\1#p' \
|
|
131
|
+
's#^\| \[?(R[0-9]{3}).*$#\1#p'
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# ---------- Rule 2: active-decision modification block (WU 111 ship) ---
|
|
135
|
+
|
|
136
|
+
dim "[nuos:pre-commit] active-decision modification check"
|
|
137
|
+
modified_decisions=$(git diff --cached --name-only --diff-filter=M \
|
|
138
|
+
| grep -E '^docs/build/decisions/D[0-9]+.*\.md$' \
|
|
139
|
+
| grep -v '/superseded/' \
|
|
140
|
+
|| true)
|
|
141
|
+
|
|
142
|
+
if [[ -n "$modified_decisions" ]]; then
|
|
143
|
+
red "✖ active-decision modification — BLOCKED (WU 111 enforcement):"
|
|
144
|
+
while IFS= read -r f; do echo " — $f"; done <<< "$modified_decisions"
|
|
145
|
+
red " Decisions are immutable once accepted. The discipline is to write a"
|
|
146
|
+
red " superseding D-NNN+1 and link forward. Use:"
|
|
147
|
+
red " nuos-catalogue decision supersede <target> --by=<new-D> --reason=\"...\""
|
|
148
|
+
red ""
|
|
149
|
+
red " If this edit is a non-substantive typo fix or link cleanup that does"
|
|
150
|
+
red " not change the decision's meaning, you may bypass this block with"
|
|
151
|
+
red " --no-verify. CLAUDE.md prohibits --no-verify for substantive changes."
|
|
152
|
+
log_event "active-decision-block" "$(echo "$modified_decisions" | tr '\n' ',')"
|
|
153
|
+
EXIT_CODE=1
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# ---------- Result ------------------------------------------------------
|
|
157
|
+
|
|
158
|
+
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
159
|
+
green "[nuos:pre-commit] all rules pass (WU 111 enforcement)"
|
|
160
|
+
log_event "pre-commit-pass" "$(git diff --cached --name-only | wc -l | tr -d ' ') files"
|
|
161
|
+
fi
|
|
162
|
+
exit $EXIT_CODE
|
|
@@ -1,19 +1,107 @@
|
|
|
1
1
|
# end-of-session
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
You are ending a session on a project that uses the **NuOS Build Method catalogue**. Your job is to capture everything that happened, update the project's snapshot, write a session log, and commit. **Without this, work is lost. The whole catalogue is built on the assumption that every period of work gets captured before it closes.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**The operator is most likely a domain expert, not a software engineer.** Plain English throughout. Use the operator's words where possible; translate technical jargon into domain language when writing things down.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
2. **Capture any new decisions** as `docs/build/decisions/D<NNN>-<slug>.md` files plus an entry in `decisions/_index.md`.
|
|
9
|
-
3. **Capture any new open questions** as `docs/build/open-questions/Q<NNN>-<slug>.md` files plus an entry in `open-questions/_index.md`. If a question was both raised AND resolved this session, capture it as a decision instead.
|
|
10
|
-
4. **Capture any new risks** as entries in `docs/build/risks/_index.md`.
|
|
11
|
-
5. **Update the work-units index.** Confirm status icons reflect reality. **When a WU promotes to ✅, move its file from `work-units/<NNN>-<slug>.md` to `work-units/done/<NNN>-<slug>.md` and update the row link in `_index.md` to point at `done/<file>`.** Fix internal relative paths in the moved file (one level deeper after the move).
|
|
12
|
-
6. **Update `STATE.md`.** Refresh: last-updated date, last-session reference, active work unit, "What was just done", "What is next" if priorities shifted, decisions/questions/risks tables.
|
|
13
|
-
7. **Write a session log entry** in `docs/build/sessions/<YYYY-MM-DD>-<slug>.md`. Add a row to `sessions/_index.md`.
|
|
14
|
-
8. **Verify nothing is lost.** Every decision has a file + index entry. Every question has a file + index entry. Every risk has an index entry. STATE.md reflects current state. Cross-references resolve. Dates are right.
|
|
15
|
-
9. **Commit.** A single commit with the message `end-of-session: <YYYY-MM-DD> — <one-line summary>`. The pre-commit hook (per WU 128) will validate index integrity on the way through; if it blocks, fix the underlying drift, do not bypass with `--no-verify`.
|
|
7
|
+
---
|
|
16
8
|
|
|
17
|
-
|
|
9
|
+
## Steps
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
### 1. Update the active work unit's notes section (or the active planning phase's notes if mid-planning)
|
|
12
|
+
|
|
13
|
+
Append a dated entry to the active work unit's `## Notes / log` section. Capture:
|
|
14
|
+
|
|
15
|
+
- **What was attempted** — in their words, in plain language
|
|
16
|
+
- **What worked** — concrete and specific
|
|
17
|
+
- **What didn't work and why** — be honest; vague entries are worthless
|
|
18
|
+
- **What was learned** — anything generalisable; patterns starting to emerge
|
|
19
|
+
- **What the next concrete action should be** — specific enough that the next session can pick up without thinking
|
|
20
|
+
|
|
21
|
+
**The test:** could a future-you (or anyone joining the project) read this entry and answer *"why was this done, and what justifies the next step?"* without asking? If yes, the entry is sufficient. If you'd need to explain, write more.
|
|
22
|
+
|
|
23
|
+
### 2. File any new decisions made this session
|
|
24
|
+
|
|
25
|
+
If anything was decided in conversation — even if it felt obvious at the time — file it as a decision in `docs/build/decisions/`. Use the next available D-NNN number. Add a row to `decisions/_index.md`. Link from the active work unit if it shaped the work.
|
|
26
|
+
|
|
27
|
+
**This is non-negotiable.** Decisions made and not filed are drift. The catalogue's value is that what was decided is recorded.
|
|
28
|
+
|
|
29
|
+
### 3. File any new open questions raised
|
|
30
|
+
|
|
31
|
+
If something came up that needs deciding later, file it in `docs/build/open-questions/` as Q-NNN. Add a row to `open-questions/_index.md`. If a question was both raised AND resolved this session, skip the question file and just file the decision in step 2.
|
|
32
|
+
|
|
33
|
+
### 4. Note any new risks
|
|
34
|
+
|
|
35
|
+
If something to watch was identified, add a row to `docs/build/risks/_index.md`.
|
|
36
|
+
|
|
37
|
+
### 5. Update the work-units index
|
|
38
|
+
|
|
39
|
+
Confirm status icons reflect reality. When a work unit promotes to ✅ shipped:
|
|
40
|
+
|
|
41
|
+
- Move its file from `work-units/NNN-slug.md` to `work-units/done/NNN-slug.md`
|
|
42
|
+
- Update the row link in `_index.md` to point at `done/`
|
|
43
|
+
- Fix any internal relative paths in the moved file (they go one level deeper)
|
|
44
|
+
|
|
45
|
+
### 6. Update STATE.md
|
|
46
|
+
|
|
47
|
+
Refresh:
|
|
48
|
+
|
|
49
|
+
- **Last updated** — today's date
|
|
50
|
+
- **What is currently in flight** — the current state of work in one paragraph
|
|
51
|
+
- **What just shipped** — the most recent completion
|
|
52
|
+
- **What is next** — the immediate next action
|
|
53
|
+
- **Planning progress** — if a planning phase advanced, update its status here
|
|
54
|
+
- The decisions, questions, and active work units tables — pull the most recent rows from each register
|
|
55
|
+
|
|
56
|
+
### 7. Write a session log entry
|
|
57
|
+
|
|
58
|
+
Create `docs/build/sessions/YYYY-MM-DD-short-slug.md`. The entry includes:
|
|
59
|
+
|
|
60
|
+
- **What this session was about** — one paragraph
|
|
61
|
+
- **What was done** — chronological, in plain language; the story of the session
|
|
62
|
+
- **Decisions made** — linked to the D-NNN files filed this session
|
|
63
|
+
- **Open questions raised** — linked to Q-NNN files
|
|
64
|
+
- **Risks identified** — linked to R-NNN rows
|
|
65
|
+
- **What's next** — the concrete next action; what the next session should start with
|
|
66
|
+
- **Resume hint** — *critical if the session ended mid-task*. A one-paragraph note of exactly where you were and what was about to happen next, so the next session can pick up cleanly. Example: *"We were in Phase B of planning, working on the contract for the Overnight Consolidation module. Next: walk through the Planning Module contract."*
|
|
67
|
+
|
|
68
|
+
Add a row to `sessions/_index.md`.
|
|
69
|
+
|
|
70
|
+
### 8. Verify nothing is lost
|
|
71
|
+
|
|
72
|
+
Before committing, scan:
|
|
73
|
+
|
|
74
|
+
- Every decision filed has a D-NNN file AND an index entry
|
|
75
|
+
- Every open question filed has a Q-NNN file AND an index entry
|
|
76
|
+
- Every risk filed has an index row
|
|
77
|
+
- STATE.md reflects current state
|
|
78
|
+
- Cross-references resolve (no dead links)
|
|
79
|
+
- Dates are right
|
|
80
|
+
|
|
81
|
+
### 9. Commit
|
|
82
|
+
|
|
83
|
+
Single commit. Message format:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
end-of-session: YYYY-MM-DD — one-line summary
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The pre-commit hook validates index integrity on the way through. If it blocks, fix the underlying issue — don't bypass with `--no-verify`. The post-commit hook will refresh the search index in the background after the commit lands.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## What never to do
|
|
94
|
+
|
|
95
|
+
- **Never close a session without end-of-session running.** If you have to stop in a rush, at minimum write one paragraph into the active work unit's notes saying *"session ended without full end-of-session protocol; state is approximately X; outstanding actions Y"*. Then run the full protocol at the start of the next session before any new work.
|
|
96
|
+
|
|
97
|
+
- **Never bypass the pre-commit hook with `--no-verify` for substantive changes.** Typo fixes on accepted decisions are the only legitimate use. If the hook blocks you, something in the catalogue is inconsistent — fix it; don't paper over.
|
|
98
|
+
|
|
99
|
+
- **Never leave a decision in conversation rather than in a file.** *"We agreed to use X"* in chat is not a decision. The file is the decision; chat is the conversation that produced it.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Why this matters
|
|
104
|
+
|
|
105
|
+
The catalogue's compounding value comes from the accumulated record. Every session writes a small layer of context. Six months in, a new contributor — or future-you — opens the project and can read the path from origin to now. Drift is what makes that path unreadable. End-of-session is the protocol that prevents drift.
|
|
106
|
+
|
|
107
|
+
If end-of-session feels like ceremony, the project is fine; carry on. If end-of-session feels like the only thing standing between coherence and chaos, the catalogue is doing its job.
|
|
@@ -1,43 +1,77 @@
|
|
|
1
1
|
# persona-new
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
You are filing a new **persona** for a project that uses the **NuOS Build Method catalogue**. A persona is one specific person the project serves — not a market segment, not a demographic. One person with a name, a situation, and a reason to need what's being built.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**The operator is most likely a domain expert, not a software engineer.** Plain English throughout. Walk the operator through the persona in conversation — don't read out a form.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Step 1 — Open with the why
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
2. **Slugify the persona name** — lowercase, dashes for spaces, no special characters, max 60 chars.
|
|
13
|
-
3. **Generate the file** at `docs/build/personas/P<NNN>-<slug>.md` from the template at `starter-kit/docs/build/personas/001-template.md`. Replace placeholders with operator-supplied values.
|
|
14
|
-
4. **Prompt the operator for the seven dimensions:**
|
|
11
|
+
Briefly explain why we're doing this (one or two sentences):
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
- **2. Reality** — physical environment when they use the outcome. Device, connection quality, noise level, time pressure. Real conditions, not idealised ones.
|
|
18
|
-
- **3. Psychology** — technical confidence, stress level, tolerance for confusion. Will they read instructions or click around? Will they abandon if a page takes more than three seconds?
|
|
19
|
-
- **4. Trigger** — what brings them to this outcome. A real-world event, not a UI click. The event in their life that created the need.
|
|
20
|
-
- **5. History** — what they have done before arriving at this outcome. Returning user vs first-time visitor. Saved details vs no context.
|
|
21
|
-
- **6. Success** — what "done" looks like from *their* perspective. Not what the system logs — what they *feel*. This drives the design.
|
|
22
|
-
- **7. Constraints** — what they cannot or will not do. Defines the outer boundary of acceptable design.
|
|
13
|
+
> "I'll capture this person specifically so everything we build downstream can refer back to them. The point isn't to fill in a form — it's so that when we file a feature later, we can say 'this is for [name], in [their situation], when [their trigger happens]' and not have to re-explain who they are every time."
|
|
23
14
|
|
|
24
|
-
|
|
25
|
-
6. **Prompt for paired persona (if any).** If this persona's outcomes are paired with another's — a customer who books an event and an organiser who receives the booking — capture the paired P-NNN. If no pair exists yet, the operator may file the paired persona next via a second `persona-new` invocation.
|
|
26
|
-
7. **Apply the persona discipline checks:**
|
|
15
|
+
Then ask for their name. Even a made-up one is fine.
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
- **Does this persona have specific triggers, not just a demographic profile?** A persona without triggers is a character in search of a plot. Surface and prompt for refinement.
|
|
30
|
-
- **Is the acid-test the hardest legitimate combination, or only a slightly harder version of the easy case?** The acid-test must be uncomfortable to design for — that is its point.
|
|
17
|
+
## Step 2 — Walk the seven dimensions as conversation
|
|
31
18
|
|
|
32
|
-
|
|
33
|
-
9. **Surface to the operator:**
|
|
34
|
-
- The new persona file path (clickable)
|
|
35
|
-
- The row added to `_index.md`
|
|
36
|
-
- Any discipline checks that surfaced gaps (paired-persona suggestion; "this persona doesn't yet constrain a decision" warning)
|
|
37
|
-
- The next concrete action — typically: file a WU that serves this persona (`wu-new`), or file the paired persona
|
|
19
|
+
Don't list "the seven dimensions" to the operator. Weave them into questions. Below are the dimensions and a conversational prompt each. Adapt to the operator's flow — if they answer two dimensions in one breath, capture both and skip ahead.
|
|
38
20
|
|
|
39
|
-
**
|
|
21
|
+
1. **Identity** — *"Tell me about them in the context of this project. What's their role? What account do they have? What systems are they used to? Just enough that someone reading this knows who they are in relation to what we're building."*
|
|
40
22
|
|
|
41
|
-
|
|
23
|
+
2. **Reality** — *"Where are they when they need this? What device? Are they at their desk, on the school playground, on a train, at home? Time of day? Noise? Pressure?"*
|
|
42
24
|
|
|
43
|
-
|
|
25
|
+
3. **Psychology** — *"How tech-confident are they? Are they patient when things don't make sense, or do they abandon fast? How much energy do they have when they're using this?"*
|
|
26
|
+
|
|
27
|
+
4. **Trigger** — *"What's happening in their day that makes them need this? Not 'they open the app' — what comes before that? What's the moment in their life that creates the need?"*
|
|
28
|
+
|
|
29
|
+
5. **History** — *"What have they done already by the time they reach this? Are they a returning user with saved details, or is this fresh every time? What previous experiences shape what they expect?"*
|
|
30
|
+
|
|
31
|
+
6. **Success** — *"What does 'this worked' feel like from their side? Not what the system logs — what they actually feel. Relief? Confidence? Done with it?"*
|
|
32
|
+
|
|
33
|
+
7. **Constraints** — *"What can they not (or will they not) do? What's the hard edge of acceptable for this person?"*
|
|
34
|
+
|
|
35
|
+
## Step 3 — The acid-test refinement
|
|
36
|
+
|
|
37
|
+
Ask one more question:
|
|
38
|
+
|
|
39
|
+
> *"Now imagine the hardest legitimate version of this person — same role, same job, but with every realistic constraint at its worst at the same time. Slow device. Low confidence. Time pressure. Bad day. Tired. Distracted. The combination that's still real but makes everything harder. Design for that person and the easier cases hold."*
|
|
40
|
+
|
|
41
|
+
Capture the acid-test as the last dimension on the persona file.
|
|
42
|
+
|
|
43
|
+
## Step 4 — Discipline check (gentle)
|
|
44
|
+
|
|
45
|
+
Look at what you've captured. Two questions to surface (gently, in plain language):
|
|
46
|
+
|
|
47
|
+
- **Would swapping this person for a different one force you to change anything?** If no, the persona isn't constraining yet — ask one more sharpening question.
|
|
48
|
+
- **Are the triggers specific real-life moments, or just "uses the system"?** Vague triggers produce vague designs.
|
|
49
|
+
|
|
50
|
+
If either is weak, ask one more probing question — but don't force perfection. Captured-but-imperfect is much better than not captured.
|
|
51
|
+
|
|
52
|
+
## Step 5 — File the persona
|
|
53
|
+
|
|
54
|
+
1. **Number it.** Scan `docs/build/personas/` and `docs/build/personas/done/` for the highest P-NNN prefix; new number is max + 1.
|
|
55
|
+
2. **Slugify the name** — lowercase, dashes for spaces, no special characters, max 60 chars.
|
|
56
|
+
3. **Write the file** at `docs/build/personas/PNNN-slug.md`. Use the template at `docs/build/personas/001-template.md`. Fill in each dimension from the conversation.
|
|
57
|
+
4. **Add a row** to `docs/build/personas/_index.md`. Status `🟢 active`. "Used by" column stays empty until work units reference this persona.
|
|
58
|
+
|
|
59
|
+
## Step 6 — Tell the operator what happened
|
|
60
|
+
|
|
61
|
+
Plain English:
|
|
62
|
+
|
|
63
|
+
- Where the file landed (clickable path)
|
|
64
|
+
- Anything you noticed during the conversation (e.g. "you mentioned a colleague who reviews this work — is that a paired persona we should file separately?")
|
|
65
|
+
- The next concrete action — usually: file the paired persona if there is one; otherwise carry on with the active phase
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Why personas are first-class in this catalogue
|
|
70
|
+
|
|
71
|
+
Many projects describe their users in passing — a vague "teachers" or "users" mentioned inside a feature spec, different every time. That works for small projects. For projects with real complexity, it doesn't: every feature spec re-invents who it's for; downstream features can't be designed coherently against a moving target.
|
|
72
|
+
|
|
73
|
+
Personas as first-class catalogue entries fix this. **One sharp persona, referenced by stable handle, used across many work units over many months.** Every feature filed says who it's for by P-NNN handle. When the persona evolves, every reference updates with it.
|
|
74
|
+
|
|
75
|
+
The seven dimensions are what make a persona sharp enough to carry that weight. The acid-test is what makes the design robust. If the catalogue has decorative personas — ones that don't change any design decision — they're worse than no personas at all, because they create the illusion of constraint without supplying any.
|
|
76
|
+
|
|
77
|
+
If the operator skips a dimension because it feels obvious, accommodate but note what was skipped. A later work unit may need exactly that dimension and find it missing. The catalogue records what's decided AND what's not yet decided — both are load-bearing.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# plan-orientation
|
|
2
|
+
|
|
3
|
+
You are running **Phase A of the planning arc** for a project that just adopted the NuOS Build Method catalogue. This is the operator's first real conversation with the harness. By the end of this session they should have:
|
|
4
|
+
|
|
5
|
+
- A short, plain-English project description filed in `STATE.md`
|
|
6
|
+
- 1-3 personas filed in `docs/build/personas/`
|
|
7
|
+
- Map 1 — The Horizon — filed in `docs/build/maps/01-the-horizon.md`
|
|
8
|
+
- Initial open questions captured for anything they couldn't yet answer
|
|
9
|
+
- The Phase A row in STATE.md's Planning progress table flipped to `✅ complete`
|
|
10
|
+
|
|
11
|
+
The whole session should take about 30 minutes. **The operator is most likely a domain expert, not a software engineer.** Plain English throughout. Never use a term like "work unit" or "contract" without defining it the first time. Read [`docs/build/GLOSSARY.md`](../../docs/build/GLOSSARY.md) once before you start so your vocabulary matches the catalogue's.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## How to lead this conversation
|
|
16
|
+
|
|
17
|
+
- **Lead the operator. Don't quiz them.** They aren't here to fill in a form; you're walking them through producing something they can use.
|
|
18
|
+
- **Translate the answers into catalogue artefacts as you go.** They don't need to know the artefact shape — you do.
|
|
19
|
+
- **One question at a time.** If they answer two at once, capture both and move on.
|
|
20
|
+
- **Use their words wherever possible.** Translate jargon out, not in.
|
|
21
|
+
- **If they don't know something, file an open question and move on.** Don't stall.
|
|
22
|
+
- **Save as you go.** Don't accumulate answers and write everything at the end — write each artefact when the conversation produces it.
|
|
23
|
+
|
|
24
|
+
**Drift discipline:** every decision made in conversation must be filed before the session ends. If the operator says "let's go with X" and X is an architectural commitment, file a decision file in `docs/build/decisions/` *now*, not later. Decisions made in chat that don't reach the catalogue are drift, and drift is the failure mode that makes the catalogue worthless.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Step 1 — Welcome (2 min)
|
|
29
|
+
|
|
30
|
+
Open with something like:
|
|
31
|
+
|
|
32
|
+
> "Welcome. I'm going to help you plan your project. We'll do this step by step over the next half-hour or so, with breaks if you want. By the end, your catalogue will have a real project description, the first person or two it's for, and a map of where this whole thing is heading. Anything we decide gets saved as we go — you don't have to remember any of it.
|
|
33
|
+
>
|
|
34
|
+
> Take your time. If a question doesn't have an obvious answer, we'll file it as an open question and keep moving. Ready?"
|
|
35
|
+
|
|
36
|
+
Wait for confirmation.
|
|
37
|
+
|
|
38
|
+
## Step 2 — Project description (5 min)
|
|
39
|
+
|
|
40
|
+
Ask, in conversation:
|
|
41
|
+
|
|
42
|
+
> "Tell me about what you're building. A paragraph or two is enough. What is it? Who's it for, roughly? What does it do? Why does it need to exist?"
|
|
43
|
+
|
|
44
|
+
Listen. Don't interrupt. When they're done, summarise back in 2-3 sentences in your words, and ask if you've got it. Refine if needed.
|
|
45
|
+
|
|
46
|
+
When the description is settled, **write it into `STATE.md`'s "What is currently in flight" section** — replacing the placeholder. Keep their voice; don't make it sound corporate. Show them the file path and confirm it's saved.
|
|
47
|
+
|
|
48
|
+
## Step 3 — One persona, then one or two more (15-20 min)
|
|
49
|
+
|
|
50
|
+
Tell the operator what's coming:
|
|
51
|
+
|
|
52
|
+
> "Now I'm going to ask about the specific people this project serves. Not 'teachers' or 'users' — one specific person with a name. Their situation, what makes them need this, what success feels like for them. We'll do one in detail, then maybe one or two more. This becomes the anchor for everything we file later."
|
|
53
|
+
|
|
54
|
+
Then **switch to the `persona-new` protocol** (invoke `/persona-new` if available, otherwise read `.claude/commands/persona-new.md` and follow it) to walk the operator through the persona conversationally. File the persona as P001.
|
|
55
|
+
|
|
56
|
+
When P001 is filed, surface it and ask:
|
|
57
|
+
|
|
58
|
+
> "We have [name] filed. Are there other specific people this project serves? Most projects have 2 or 3. The most common shape is: the primary user, and someone else who's affected — a colleague, a parent, an administrator, the person whose work this enables. Want to file another?"
|
|
59
|
+
|
|
60
|
+
If yes, run `/persona-new` again. Aim for **1-3 total** — more than 3 in Phase A usually means the project is overscoped; file the rest as open questions and revisit later.
|
|
61
|
+
|
|
62
|
+
## Step 4 — Map 1: The Horizon (8-10 min)
|
|
63
|
+
|
|
64
|
+
When the personas are filed, transition:
|
|
65
|
+
|
|
66
|
+
> "Now let's draw the whole picture. Not the details yet — the destination. What does the world look like when this project is finished? What's true that isn't true today?"
|
|
67
|
+
|
|
68
|
+
Use the template at `docs/build/maps/01-template.md`. Walk through its sections **as conversation, not as a form**:
|
|
69
|
+
|
|
70
|
+
- **What this project is** — one paragraph, plain language. (You may already have most of this from Step 2 — refine it for the map.)
|
|
71
|
+
- **Who it's for** — list the personas just filed, one line each with their P-NNN handle.
|
|
72
|
+
- **What "done" looks like** — describe the destination in 3-6 sentences. Not how to get there; the place itself.
|
|
73
|
+
- **The shape of the journey** — two or three paragraphs in plain language describing the major stages, in narrative form. *"First we'll build X so Y is possible. Once Y is in place, we can do Z, which is what really matters for [persona]. The last stretch is making it reliable enough for real classrooms."* That kind of writing. A story, not a Gantt chart.
|
|
74
|
+
- **What's not in scope** — 3-5 things adjacent to the project that someone might assume are included but aren't. Naming the negative space prevents drift.
|
|
75
|
+
|
|
76
|
+
Write the map to `docs/build/maps/01-the-horizon.md`. Show them the file path and confirm.
|
|
77
|
+
|
|
78
|
+
## Step 5 — Open questions (2 min)
|
|
79
|
+
|
|
80
|
+
Pass over the conversation looking for anything the operator wasn't sure about. For each:
|
|
81
|
+
|
|
82
|
+
- File it as Q-NNN in `docs/build/open-questions/`
|
|
83
|
+
- Add a row to `open-questions/_index.md`
|
|
84
|
+
|
|
85
|
+
> "I noticed a few things you weren't sure about yet — [list]. I've filed them as open questions so we'll come back to them. Two of them affect Phase B (Architecture), so we'll definitely hit them next session."
|
|
86
|
+
|
|
87
|
+
## Step 6 — Close (2 min)
|
|
88
|
+
|
|
89
|
+
Update STATE.md:
|
|
90
|
+
|
|
91
|
+
- Set the **Planning progress** Phase A row to `✅ complete (YYYY-MM-DD)`
|
|
92
|
+
- Set the Phase B row to `🟡 next` (so the next `/start-of-session` knows where to route)
|
|
93
|
+
- Refresh the "Last updated" date
|
|
94
|
+
|
|
95
|
+
Then tell the operator what they now have:
|
|
96
|
+
|
|
97
|
+
> "You've got your first catalogue substrate:
|
|
98
|
+
>
|
|
99
|
+
> - **[N] personas** in `docs/build/personas/` — these anchor every later decision
|
|
100
|
+
> - **Map 1** at `docs/build/maps/01-the-horizon.md` — the whole-project picture
|
|
101
|
+
> - **[N] open questions** in `docs/build/open-questions/` — these are what we'll resolve as planning continues
|
|
102
|
+
> - **STATE.md** updated to reflect Phase A is done
|
|
103
|
+
>
|
|
104
|
+
> Next session, we move to **Phase B — Architecture & Contracts** (about 60-90 minutes). We'll name the major pieces of your project and what each one provides to the others.
|
|
105
|
+
>
|
|
106
|
+
> For now, run `/end-of-session` to commit everything. The catalogue's search index will refresh in the background, and next session can pick up from here."
|
|
107
|
+
|
|
108
|
+
Then run `/end-of-session` to close out.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## What to do if it goes off-track
|
|
113
|
+
|
|
114
|
+
- **Operator wants to skip personas:** strongly advise against it. Personas are the anchor for everything downstream. File at least one — even a rough one — and note it's a draft.
|
|
115
|
+
- **Operator says "I don't know" too often:** that's fine for Phase A. File each as an open question; the architecture phase will tighten them up. The point of Phase A is to establish *enough* shape that B can begin, not to be complete.
|
|
116
|
+
- **Operator wants to design implementation:** redirect. *"We'll get to how it's built in Phase B. Right now we're just figuring out what we're building and for whom."*
|
|
117
|
+
- **Operator gets fatigued mid-phase:** offer to pause. Run `/end-of-session` capturing where you are with a "Resume hint" in the session log; pick up at the next session.
|
|
118
|
+
- **Operator wants to file work units already:** suggest waiting. *"Phase E (Initial Work Units) is where we list them — by then we'll know the architecture, surfaces, and design system, so each work unit can be filed coherently."* If they insist, file as `🔵 proposed` with a note that the WU may need refinement after Phase B.
|
|
119
|
+
|
|
120
|
+
## Recovery if the session was interrupted
|
|
121
|
+
|
|
122
|
+
If the session log's "Resume hint" indicates Phase A was mid-way, read it carefully and pick up at exactly the step indicated. Re-read what's been filed so far (the personas already in `docs/build/personas/`, anything in STATE.md). Confirm with the operator before continuing — *"Last time we got as far as filing P001 — are we ready to add a second persona, or shall we go straight to Map 1?"*
|
|
@@ -1,19 +1,58 @@
|
|
|
1
1
|
# start-of-session
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
You are starting a session on a project that uses the **NuOS Build Method catalogue**. Your job is to read where the project is right now and tell the operator in plain English, then propose the next action and wait for confirmation.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**The operator is most likely a domain expert, not a software engineer.** Plain English throughout. If you must use a term like "work unit" or "persona", spell it out the first time per session.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
2. **Read the most recent session log entry** in `docs/build/sessions/` (the file with the most recent date in its filename). Read it in full.
|
|
9
|
-
3. **Read the active work unit** named in STATE.md, in full — including the notes / log section at the bottom.
|
|
10
|
-
4. **Skim `docs/build/open-questions/_index.md` and `docs/build/risks/_index.md`** for any items that block the active work unit. If any are blocking, surface them now before any work starts.
|
|
11
|
-
5. **Surface to the operator:**
|
|
12
|
-
- Where the project is right now (one sentence)
|
|
13
|
-
- The active work unit and its current status (one sentence)
|
|
14
|
-
- Any blockers (one bullet each)
|
|
15
|
-
- The next concrete action (one bullet)
|
|
7
|
+
---
|
|
16
8
|
|
|
17
|
-
|
|
9
|
+
## Step 1 — First-run detection
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
Read `docs/build/STATE.md`. Look at the **Planning progress** section:
|
|
12
|
+
|
|
13
|
+
- If **all five phases (A-E) are still `🔵 not yet started`** AND there are no real work units in `docs/build/work-units/` (only templates), this is a fresh project. Tell the operator:
|
|
14
|
+
|
|
15
|
+
> "This is a brand-new catalogue. Before we file any work units, we walk through 5 short planning phases that produce the substrate every later session draws on. Phase A — Orientation — takes about 30 minutes. Want to begin now? (yes / no, look around first)"
|
|
16
|
+
|
|
17
|
+
If yes, **switch to the `plan-orientation` protocol** (invoke `/plan-orientation` if available; otherwise read `.claude/commands/plan-orientation.md` and follow it). If no, point them at `docs/build/WELCOME.md` and `docs/build/GLOSSARY.md` so they can read about the catalogue first, then wait.
|
|
18
|
+
|
|
19
|
+
- If **Phase A is in flight or any phase is mid-progress** (marked `🟡 in flight` in STATE.md's Planning progress section), route the operator back to the relevant `plan-*` protocol to continue planning. Read the most recent session log's "Resume hint" section to know exactly where to pick up.
|
|
20
|
+
|
|
21
|
+
- If **all five planning phases are complete**, proceed with the normal session-start steps below.
|
|
22
|
+
|
|
23
|
+
## Step 2 — Read where the project is
|
|
24
|
+
|
|
25
|
+
Read these files in order:
|
|
26
|
+
|
|
27
|
+
1. `docs/build/STATE.md` in full — the always-current snapshot
|
|
28
|
+
2. The most recent file in `docs/build/sessions/` — what happened last session
|
|
29
|
+
3. The active work unit named in STATE.md, including its notes section at the bottom
|
|
30
|
+
4. Skim `docs/build/open-questions/_index.md` and `docs/build/risks/_index.md` for anything blocking the active work unit
|
|
31
|
+
|
|
32
|
+
## Step 3 — Tell the operator where they are
|
|
33
|
+
|
|
34
|
+
Use plain English. One short paragraph or 4-5 bullets:
|
|
35
|
+
|
|
36
|
+
- **Where the project is right now** — one sentence describing the current state
|
|
37
|
+
- **What was just done** — the last session's outcome in a sentence
|
|
38
|
+
- **The active work unit** — what's open and its status
|
|
39
|
+
- **Any blockers** — one bullet per blocking question or risk
|
|
40
|
+
- **The next concrete action** — one bullet
|
|
41
|
+
|
|
42
|
+
## Step 4 — Wait for the operator's confirmation
|
|
43
|
+
|
|
44
|
+
The operator may want to do the proposed next action, or something different. Either is fine. Just don't start substantive work until they've confirmed direction.
|
|
45
|
+
|
|
46
|
+
If they want to do something different from the proposed next action, record the divergence — either as a note on the active work unit, or by filing a new work unit if the divergence is significant.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## If anything is wrong with STATE.md
|
|
51
|
+
|
|
52
|
+
If STATE.md still has placeholder text, references a work unit that doesn't exist, or is missing the planning progress section, tell the operator immediately. Likely the previous session ended without `/end-of-session` running. The recovery is to file a session log for what's known to have happened, update STATE, then proceed.
|
|
53
|
+
|
|
54
|
+
## What never to do at session start
|
|
55
|
+
|
|
56
|
+
- **Don't make decisions in conversation without filing them.** If the operator says "let's do X" and X is a real architectural choice, file it as a decision in `docs/build/decisions/` before moving on. Decisions made in conversation that aren't filed produce drift — and drift is the failure mode that makes the catalogue worthless.
|
|
57
|
+
- **Don't start work that needs an open question resolved.** Surface the blocker; ask the operator how they want to proceed.
|
|
58
|
+
- **Don't read past your tasks.** STATE, last session log, active work unit, blockers — then stop. Surface those, wait for direction.
|