From 9099eeffb6fe1abd46f9c3af9bf08d50018cdf76 Mon Sep 17 00:00:00 2001 From: Tamika Nomara Date: Wed, 15 Jul 2026 02:01:04 +0400 Subject: [PATCH] chore(lint): make Markdown Prettier-safe and re-enable it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #127 took Markdown out of Prettier's scope because running it corrupted files that agents read as raw source. Two of Prettier's normalizations are core CommonMark rules that cannot be turned off (ordered-list renumbering and inline-code-span trimming), so the fix is to make the source robust to them rather than to configure them away. With that done, Prettier formats this repo's Markdown without changing what any file says. Config: - .prettierrc.json: proseWrap "preserve" (no paragraph reflow, so the reformat stays small) and embeddedLanguageFormatting "off" (leave fenced code alone). - .prettierignore: stop excluding *.md; ignore the schematic html-template.html that Prettier hard-errors on (the prek hook never hands it over, but a direct `prettier .` would). - .pre-commit-config.yaml: update the stale comment that said Markdown is excluded. Content made robust to the two un-disable-able normalizations: - coding-standard: fix the Step 5 list numbering (1,2,4,5 -> 1,2,3,4). - project-documentation, plan-a-feature: give the ordered lists that a lead-in sentence interrupts a valid start, so Prettier keeps them as lists instead of collapsing them into a run-on paragraph. - work-item / issue templates: drop the ` — ` code span from the prose (the em-dash heading format is already shown in the template above) and keep the "em-dash with surrounding spaces" wording. - overview-template, script-execution-instructions, writing-effective- instructions: 4-backtick fences around Markdown examples that nest a fence, so the inner fence no longer closes the outer block early. - readability-editor, markdown-to-confluence, project-documentation: reword inline code spans Prettier would re-delimit. - context-injection-commands: drop the redundant padding spaces inside a double-backtick code span (they do not render, and Prettier strips them). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01AhopKKK5YVPzmkdAzHtPcG --- .pre-commit-config.yaml | 12 +++++++----- .prettierignore | 19 +++++++++++-------- .prettierrc.json | 4 +++- .../skills/markdown-to-confluence/SKILL.md | 2 +- .../references/overview-template.md | 8 ++++---- han-coding/skills/coding-standard/SKILL.md | 4 ++-- han-core/agents/readability-editor.md | 2 +- .../skills/project-documentation/SKILL.md | 5 +++-- .../references/issue-template.md | 2 +- han-planning/skills/plan-a-feature/SKILL.md | 7 +++---- .../references/work-item-template.md | 2 +- .../context-injection-commands.md | 2 +- .../script-execution-instructions.md | 4 ++-- .../writing-effective-instructions.md | 4 ++-- 14 files changed, 42 insertions(+), 35 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1dc3c8a2..4ac9b734 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,11 +6,13 @@ exclude: "^(docs/plans/|docs/research/|han-reporting/skills/html-summary/assets/)" repos: - # Prettier owns formatting for JSON, YAML, and JS at 120 columns. Markdown is - # deliberately excluded in .prettierignore: agents read skills and reference - # files as raw source, and Prettier's list renumbering and code-span trimming - # change what those files say. Running the local devDependency keeps Prettier's - # version in package.json only, not duplicated in a hook mirror. + # Prettier owns formatting for Markdown, JSON, YAML, and JS at 120 columns. + # Markdown runs with proseWrap: preserve and embeddedLanguageFormatting off (see + # .prettierrc.json). Agents read skills and reference files as raw source, so the + # source is kept robust to the two normalizations Prettier cannot turn off — + # ordered-list renumbering and inline code-span trimming — and Prettier then + # leaves what those files say unchanged. Running the local devDependency keeps + # Prettier's version in package.json only, not duplicated in a hook mirror. # It runs first so the hygiene fixers below never fight it. - repo: local hooks: diff --git a/.prettierignore b/.prettierignore index efc971f2..b4fd2f4d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,14 +1,12 @@ # Markdown is the product, not just prose about it: skills, agents, and reference # files are read as raw source by agents, so a transform that renders the same can # still change what an agent is told to do. Prettier has two such transforms that -# cannot be turned off, because they are core CommonMark normalizations: -# * It renumbers ordered lists, while the prose cross-references to those steps -# ("see Step 6") stay put and end up pointing at the wrong ones. -# * It strips the spaces inside inline code spans, so a heading spec written as -# ` — ` becomes `—` next to prose that still says "with surrounding spaces". -# Both survive proseWrap: preserve and embeddedLanguageFormatting: off, so there is -# no configuration that formats this repo's Markdown without corrupting it. -*.md +# cannot be turned off, because they are core CommonMark normalizations: it +# renumbers ordered lists, and it strips the padding spaces inside inline code +# spans. The source is kept robust to both (ordered lists are already sequential, +# and no prose wraps a padded spec like ` — ` in backticks), so proseWrap: preserve +# plus embeddedLanguageFormatting: off formats this repo's Markdown without +# corrupting it. Keep it that way when editing. # Static historical artifacts: left as written. docs/plans/ @@ -17,6 +15,11 @@ docs/research/ # Vendored third-party assets: checked in verbatim, never reformat. han-reporting/skills/html-summary/assets/ +# A schematic HTML sketch, not real HTML: Prettier hard-errors trying to parse it. +# The prek hook never hands it over (it filters to markdown, JSON, YAML, and JS), +# but ignore it here too so a direct `prettier .` stays green. +han-reporting/skills/html-summary/references/html-template.html + # Dependencies and generated files. node_modules/ package-lock.json diff --git a/.prettierrc.json b/.prettierrc.json index 963354f2..60face34 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,3 +1,5 @@ { - "printWidth": 120 + "printWidth": 120, + "proseWrap": "preserve", + "embeddedLanguageFormatting": "off" } diff --git a/han-atlassian/skills/markdown-to-confluence/SKILL.md b/han-atlassian/skills/markdown-to-confluence/SKILL.md index 4cb5805e..c0298d1e 100644 --- a/han-atlassian/skills/markdown-to-confluence/SKILL.md +++ b/han-atlassian/skills/markdown-to-confluence/SKILL.md @@ -135,7 +135,7 @@ draft-vs-published. changes local only. **Diagram note:** Markdown produced by Han's documentation skills emits Mermaid -diagrams in fenced ```mermaid``` code blocks. Confluence does not render Mermaid +diagrams in fenced `mermaid` code blocks. Confluence does not render Mermaid natively without a Mermaid macro, so these blocks publish as code, not rendered diagrams. Leave them intact — do not silently strip them — and tell the user the diagrams posted as Mermaid source, in case their space has a macro that renders diff --git a/han-coding/skills/code-overview/references/overview-template.md b/han-coding/skills/code-overview/references/overview-template.md index 9fcb831b..860e81f6 100644 --- a/han-coding/skills/code-overview/references/overview-template.md +++ b/han-coding/skills/code-overview/references/overview-template.md @@ -52,7 +52,7 @@ remove the guidance comments, and keep the section order exactly as written. ## Code mode — explaining code as it is now -```markdown +````markdown # Code Overview: {short name of the target} {Intro paragraph: one or two sentences naming what code is being examined — the @@ -98,13 +98,13 @@ read as how the code delivers on the why above.} {The concrete entry points — the specific files or components — the reader would open first to begin working, with one line each on what each is for.} -``` +```` --- ## PR mode — explaining a set of changes -```markdown +````markdown # Change Overview: {short name of the pull request or branch} {Intro paragraph: one or two sentences naming what is being examined — which @@ -160,4 +160,4 @@ quality or risk judgment; that is code-review's job, not this skill's. --> {The concrete entry points — the specific files or components — where the change is densest or most interconnected, with one line each on why a reviewer should slow down there.} -``` +```` diff --git a/han-coding/skills/coding-standard/SKILL.md b/han-coding/skills/coding-standard/SKILL.md index 6e4d48c5..9b407faa 100644 --- a/han-coding/skills/coding-standard/SKILL.md +++ b/han-coding/skills/coding-standard/SKILL.md @@ -109,8 +109,8 @@ When converting an existing document into a coding standard: 1. Read the source document 2. Map sections to coding standard sections using the mapping at [adr-conversion-mapping.md](./references/adr-conversion-mapping.md) -4. **If the source document is fully subsumed:** delete it and update references (search `CLAUDE.md`, `AGENTS.md`, and other markdown files) -5. **If the source document retains useful content:** add a link to the new coding standard in the source document and remove migrated sections +3. **If the source document is fully subsumed:** delete it and update references (search `CLAUDE.md`, `AGENTS.md`, and other markdown files) +4. **If the source document retains useful content:** add a link to the new coding standard in the source document and remove migrated sections ## Step 6: Write the Coding Standard diff --git a/han-core/agents/readability-editor.md b/han-core/agents/readability-editor.md index 4a96a313..077bee20 100644 --- a/han-core/agents/readability-editor.md +++ b/han-core/agents/readability-editor.md @@ -17,7 +17,7 @@ You will receive the path to a draft file (or the draft text inline) and the sha You rewrite **prose regions only**. Leave these byte-for-byte unchanged: -- Content inside code fences (```` ``` ````) and inline code spans. +- Content inside code fences and inline code spans. - Diagram bodies — the content of a Mermaid block or any other rendered diagram. - Rendered markup — an HTML report's tags, attributes, and class names. - Inline citation identifiers (`A1`, `V3`, `[F5]`, and the like) — their whole value is that they still resolve to their registry, so they survive your rewrite exactly. diff --git a/han-core/skills/project-documentation/SKILL.md b/han-core/skills/project-documentation/SKILL.md index 0b24aeec..d3f0de6e 100644 --- a/han-core/skills/project-documentation/SKILL.md +++ b/han-core/skills/project-documentation/SKILL.md @@ -58,6 +58,7 @@ Lead with behavior. These rules make the doc an overview first and a reference s 4. **Reference is supporting detail.** Place schema, core types, constants, implementation notes, API bodies, and component listings under the `## Technical Reference` region, below the behavioral spine. Treat them as lookup material, not the document's main body. Apply to every section: + 5. **Absolute file paths** from repo root (e.g., `src/services/auth.ts`, not `./auth.ts`). 6. **Prefer pointers over long code.** In Technical Reference, point to the file and function and include a short illustrative snippet only where the source is non-obvious. Do not reproduce long (10-30 line) source blocks; link to the source instead. 7. **Code fence language identifiers** must match the project's actual languages (from Step 1). @@ -65,7 +66,7 @@ Apply to every section: 9. **Skip CONDITIONAL sections** from the template that don't apply. Don't include empty sections. 10. **One plain-language description** in the title area summarizing what the feature does. 11. **Separate backend and frontend content.** Use `### Backend` / `### Frontend` sub-headings for cross-cutting features; skip sub-headings for single-layer features. -12. **Diagrams are Mermaid, not ASCII.** Render the Architecture diagram, any Primary Flow diagram, and the Component Hierarchy as Mermaid in a ```` ```mermaid ```` fence — `flowchart` for structure and trees, `sequenceDiagram` for actor-to-system exchanges. Label nodes with parts a reader recognizes and label edges with what passes between them. Keep each diagram to the parts that matter; a reader should grasp the shape at a glance. +12. **Diagrams are Mermaid, not ASCII.** Render the Architecture diagram, any Primary Flow diagram, and the Component Hierarchy as Mermaid in a ` ```mermaid ` fence — `flowchart` for structure and trees, `sequenceDiagram` for actor-to-system exchanges. Label nodes with parts a reader recognizes and label edges with what passes between them. Keep each diagram to the parts that matter; a reader should grasp the shape at a glance. **Updating existing documents:** Read the entire existing document first and note all content sources (existing doc, content migrated from CLAUDE.md or other files, any other inputs). Preserve the existing structure; don't reorganize unless requested. Identify sections needing changes based on Step 2 exploration. Add new sections where the template suggests them. If the existing doc has no plain-language behavioral layer (no Summary, How It Works, or Primary Flows), add those sections at the top so the updated doc leads with behavior. Flag removals as provisional for the Content Audit (Step 6). Update code examples to match current source and update cross-references in both directions. @@ -121,7 +122,7 @@ Fidelity wins: the standard governs how the content is said, never whether a req ## Step 10: Verification -1. **Documentation file:** Follows template structure and leads with behavior (Summary, How It Works, Primary Flows appear before the `## Technical Reference` region), no `{placeholder}` values remain, absolute file paths, reference code is short snippets or file pointers rather than long source blocks, no empty CONDITIONAL sections, Mermaid diagrams are syntactically valid (open with ```` ```mermaid ````, declare a diagram type, and parse) +1. **Documentation file:** Follows template structure and leads with behavior (Summary, How It Works, Primary Flows appear before the `## Technical Reference` region), no `{placeholder}` values remain, absolute file paths, reference code is short snippets or file pointers rather than long source blocks, no empty CONDITIONAL sections, Mermaid diagrams are syntactically valid (open with ` ```mermaid `, declare a diagram type, and parse) 2. **Agent config file:** Reference correctly formatted, link path valid, placed in right section 3. **Cross-references:** Links point to real files, related docs link back to new doc 4. **IA review applied:** Step 7 edits were applied, or any skipped edits were surfaced to the user diff --git a/han-github/skills/work-items-to-issues/references/issue-template.md b/han-github/skills/work-items-to-issues/references/issue-template.md index 365a09ab..1565cac6 100644 --- a/han-github/skills/work-items-to-issues/references/issue-template.md +++ b/han-github/skills/work-items-to-issues/references/issue-template.md @@ -42,7 +42,7 @@ The format below is what `/plan-work-items` emits and what the publish pipeline These are the patterns the publish scripts grep for; violating them breaks the pipeline. The skill's Step 3 validation checks each invariant before publishing and proposes evidence-based repairs. -- **Heading line** begins with `## ` followed by `` (uppercase letters or digits, dash, digits), then ` — ` (em-dash with surrounding spaces), then the title. +- **Heading line** begins with `## ` followed by `` (uppercase letters or digits, dash, digits), then an em-dash with surrounding spaces, then the title. - **Heading rewrite.** After issue creation, `scripts/create-issues.sh` rewrites each heading in place to `## (#NNN) — `. The `(#NNN)` annotation is how `link-blockers.sh` resolves symbolic IDs to GitHub issue numbers, and how `create-issues.sh` knows to skip already-created slices on re-run. Both shapes — with and without `(#NNN)` — are valid input. - **Slice body** ends at the next `## ` heading or end of file. - **Screenshot URLs** use the exact path scheme `.github/issue-assets/<feature-slug>/<SYM-N>/<file>.png`, where `<feature-slug>` is the kebab-cased basename of the plan folder. The upload script extracts this path verbatim from the per-repo file and reads the slug back out of it, so the slug written into the URL is authoritative. diff --git a/han-planning/skills/plan-a-feature/SKILL.md b/han-planning/skills/plan-a-feature/SKILL.md index 139ecd37..eca1edae 100644 --- a/han-planning/skills/plan-a-feature/SKILL.md +++ b/han-planning/skills/plan-a-feature/SKILL.md @@ -223,10 +223,9 @@ After all review agents return, compile their findings. **Do not dump raw findin - On each affected `T#` entry in `artifacts/feature-technical-notes.md`, add this finding's ID to `Driven by findings:` and list affected spec sections under `Referenced in spec:`. - If a new decision was introduced, add an inline `([D#](artifacts/decision-log.md#...))` reference in the relevant section of `feature-specification.md` and list that section under the decision's `Referenced in spec:` field. Apply the same pattern for any new `T#` references. 5. **"Mechanics leaking into spec" findings** — findings in this class usually resolve by rewriting the offending spec sentence behaviorally and either extracting the mechanic to a `T#` note (if load-bearing) or removing it entirely (if pure implementation or discoverable from code). Do not escalate these to the user unless the rewrite would change the feature's meaning. - -5a. **`YAGNI candidate` findings** — apply the YAGNI rule per [../../references/yagni-rule.md](../../references/yagni-rule.md). For each finding, three resolution paths exist: (a) cite the missing evidence (per the rule's evidence test) and keep the spec item — record the citation in the relevant `D#`'s `Evidence:` field and close the finding; (b) replace with the strictly simpler version that satisfies the same evidence — update the spec sentence and the related `D#`, list the larger version under that `D#`'s `Rejected alternatives:` with the reason "simpler version satisfies the same evidence"; (c) demote to the spec's `## Deferred (YAGNI)` section with the reopening trigger named, removing the inline behavior from the affected sections. Surface YAGNI deferrals to the user in Step 7's escalation pass so the user can override consciously, but do not require user input when evidence resolves the finding directly. -6. **Escalate only what genuinely needs the user.** For findings that remain open, draft a recommended answer with rationale and alternatives, the same way Step 4 surfaces questions. Present them to the user together, organized by the decision they affect — not by which agent raised them. -7. **Capture the user's answers** in the relevant `D#` entry in `artifacts/decision-log.md`, finish populating the `F#` entry (`Resolved by: user input`), update any dependent decisions or tech-notes, and keep all files' cross-refs in sync. +6. **`YAGNI candidate` findings** — apply the YAGNI rule per [../../references/yagni-rule.md](../../references/yagni-rule.md). For each finding, three resolution paths exist: (a) cite the missing evidence (per the rule's evidence test) and keep the spec item — record the citation in the relevant `D#`'s `Evidence:` field and close the finding; (b) replace with the strictly simpler version that satisfies the same evidence — update the spec sentence and the related `D#`, list the larger version under that `D#`'s `Rejected alternatives:` with the reason "simpler version satisfies the same evidence"; (c) demote to the spec's `## Deferred (YAGNI)` section with the reopening trigger named, removing the inline behavior from the affected sections. Surface YAGNI deferrals to the user in Step 7's escalation pass so the user can override consciously, but do not require user input when evidence resolves the finding directly. +7. **Escalate only what genuinely needs the user.** For findings that remain open, draft a recommended answer with rationale and alternatives, the same way Step 4 surfaces questions. Present them to the user together, organized by the decision they affect — not by which agent raised them. +8. **Capture the user's answers** in the relevant `D#` entry in `artifacts/decision-log.md`, finish populating the `F#` entry (`Resolved by: user input`), update any dependent decisions or tech-notes, and keep all files' cross-refs in sync. ## Step 8: Project Manager Synthesis diff --git a/han-planning/skills/plan-work-items/references/work-item-template.md b/han-planning/skills/plan-work-items/references/work-item-template.md index f31a0416..5e466f43 100644 --- a/han-planning/skills/plan-work-items/references/work-item-template.md +++ b/han-planning/skills/plan-work-items/references/work-item-template.md @@ -38,7 +38,7 @@ Each work item in `work-items.md` uses this template. Required fields appear in ## Format invariants -- Heading line begins with `## ` followed by `<W-N>` (the prefix letters, a dash, then digits), then ` — ` (em-dash with surrounding spaces), then the title. +- Heading line begins with `## ` followed by `<W-N>` (the prefix letters, a dash, then digits), then an em-dash with surrounding spaces, then the title. - A work item body ends at the next `## ` heading or end of file. - Design-reference paths are relative to the `work-items.md` file (e.g., `ui-designs/<file>.png` when the screenshots live in the plan folder). Never use an absolute path or a cross-repository URL. - The `**Depends on.**` line uses the literal bold marker, comma-separates dependencies, and ends with `.` (the trailing period is part of the format, not a sentence terminator). diff --git a/han-plugin-builder/skills/guidance/references/skill-building-guidance/context-injection-commands.md b/han-plugin-builder/skills/guidance/references/skill-building-guidance/context-injection-commands.md index a6e0212b..10067f36 100644 --- a/han-plugin-builder/skills/guidance/references/skill-building-guidance/context-injection-commands.md +++ b/han-plugin-builder/skills/guidance/references/skill-building-guidance/context-injection-commands.md @@ -11,7 +11,7 @@ Context injection commands use the `` !`command` `` syntax to execute a shell co Format: `` - label: !`command` `` -Multiple commands per line: `` - Git user: !`git config user.name` (!`git config user.email`) `` +Multiple commands per line: ``- Git user: !`git config user.name` (!`git config user.email`)`` Many skills use this pattern: code-review skills, documentation skills, PR-description skills, investigation skills, project-discovery skills, and any skill whose steps need to know the current git state or project layout. diff --git a/han-plugin-builder/skills/guidance/references/skill-building-guidance/script-execution-instructions.md b/han-plugin-builder/skills/guidance/references/skill-building-guidance/script-execution-instructions.md index 8243b9dd..08e70487 100644 --- a/han-plugin-builder/skills/guidance/references/skill-building-guidance/script-execution-instructions.md +++ b/han-plugin-builder/skills/guidance/references/skill-building-guidance/script-execution-instructions.md @@ -28,7 +28,7 @@ Each step has three elements: Fenced code blocks with comments as pseudocode are ambiguous: -```markdown +````markdown <!-- BAD — do not do this --> ``` # generate a unique temp file path @@ -40,7 +40,7 @@ Fenced code blocks with comments as pseudocode are ambiguous: # post the review scripts/post-pr-review.sh {args} ``` -``` +```` Problems: diff --git a/han-plugin-builder/skills/guidance/references/skill-building-guidance/writing-effective-instructions.md b/han-plugin-builder/skills/guidance/references/skill-building-guidance/writing-effective-instructions.md index fc303c12..b73f7c79 100644 --- a/han-plugin-builder/skills/guidance/references/skill-building-guidance/writing-effective-instructions.md +++ b/han-plugin-builder/skills/guidance/references/skill-building-guidance/writing-effective-instructions.md @@ -237,7 +237,7 @@ network calls and file writes are explicit in function names so callers know wha Three conventions are buried in a single paragraph. The model must parse sentence boundaries to separate them. **After (each convention as its own block):** -```markdown +````markdown ## Step 3: Apply Review Standards ### Error handling @@ -273,7 +273,7 @@ Functions with network calls or file writes must name the side effect. // do this: fetchPricing(), writeSummaryToFile() // not this: getPricing(), generateSummary() ``` -``` +```` Each convention is independently parseable: heading, rule, example. ### Rule: Resolve variation at the point of use