@@ -65,47 +65,113 @@ examples.
6565
6666### Pain points
6767
68- 1 . ** Same syntax, different semantics** --
69- ` {{.field}} ` means "insert value" in catalog
68+ 1 . ` {{.field}} ` means "insert value" in catalog
7069 but "match any text" in required-structure.
71- 2 . ** Marker pairs vs single markers** -- no
72- visual cue tells the user whether a marker
70+ 2 . No visual cue tells you whether a marker
7371 needs a closing tag.
74- 3 . ** Parameter count varies wildly** -- from
75- zero (allow-empty-section) to seven (catalog).
76- 4 . ** No single reference** -- rules are
77- documented per-rule; no unified walkthrough
78- exists.
79-
80- ### What works well
81-
82- - The ` <?name ... ?> ` syntax is visually
83- distinct from Markdown content.
84- - YAML inside markers is familiar to users who
85- already write front matter.
86- - Catalog and include share the same
87- open/generate/close lifecycle via the
88- ` gensection ` archetype.
72+ 3 . No single reference exists -- rules are
73+ documented per-rule only.
74+
75+ ## Blind trial results (5 participants)
76+
77+ Five developers got a two-sentence intro and
78+ 15 syntax snippets. They guessed what each
79+ snippet does and rated their confidence.
80+
81+ ### Confidence scores (1=guessing, 5=certain)
82+
83+ | Snippet | Topic | Avg | Range |
84+ | ---------| -----------------------------| -----| -------|
85+ | 1 | ` <?catalog?> ` pair | 4.8 | 4-5 |
86+ | 2 | ` <?include?> ` pair | 4.8 | 4-5 |
87+ | 3 | ` <?require?> ` single marker | 4.0 | 2-5 |
88+ | 4 | ` <?allow-empty-section?> ` | 4.8 | 4-5 |
89+ | 5 | ` {{.id}}: {{.title}} ` heading | 3.8 | 3-4 |
90+ | 6 | catalog ` row ` table template | 4.4 | 4-5 |
91+ | 7 | ` line-length ` config | 4.0 | 4-5 |
92+ | 8 | config overrides | 4.8 | 4-5 |
93+ | 9 | CUE front-matter schema | 4.4 | 4-5 |
94+ | 10 | ` {{.field}} ` heading vs row | 4.0 | 3-5 |
95+ | 11 | 4-space indented directive | 2.6 | 1-4 |
96+ | 12 | nested directives in row | 2.0 | 1-3 |
97+ | 13 | empty section at EOF | 4.6 | 3-5 |
98+ | 14 | ` paragraph-readability ` | 4.0 | 3-5 |
99+ | 15 | ` token-budget ` with ratio | 3.8 | 2-5 |
100+
101+ ### Key misconceptions found
102+
103+ 1 . ** ` {{.field}} ` dual meaning (snippet 10):**
104+ All five participants correctly identified
105+ that template headings and catalog rows use
106+ the same syntax for different purposes. All
107+ flagged this as the top source of confusion.
108+ Three called it "genuinely confusing" despite
109+ getting the right answer. The syntax collision
110+ means even correct users feel uncertain.
111+
112+ 2 . ** Indented directives silently break
113+ (snippet 11):** Average confidence 2.6.
114+ Most guessed it would be treated as a code
115+ block, but nobody was sure. Four of five
116+ called this a "footgun" because there is no
117+ diagnostic -- the directive just disappears.
118+
119+ 3 . ** Nested directives undefined (snippet 12):**
120+ Confidence 2.0, the lowest of all snippets.
121+ Guesses ranged from "literal text" to "nested
122+ not allowed" to "recursive include." Nobody
123+ was sure.
124+
125+ 4 . ** ` <?require?> ` role unclear (snippet 3):**
126+ One participant rated confidence 2. The word
127+ "require" is ambiguous: require a file to
128+ exist? A filename pattern? Front-matter
129+ fields? The snippet alone does not tell you.
130+
131+ 5 . ** ` ratio: 0.75 ` meaning (snippet 15):**
132+ Two participants misread ` ratio ` as a warning
133+ threshold (warn at 75% of budget). It is
134+ actually a words-to-tokens multiplier. The
135+ parameter name does not signal its unit.
136+
137+ 6 . ** fix behavior unclear for simple rules
138+ (snippet 7):** Three participants were unsure
139+ whether ` line-length ` is fixable. One rated
140+ fix confidence at 2. Users cannot predict
141+ which rules are fixable without reading each
142+ rule's docs.
143+
144+ ### What worked well
145+
146+ - Self-describing names scored highest:
147+ ` allow-empty-section ` (4.8), ` overrides ` (4.8).
148+ - Marker pairs are intuitive: catalog and
149+ include both scored 4.8.
150+ - CUE schema readable: ` | ` union and ` ? `
151+ optional read naturally (4.4).
152+
153+ ### Implications for the user model
154+
155+ Users grasped marker pairs quickly. The real
156+ confusion is elsewhere:
157+
158+ - Same syntax, two meanings (` {{.field}} ` ).
159+ - Silent failures (indented directives).
160+ - Undefined composition (nesting).
161+ - Ambiguous parameter names (` ratio ` ).
162+ - Unpredictable fixability.
163+
164+ The guide must address all five.
89165
90166## Proposed user model
91167
92168### Principle: two kinds of markers
93169
94- Collapse all directives into two categories a
95- user can identify on sight :
170+ Users already grasp this (blind trial 4.8 avg
171+ for pairs). Make it the documented rule :
96172
97- | Kind | Shape | Rule | User prediction |
98- | ------------| -------------------------------| -----------------------------------------------| -----------------------------------------------------|
99- | ** Generator** | ` <?name ...?> ` ... ` <?/name?> ` | Content between markers is managed by mdsmith | "If I see a marker pair, ` fix ` regenerates the body" |
100- | ** Constraint** | ` <?name ...?> ` (no closing tag) | The marker asserts a condition | "If I see a lone marker, ` check ` validates something" |
101-
102- The core rule: if a marker has a closing tag,
103- the body is auto-generated; if it does not, it
104- is a validation constraint.
105-
106- This is already almost true today. The plan
107- makes it explicit and documents it as the
108- governing rule.
173+ - Closing tag present: ` fix ` regenerates body.
174+ - No closing tag: ` check ` validates a condition.
109175
110176### Principle: one template language
111177
@@ -135,49 +201,33 @@ field-name hint.
135201** Decision required from maintainer:** pick A
136202or B before implementation.
137203
138- ### Principle: consistent YAML parameters
139-
140- All directives already use YAML for parameters.
141- No change needed, but the guide must present
142- them with a uniform layout:
143-
144- ``` markdown
145- <? directive-name
146- param1: value
147- param2: value
148- ?>
149- ```
150-
151204### What does NOT change
152205
153- - The ` <?...?> ` marker syntax itself stays.
154- - The YAML parameter format stays.
155- - The ` gensection ` engine for generators stays.
156- - The ` fix ` / ` check ` CLI commands stay.
157- - ` .mdsmith.yml ` configuration stays.
158-
159- This is intentionally conservative. The goal is
160- a clearer mental model and a guide, not a
161- rewrite.
206+ The ` <?...?> ` syntax, YAML parameters,
207+ ` gensection ` engine, CLI commands, and
208+ ` .mdsmith.yml ` all stay. This plan improves
209+ the user model and docs, not the engine.
162210
163211## Tasks
164212
165- ### Phase 1: central directive reference (#70 )
213+ ### Phase 1: central directive guide (#70 )
166214
1672151 . Write ` docs/guides/directives.md ` covering:
168216
169- - The two-kind model (generator vs
170- constraint)
171- - Placement constraints: must be at document
172- root, at most 3-space indent, ignored
173- inside fenced code blocks and HTML blocks
174- - Every directive with: purpose, parameters,
175- one good example, one bad example, what
176- ` check ` reports, what ` fix ` does
177- - A quick-reference table at the top
178- - Classification by role: "generated-section
179- markers" vs "rule modifiers / escape
180- hatches" (per #70 )
217+ - Quick-reference table (name, purpose, has
218+ closing tag, fixable, parameters)
219+ - Placement rules: max 3-space indent, not
220+ inside fenced code or HTML blocks. Call out
221+ the 4-space footgun with an explicit warning
222+ and example (blind trial snippet 11)
223+ - Each directive: purpose, parameters, one
224+ good example, one bad example, what ` check `
225+ reports, what ` fix ` does
226+ - A "which rules auto-fix?" summary (blind
227+ trial snippet 7 confusion)
228+ - Nesting: explicitly state that directives
229+ inside generated content are not processed
230+ (blind trial snippet 12 confusion)
181231
1822322 . Add cross-links from each rule README to the
183233 guide.
@@ -204,17 +254,24 @@ rewrite.
204254 ` internal/rules/proto.md ` ,
205255 ` .claude/skills/proto.md ` ) to the new syntax.
206256
257+ ### Phase 2b: fix ambiguous parameter names
258+
259+ 9 . Rename ` token-budget ` ` ratio ` to
260+ ` words-per-token ` (blind trial showed 2 of 5
261+ misread it as a warning threshold). Keep
262+ ` ratio ` as a deprecated alias.
263+
207264### Phase 3: evaluate template engine (stretch)
208265
209- 9 . Prototype replacing Go ` text/template ` with
266+ 10 . Prototype replacing Go ` text/template ` with
210267 gonja or pongo2 in catalog rendering.
211268
212269 - Measure: does Jinja syntax reduce user
213270 confusion vs Go templates?
214271 - Measure: does it enable filters/conditionals
215272 that users actually need?
216273
217- 10 . If the prototype shows clear benefit, plan a
274+ 11 . If the prototype shows clear benefit, plan a
218275 migration. If not, keep Go ` text/template ` and
219276 document its quirks in the guide.
220277
@@ -224,11 +281,16 @@ rewrite.
224281 covers every directive with examples
225282- [ ] The guide passes `mdsmith check
226283 docs/guides/`
284+ - [ ] The guide documents the 4-space indent
285+ footgun and nesting behavior
286+ - [ ] The guide includes a fixability summary
227287- [ ] ` {{.field}} ` in required-structure
228288 templates uses a distinct syntax from
229289 catalog templates (Phase 2)
230290- [ ] Existing template files are migrated
231291 (Phase 2)
292+ - [ ] ` ratio ` renamed to ` words-per-token ` with
293+ backward-compatible alias (Phase 2b)
232294- [ ] All tests pass: ` go test ./... `
233295- [ ] ` go tool golangci-lint run ` reports no
234296 issues
0 commit comments