aboutsummaryrefslogtreecommitdiff
path: root/todo.org
diff options
context:
space:
mode:
Diffstat (limited to 'todo.org')
-rw-r--r--todo.org2089
1 files changed, 2089 insertions, 0 deletions
diff --git a/todo.org b/todo.org
new file mode 100644
index 0000000..3353745
--- /dev/null
+++ b/todo.org
@@ -0,0 +1,2089 @@
+#+TITLE: Rulesets — Open Work
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-04-19
+
+Tracking TODOs for the rulesets repo that span more than one commit.
+Project-scoped (not the global =~/sync/org/roam/inbox.org= list).
+
+* Rulesets Open Work
+
+** DOING [#A] Check that memories are sync'd across machines via git.m
+
+*** 2026-05-14 Thu @ 19:14:11 -0500 Investigate current memory storage
+
+Memory files live at
+[[file:/home/cjennings/.claude/projects/-home-cjennings-code-rulesets/memory/][~/.claude/projects/-home-cjennings-code-rulesets/memory/]]
+— four files including =MEMORY.md= and three individual entries
+(=feedback_never_guess.md=, =project_ai_scripts_canonical_source.md=,
+=reference_pdftools_venv.md=). The directory is a plain unmanaged dir
+(no symlink, no enclosing git checkout). Neither
+[[file:/home/cjennings/.claude/][~/.claude/]] itself nor any subtree
+containing the project-memory dirs is tracked in
+[[file:/home/cjennings/code/archsetup/][archsetup]] or
+[[file:/home/cjennings/code/rulesets/][rulesets]]. Without a symlink
+into a stowed or tracked location, memory files don't survive a new
+machine setup or a dotfiles restore.
+
+Proposed setup: stow =~/.claude/projects= →
+=archsetup/dotfiles/common/.claude/projects/= (path doesn't exist yet
+— it's the target location pending VERIFY).
+Create the destination in archsetup, move existing per-project
+=projects/<encoded-cwd>/memory/= dirs there, run =stow= to link, then
+commit + push archsetup. After that, every machine running =stow=
+picks up the same memory tree.
+
+*** VERIFY Approve stow-based sync of ~/.claude/projects via archsetup/dotfiles/common/
+** TODO [#B] Document rulesets + claude-templates pull-before-project ordering in protocols.org
+
+Startup currently pulls claude-templates in Phase A.0 and fast-forwards the
+project repo, but the rulesets repo (=~/code/rulesets/=) isn't pulled at all
+-- rule changes there don't reach the agent without a manual pull. The
+ordering and the "resolve any issues before proceeding" expectation also live
+in =startup.org= rather than =protocols.org= (the single entry point).
+
+Required ordering: rulesets first, then claude-templates, then local project.
+Resolve dirty-tree / merge issues at each step before moving on. Goal: every
+session starts against the freshest behavioral rules and workflow templates,
+not a stale local snapshot.
+
+Changes needed:
+1. Add a rulesets pull step to =startup.org= Phase A.0, mirroring the
+ existing claude-templates ff-only pull logic.
+2. State the ordering and the "resolve before proceeding" rule early in
+ =protocols.org= itself, not buried in a workflow file.
+
+** TODO [#A] Build =create-documentation= skill for high-quality project/product docs
+
+Create a Claude skill named =create-documentation= that can plan, write,
+refresh, and review software documentation across README files, project docs,
+developer guides, API docs, operational docs, and generated/published doc
+sites.
+
+This is broader than =arch-document=. =arch-document= should remain the
+architecture-specific arc42 skill. =create-documentation= should know when to
+delegate to it for architecture documentation, but its main job is the full
+documentation system around a product or repo: onboarding, tutorials, how-to
+guides, reference, explanation, operations, troubleshooting, contribution,
+release/upgrade, and publication format.
+
+*** Why this matters
+
+The repo currently has strong skills for architecture, testing, review,
+debugging, and workflow. It does not have a general documentation skill that:
+
+- Chooses the right documentation type for the user need.
+- Audits existing docs against code and expected user journeys.
+- Creates a coherent doc map instead of dumping everything into =README.md=.
+- Writes in a consistent technical style.
+- Decides source/publish format intentionally (=.md=, =.org=, generated
+ =.html=, OpenAPI, etc.).
+- Treats docs as a maintained product surface with verification, ownership,
+ navigation, accessibility, and freshness checks.
+
+*** Research notes
+
+**** Documentation frameworks and best-practice sources
+
+- Diataxis separates documentation by reader need:
+ - Tutorials: learning-oriented, take the reader by the hand.
+ - How-to guides: task-oriented, solve a specific real problem.
+ - Reference: information-oriented, accurate and complete lookup material.
+ - Explanation: understanding-oriented, concepts, background, tradeoffs.
+ Source: [[https://diataxis.fr/][Diataxis]] and the official guidance around
+ tutorials/how-to/reference/explanation.
+- Django explicitly documents this same organization and teaches readers how
+ to navigate it: tutorials for beginners, topic guides for concepts,
+ reference for APIs, how-to guides for recipes. This is a major reason the
+ docs feel navigable despite large scope.
+ Source: [[https://docs.djangoproject.com/en/5.2/][Django documentation]]
+- Kubernetes separates concepts, tasks, tutorials, and reference. It also has
+ current/previous-version docs, localization, contribution paths, and
+ task-focused landing pages. Its docs are good at answering "what is this?"
+ separately from "how do I do one thing?"
+ Sources: [[https://kubernetes.io/docs/home/][Kubernetes docs home]],
+ [[https://kubernetes.io/docs/tasks/][Kubernetes tasks]],
+ [[https://kubernetes.io/docs/tutorials/][Kubernetes tutorials]]
+- Write the Docs emphasizes docs that are precursory, participatory,
+ exemplary, consistent, current, discoverable, addressable, cumulative, and
+ comprehensive. Especially important: incorrect docs are worse than missing
+ docs, and examples should cover common use cases without overwhelming the
+ reference.
+ Source: [[https://www.writethedocs.org/guide/writing/docs-principles/][Write the Docs principles]]
+- Google developer docs guidance emphasizes project-specific style first,
+ clarity and consistency, conversational but not frivolous tone, active voice,
+ second person, descriptive links, global audience, accessibility, sentence
+ case headings, numbered lists for procedures, code font for code, and alt
+ text for images.
+ Sources: [[https://developers.google.com/style/][Google developer documentation style guide]],
+ [[https://developers.google.com/style/highlights][Google style highlights]],
+ [[https://developers.google.com/style/accessibility][Google accessible docs]]
+- Google's doc best-practices page adds a pragmatic maintenance principle:
+ minimum viable documentation, update docs with code, delete dead docs, prefer
+ good over perfect, tell the story of code, and avoid duplication.
+ Source: [[https://google.github.io/styleguide/docguide/best_practices.html][Google documentation best practices]]
+- The Good Docs Project is useful as a template source, especially for
+ README, how-to, tutorial, concept, reference, troubleshooting, contributor,
+ and release-note patterns. Do not vendor wholesale; use as prior art.
+ Source: [[https://www.thegooddocsproject.dev/][The Good Docs Project]]
+
+**** Praised project docs to analyze and steal from
+
+***** Django
+
+Why it works:
+- It labels the doc types directly and explains when to use each.
+- It has a beginner path, advanced tutorials, topic guides, API reference,
+ how-to recipes, deployment, security, testing, release notes, and community
+ help in one coherent index.
+- It is versioned, so readers know which framework version the docs target.
+- It cross-links introductory material to deeper references without making the
+ first page a wall of every detail.
+
+Patterns to use:
+- Make the top-level docs home a routing page by reader intent.
+- Put "How these docs are organized" near the top when the doc set is large.
+- Split concept, task, tutorial, and reference instead of mixing them.
+- Include "getting help" and "not found?" paths so the docs have an exit ramp.
+
+Source: [[https://docs.djangoproject.com/en/5.2/][Django documentation]]
+
+***** Kubernetes
+
+Why it works:
+- It has a large, complex product but maintains separate lanes for Concepts,
+ Tasks, Tutorials, Reference, and Contribute.
+- Task pages are short sequences for one operation; tutorials are larger goals
+ with several sections. This prevents "one page tries to teach everything."
+- It exposes version state clearly, including static old versions and current
+ docs.
+- It supports localization and documentation contribution, which makes the
+ docs a product surface rather than a side artifact.
+
+Patterns to use:
+- For platform or infrastructure docs, include Concepts / Tasks / Tutorials /
+ Reference as first-class folders.
+- Create version/freshness metadata when docs are tied to released software.
+- Add doc contribution guidance for projects with external contributors.
+- Make operational tasks discoverable by category, not just search.
+
+Sources: [[https://kubernetes.io/docs/home/][Kubernetes docs home]],
+[[https://kubernetes.io/docs/tasks/][Kubernetes tasks]]
+
+***** Rust
+
+Why it works:
+- Rust has a "bookshelf" rather than one overloaded manual: The Book, Rust by
+ Example, standard library API reference, Reference, Cargo Guide, Error Index,
+ Rustonomicon, release notes, platform support, policies, etc.
+- The learning path is honest about audience: "assume programmed before, not in
+ any specific language."
+- Reference and learning material are separated. Advanced unsafe guidance gets
+ its own book.
+- Offline docs via =rustup doc= are treated as part of the product.
+
+Patterns to use:
+- For broad ecosystems, create a documentation bookshelf rather than a single
+ mega-doc.
+- Separate beginner path, examples, formal reference, advanced/unsafe topics,
+ tooling docs, error index, release notes, and policies.
+- Document assumptions about reader experience.
+- Consider offline/local docs for CLI/library ecosystems.
+
+Source: [[https://doc.rust-lang.org/][Rust documentation]]
+
+***** Stripe API docs
+
+Why it works:
+- The API reference is organized around resources and common cross-cutting
+ concerns: authentication, errors, idempotency, pagination, request IDs,
+ versioning, metadata, connected accounts.
+- It pairs prose with concrete request/response examples and client-library
+ language selection.
+- It exposes test-mode vs live-mode distinctions early.
+- It offers "Copy for LLM" / "View as Markdown", which acknowledges modern
+ consumption patterns without sacrificing normal docs UX.
+- Its reputation comes from matching developer mental models and making the
+ common path implementable quickly, not just visual polish.
+
+Patterns to use:
+- API docs should be generated from or checked against OpenAPI/JSON schema or
+ source annotations wherever possible.
+- Keep cross-cutting API behavior near the front, before endpoint lists.
+- Include runnable examples, auth, errors, pagination, versioning, idempotency,
+ and sandbox/test data.
+- Consider LLM-friendly exports (=llms.txt=, "view as Markdown", stable
+ anchors), but do not make the docs only for AI.
+
+Source: [[https://docs.stripe.com/api][Stripe API Reference]]
+
+***** FastAPI
+
+Why it works:
+- Documentation is part of the framework's value proposition: OpenAPI and JSON
+ Schema drive interactive Swagger UI and ReDoc automatically.
+- It reduces manual drift for API reference by deriving docs from typed code.
+- It integrates examples and tutorial-style explanations with standards-based
+ generated reference.
+
+Patterns to use:
+- Prefer generated API reference from code/specs over hand-maintained endpoint
+ tables.
+- Generated docs need human-written overview, concepts, authentication,
+ examples, and operational guidance around them.
+- The skill should identify when an OpenAPI/Swagger/ReDoc/Scalar route already
+ exists and improve metadata/schema quality instead of creating duplicate
+ manual docs.
+
+Source: [[https://fastapi.tiangolo.com/features/][FastAPI features]]
+
+*** Format and presentation decisions
+
+**** Default source format: Markdown
+
+Use =.md= as the default for shared project documentation when:
+- The repo is on GitHub/GitLab/Forgejo and readers browse docs in the web UI.
+- The project already uses MkDocs, Docusaurus, VitePress, Sphinx+MyST,
+ Jekyll, GitHub Pages, or plain README-driven docs.
+- Contributors are expected to edit docs without Emacs-specific tooling.
+- The docs need easy static-site publishing.
+- The content is README, tutorial, how-to, reference, troubleshooting,
+ contributing, release notes, runbooks, or ordinary prose + code blocks.
+
+Markdown source works well because it is low-friction, reviewable in diffs,
+rendered by repository hosts, and supported by documentation site generators.
+MkDocs is a good reference point: Markdown source, YAML config, built-in dev
+server, static HTML output, and easy hosting.
+Source: [[https://www.mkdocs.org/][MkDocs]]
+
+**** Use Org when the document is Emacs-native or personal/planning-heavy
+
+Use =.org= when:
+- The user's workflow is explicitly Emacs/org-mode.
+- The document contains TODO states, schedules, priorities, tags, agenda
+ integration, property drawers, clocking, or personal planning.
+- The document is an internal strategy/planning artifact such as V2MOM,
+ research notes, meeting notes, task triage, or a living personal operating
+ document.
+- The output may later be exported, but the source of truth is intended to be
+ edited in org-mode.
+
+Do not default team-facing documentation to =.org= unless the team already uses
+org-mode. Org can export to HTML, but that does not make it the right authoring
+format for non-Emacs contributors.
+Sources: [[https://orgmode.org/org.html][Org manual]],
+[[https://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html][Org publish HTML tutorial]]
+
+**** Use HTML as generated/published output, rarely as hand-authored source
+
+Use =.html= when:
+- The deliverable is a published static documentation site.
+- The document needs interactive widgets, embedded API consoles, custom layout,
+ or generated navigation/search.
+- The project already publishes docs as a website.
+- The target audience needs searchable, browsable, linkable pages rather than
+ repo-local files.
+
+Prefer generated HTML from Markdown/Org/reStructuredText/AsciiDoc/OpenAPI over
+hand-authored HTML. Hand-edit HTML only for standalone artifacts, custom landing
+pages, or cases where the project already treats HTML templates as docs source.
+
+**** Consider generated/spec-backed formats
+
+Use generated reference when possible:
+- API reference: OpenAPI/Swagger/ReDoc/Scalar from code/spec.
+- CLI reference: generated from command parser/help output.
+- Library API reference: language-native doc tools such as rustdoc, pydoc,
+ TypeDoc, JSDoc, Go doc, Sphinx autodoc, etc.
+- Config reference: generated from schema, types, or validated defaults.
+
+The skill should not duplicate generated reference by hand. It should improve
+source comments, schema descriptions, examples, front matter, and surrounding
+guides.
+
+**** Presentation requirements
+
+Every generated doc set should have:
+- A docs home or README that routes by reader intent.
+- Stable headings and anchors for addressability.
+- Descriptive link text, no "click here."
+- Search/navigation plan when docs exceed a handful of pages.
+- Version/freshness metadata when tied to released software.
+- Ownership/review cadence for docs likely to rot.
+- Accessible structure: semantic headings, alt text, no image-only info,
+ tables only when appropriate, left-aligned text, readable code blocks.
+- Copyable commands and code examples.
+- "What changed?" / release notes / migration path when docs describe a new or
+ changed behavior.
+- Troubleshooting path for common failures.
+- Clear prerequisites before procedures.
+- Verification steps after procedures.
+- Support/escalation path when the docs do not answer the question.
+- Optional LLM-friendly surfaces for larger doc sets: =llms.txt=,
+ "copy as Markdown" equivalents, concise page summaries, and stable anchors.
+
+*** Proposed skill design
+
+**** Skill name and trigger
+
+Name: =create-documentation=
+
+Trigger when the user asks to:
+- create documentation, docs, README, guide, manual, runbook, tutorial,
+ quickstart, API docs, CLI docs, troubleshooting docs, contributor docs,
+ architecture-adjacent docs, release notes, upgrade guide, or doc site;
+- improve, audit, reorganize, or publish existing docs;
+- decide documentation structure or format for a project.
+
+Do not trigger for:
+- architecture-only arc42 docs when =arch-document= is the direct fit;
+- ADR creation (=arch-decide=);
+- design docs before implementation shape is known (=brainstorm= or
+ =arch-design=);
+- prose polishing only (future writing/humanizer skill);
+- inline code comments/docstrings only, unless the user asks to create docs
+ from them.
+
+**** V1 should be one orchestrating skill, not many separate skills
+
+Build v1 as one skill with explicit phases and subcommands rather than a set
+of separate skills. Rationale:
+- Documentation tasks often start ambiguous; the first job is classification.
+- Splitting too early creates command-discovery burden.
+- A single skill can dispatch to existing specialized skills
+ (=arch-document=, =c4-diagram=, =security-check=, =playwright-js/py= for
+ doc-site verification) without making users choose the internal pipeline.
+
+Support discoverable subcommands inside one skill:
+
+#+begin_example
+/create-documentation audit <path>
+/create-documentation plan <path-or-scope>
+/create-documentation write <doc-type> <scope>
+/create-documentation refresh <path>
+/create-documentation publish <path>
+/create-documentation review <path>
+#+end_example
+
+The default =/create-documentation <scope>= runs audit -> plan -> write ->
+review, asking for confirmation before broad rewrites.
+
+**** Future split if v1 gets too large
+
+If the skill grows past a manageable size, split into a discoverable
+=documentation-*= chain. Names and order:
+
+1. =documentation-audit= — inventory existing docs, code/docs drift, reader
+ journeys, missing doc types, stale/generated docs.
+2. =documentation-plan= — choose audiences, doc map, formats, source of truth,
+ publishing path, ownership, and freshness policy.
+3. =documentation-write= — write or update the selected docs.
+4. =documentation-reference= — generate or improve API/CLI/config/library
+ reference from source/spec.
+5. =documentation-publish= — configure MkDocs/Docusaurus/Sphinx/GitHub Pages
+ or equivalent, build static HTML, verify links/search.
+6. =documentation-review= — quality gate for accuracy, style, navigation,
+ accessibility, examples, and freshness.
+
+Keep =create-documentation= as the orchestrator and user-facing entry point.
+The chain is discoverable because every helper starts with =documentation-= and
+the orchestrator prints the next command at each handoff.
+
+*** V1 workflow details
+
+**** Phase 1: Intake and classification
+
+Ask only what is missing from local context:
+- Who is the reader? New user, evaluator, integrator, maintainer, operator,
+ contributor, auditor, support engineer?
+- What is the reader trying to do or understand?
+- Is this for a public project, internal team, personal workflow, regulated
+ audience, or customer-facing product?
+- Is the output repo-browsed, web-published, printed/exported, or Emacs-native?
+- Is there existing code, existing docs, an API spec, generated reference, or
+ only a concept?
+- What is the maintenance expectation? One-off, release-maintained,
+ continuously updated?
+
+Classify the work into one or more doc types:
+- README / landing page.
+- Quickstart.
+- Tutorial.
+- How-to guide.
+- Concept/explanation.
+- API reference.
+- CLI reference.
+- Configuration reference.
+- Architecture docs (delegate to =arch-document= if arc42/C4/ADR-driven).
+- Operations/runbook.
+- Troubleshooting/FAQ.
+- Upgrade/migration/release notes.
+- Contributor/development docs.
+- Security/compliance docs.
+- Examples/cookbook.
+
+**** Phase 2: Audit existing material
+
+Inventory:
+- =README*=, =docs/=, =doc/=, =site/=, =mkdocs.yml=, =docusaurus.config.*=,
+ =vitepress=, =sphinx=, =docs.rs=, =pkg.go.dev=, OpenAPI specs,
+ generated docs folders, GitHub Pages config, ADRs, architecture docs,
+ examples, scripts, CLI help, package metadata.
+- Existing doc type coverage: tutorial/how-to/reference/explanation.
+- Broken links, stale version numbers, commands that no longer exist,
+ screenshots that may be stale, code snippets not exercised, doc/code drift.
+- Source of truth for generated docs. Flag generated files; do not hand-edit
+ them until source is known.
+- Reader journey gaps: "new user can install?", "first success path?",
+ "operator can recover?", "contributor can run tests?", "API consumer can
+ authenticate and handle errors?"
+
+Use =rg= first. For API/CLI reference, prefer structured sources:
+OpenAPI/JSON Schema, package metadata, command =--help= output, docstrings, or
+language-native documentation tooling.
+
+**** Phase 3: Documentation plan
+
+Write a short plan before broad edits:
+- Audiences and priority order.
+- Proposed doc map/tree.
+- Doc type for each page.
+- Source format decision: =.md= / =.org= / generated spec / generated HTML.
+- Publishing target, if any.
+- Existing docs to preserve, move, merge, or delete.
+- Generated-reference strategy.
+- Ownership and freshness policy.
+- Verification plan.
+
+Stop for confirmation when the plan moves or rewrites more than one file.
+
+**** Phase 4: Write or update docs
+
+Writing rules:
+- Lead with the reader's goal, not the implementation history.
+- Put prerequisites before steps.
+- Use numbered lists for procedures.
+- Use bullets for non-ordered choices.
+- Use active voice and second person for instructions.
+- Keep sentences short and globally readable.
+- Define acronyms on first use.
+- Use code font for commands, file names, env vars, API names, and literals.
+- Use descriptive links.
+- Prefer examples that cover the common path and one meaningful edge/error
+ path.
+- Separate examples/tutorials from dense reference.
+- Avoid stale duplication: link to canonical generated reference instead of
+ copying it.
+- Include expected output after commands where it helps verification.
+- Include cleanup/rollback steps when procedures change state.
+- Include troubleshooting for common failures.
+- Avoid marketing voice in technical docs. State capability and constraints
+ plainly.
+- No AI attribution in docs, examples, comments, generated pages, footers, or
+ screenshots.
+
+Page skeletons:
+
+README / docs home:
+#+begin_example
+# <Project>
+
+<One-paragraph purpose>
+
+## Start here
+- New user: <quickstart>
+- Existing user with a task: <how-to index>
+- API lookup: <reference>
+- Maintainer/operator: <operations/contributing>
+
+## Quick example
+...
+
+## Documentation map
+...
+
+## Support / contributing
+...
+#+end_example
+
+Tutorial:
+#+begin_example
+# Tutorial: <goal>
+
+## What you'll build
+## Prerequisites
+## Step 1 ...
+## Checkpoint
+## Step 2 ...
+## What you learned
+## Next
+#+end_example
+
+How-to:
+#+begin_example
+# How to <task>
+
+## When to use this
+## Prerequisites
+## Steps
+## Verify
+## Troubleshooting
+## Related
+#+end_example
+
+Reference:
+#+begin_example
+# <Thing> reference
+
+## Summary
+## Parameters / options / fields
+## Behavior
+## Errors
+## Examples
+## Version notes
+#+end_example
+
+Explanation:
+#+begin_example
+# <Concept>
+
+## Problem it solves
+## Mental model
+## How it fits with related concepts
+## Tradeoffs and constraints
+## Further reading
+#+end_example
+
+Runbook:
+#+begin_example
+# Runbook: <operation>
+
+## Scope
+## Preconditions
+## Normal procedure
+## Verification
+## Rollback
+## Alerts and escalation
+## Post-incident notes
+#+end_example
+
+**** Phase 5: Presentation and publishing
+
+If docs are repo-local only:
+- Ensure links render on GitHub/GitLab.
+- Keep relative links stable.
+- Add an index if more than 4-5 docs exist.
+
+If docs are web-published:
+- Detect existing generator and follow it.
+- Prefer project-native tooling over introducing MkDocs/Docusaurus/Sphinx.
+- If no tooling exists and user wants a site, choose conservatively:
+ - Python/simple repo: MkDocs Material is a pragmatic default.
+ - JS/React ecosystem: Docusaurus or VitePress if already in stack.
+ - Python libraries: Sphinx or MkDocs depending on existing ecosystem.
+ - API docs: ReDoc/Swagger/Scalar from OpenAPI.
+- Build locally if dependencies exist.
+- Check links, nav, search, mobile viewport, and accessibility basics.
+- Do not commit generated =site/= output unless the project already does.
+
+**** Phase 6: Verification
+
+Verification should match doc type:
+- Commands in quickstarts/how-tos: run them or mark not run with reason.
+- Code snippets: compile/run where feasible, or use fenced language and note
+ assumptions.
+- API docs: validate OpenAPI/spec if tooling exists.
+- Links: run link checker if configured; otherwise sample-check changed links.
+- Published site: build docs and inspect output.
+- Screenshots: verify current UI if included.
+- Generated docs: regenerate from source and confirm no unexpected diff.
+
+Final report must say:
+- Files created/changed.
+- Doc types covered.
+- Format/source-of-truth decisions.
+- What was verified.
+- What could not be verified.
+- Known gaps/follow-ups.
+
+*** Relationship to existing skills
+
+- =arch-document=: use when the requested docs are specifically architecture
+ docs from brief + ADRs + C4/arc42. =create-documentation= may call it, then
+ wrap the output in a broader docs map.
+- =c4-analyze= / =c4-diagram=: use for diagrams in architecture or concept
+ docs when visual structure helps.
+- =brainstorm=: use before =create-documentation= when the product/feature
+ itself is still unclear.
+- =arch-design= / =arch-decide=: use when documentation reveals missing
+ architectural choices.
+- =security-check=: use when docs include security guidance, auth, secrets,
+ deployment, or compliance claims.
+- =playwright-js= / =playwright-py=: use to verify published doc sites,
+ interactive docs, screenshots, and browser-rendered examples.
+- =codify=: use after a documentation session reveals reusable project-specific
+ documentation rules.
+
+*** Quality bar and anti-patterns
+
+The skill should reject:
+- A giant README that mixes tutorial, reference, architecture, and operations.
+- Duplicating generated API/CLI/config reference by hand.
+- Unverified commands in quickstarts without a "not run" note.
+- Screenshots with no alt text or no update path.
+- Tables used for layout instead of actual tabular data.
+- "Overview" pages that do not route readers to tasks.
+- Tutorials that become reference dumps.
+- How-to guides that explain concepts for pages before giving steps.
+- Reference pages that hide required options in prose.
+- Marketing claims without concrete examples.
+- Docs that mention local private paths, personal tooling, or AI attribution in
+ public artifacts.
+- Publishing generated HTML as source unless the project explicitly owns HTML
+ docs that way.
+
+*** Acceptance criteria for building the skill
+
+- [ ] Directory =create-documentation/= with =SKILL.md=.
+- [ ] Frontmatter description includes positive and negative triggers.
+- [ ] Skill body includes the V1 phases above.
+- [ ] Includes a source-format decision table for =.md= / =.org= / =.html= /
+ generated spec/reference.
+- [ ] Includes doc-type classifier based on Diataxis plus README/runbook/API
+ additions.
+- [ ] Includes examples/skeletons for README, tutorial, how-to, reference,
+ explanation, runbook, troubleshooting, contributor docs, and API overview.
+- [ ] Includes audit checklist for existing repos.
+- [ ] Includes publishing guidance without hardcoding one static-site tool.
+- [ ] Includes verification checklist and "unable to verify" reporting.
+- [ ] Cross-references =arch-document=, =brainstorm=, =security-check=,
+ =playwright-js=, =playwright-py=, and =codify=.
+- [ ] Adds =references/= only if needed; suggested files:
+ - =references/doc-type-decision.md=
+ - =references/style-guide.md=
+ - =references/format-decision.md=
+ - =references/page-skeletons.md=
+ - =references/doc-audit-checklist.md=
+- [ ] Keep =SKILL.md= concise enough to load; move long skeletons/checklists to
+ references for progressive disclosure.
+- [ ] Run =./scripts/lint.sh= after adding the skill.
+
+*** Open design questions before implementation
+
+- Should the user-facing command be exactly =/create-documentation= while
+ internal helper names use =documentation-*=, or should all names share the
+ =create-documentation <subcommand>= form? Recommendation: one skill with
+ subcommands for v1.
+- Should Markdown be the hard default for team docs? Recommendation: yes,
+ unless the project already uses org/reST/AsciiDoc or the output is personal
+ Emacs-native planning.
+- Should the skill create a docs site automatically? Recommendation: no. It
+ should propose a site when the doc set exceeds README-scale or when search,
+ versioning, or public publishing is required. Ask before adding tooling.
+- Should it write docs before code exists? Recommendation: yes for specs,
+ user journeys, and design docs, but route unclear feature/product decisions
+ through =brainstorm= or =arch-design= first.
+- Should it include LLM-specific docs surfaces? Recommendation: optional for
+ public/library/API docs: =llms.txt= or markdown export is valuable, but normal
+ human navigation remains primary.
+
+** TODO [#A] Review pass: tighten skills and rulesets after 2026-05-04 audit
+
+Source notes used in this pass:
+- C4 official docs: C4 is notation-independent; System Context and Container
+ diagrams are enough for most teams; every diagram needs title, key/legend,
+ explicit element types, and audience-appropriate abstraction.
+ [[https://c4model.com/diagrams][C4 diagrams]],
+ [[https://c4model.com/diagrams/notation][C4 notation]],
+ [[https://c4model.com/abstractions/component][C4 component]]
+- arc42 docs: quality requirements need measurable scenarios; section 10
+ should reference top quality goals and capture lesser quality requirements
+ with specific measures. [[https://docs.arc42.org/section-10/][arc42 section 10]],
+ [[https://quality.arc42.org/articles/specify-quality-requirements][specifying quality requirements]]
+- ADR references: ADRs capture one justified architecturally significant
+ decision and its rationale; Nygard's original guidance emphasizes short,
+ numbered, repository-stored records and superseding rather than rewriting old
+ decisions. [[https://adr.github.io/][adr.github.io]],
+ [[https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions][Nygard ADR article]]
+- Playwright docs: prefer user-visible locators and web assertions; locators
+ auto-wait and retry; =networkidle= is discouraged for testing readiness.
+ [[https://playwright.dev/docs/best-practices][Playwright best practices]],
+ [[https://playwright.dev/docs/locators][Playwright locators]],
+ [[https://playwright.dev/docs/next/api/class-page][Playwright page API]]
+- OWASP references: Top 10 2021 includes Broken Access Control,
+ Cryptographic Failures, Injection, Insecure Design, Security
+ Misconfiguration, Vulnerable and Outdated Components, Identification and
+ Authentication Failures, Software and Data Integrity Failures, Security
+ Logging and Monitoring Failures, and SSRF; WSTG adds a broader testing map
+ across configuration, identity, authn/z, sessions, input validation, error
+ handling, cryptography, business logic, client-side, and API testing.
+ [[https://owasp.org/Top10/2021/][OWASP Top 10 2021]],
+ [[https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/][OWASP WSTG]]
+- V2MOM references: Salesforce calls the last M "Measures" and emphasizes a
+ simple alignment document with prioritized Methods, explicit Obstacles, and
+ measurable outcomes. [[https://trailhead.salesforce.com/content/learn/modules/selfmotivation/get-focused-with-your-personal-v2mom][Salesforce Trailhead personal V2MOM]],
+ [[https://www.salesforce.com/blog/?p=12][Salesforce V2MOM alignment]]
+- Prompt research: the cited Meincke paper is titled "Call Me A Jerk:
+ Persuading AI to Comply with Objectionable Requests"; its scope is
+ persuasion increasing compliance with objectionable requests, not a general
+ proof that persuasion framing improves prompt quality.
+ [[https://papers.ssrn.com/sol3/papers.cfm?abstract_id=5357179][SSRN paper]]
+- Combinatorial testing references: NIST supports t-way combinatorial testing
+ and notes pairwise is one covering strength, with higher-strength arrays
+ useful for failures requiring more interacting factors.
+ [[https://www.nist.gov/publications/practical-combinatorial-testing-beyond-pairwise][NIST beyond pairwise]],
+ [[https://www.nist.gov/publications/combinatorial-software-testing][NIST combinatorial testing]]
+
+*** Grouped index (for batching by area)
+
+Each item below is a one-line summary of a sub-TODO further down. Tick the box when the matching sub-TODO is moved to =DONE=. Items are grouped by area so they can be batched (e.g., "do all Playwright items in one session").
+
+**** Browser testing
+- [ ] [#A] =playwright-js=: locator/assertion-first guidance (replace raw CSS, =networkidle=)
+- [ ] [#B] =playwright-js= + =playwright-py=: reconcile headless/visible defaults
+- [ ] [#B] =playwright-js= + =playwright-py=: remove emoji console markers from examples
+
+**** Frontend / UI
+- [ ] [#B] =frontend-design=: WCAG 2.2 alignment, accessibility non-optional
+- [ ] [#B] =frontend-design=: harmonize aesthetic guidance with anti-pattern rules
+
+**** Security
+- [ ] [#A] =security-check=: OWASP 2021 + WSTG coverage
+- [ ] [#B] =security-check=: tooling and offline/network caveats
+
+**** Combinatorial testing
+- [ ] [#B] =pairwise-tests=: t-way escalation guidance beyond pairwise
+- [ ] [#B] =pairwise-tests=: clarify negative value syntax + generator availability
+
+**** V2MOM
+- [ ] [#A] =create-v2mom=: rename Metrics → Measures (Salesforce alignment)
+- [ ] [#B] =create-v2mom=: prevent task migration from turning V2MOM into a backlog
+- [ ] [#B] =create-v2mom=: mitigation/owner fields for Obstacles
+
+**** Prompt engineering
+- [ ] [#A] =prompt-engineering=: correct/narrow Meincke citation
+- [ ] [#B] =prompt-engineering=: eval-harness requirement for production prompts
+
+**** Codify
+- [ ] [#B] =codify=: stale-entry review + privacy checks before writing project =CLAUDE.md=
+
+**** Code review
+- [ ] [#A] =review-code=: resolve local-verification vs CI boundary
+- [ ] [#B] =review-code=: =CLAUDE.md= citation scope for public artifacts
+- [ ] [#B] =review-code=: relax three-strengths rule for tiny/failing diffs
+
+**** PR / review responses
+- [ ] [#A] =respond-to-review=: remove review-process language from commit messages
+- [ ] [#B] =respond-to-review=: use unresolved threads + resolution state
+- [ ] [#B] =respond-to-cj-comments=: drop personal absolute paths from public-writing
+- [ ] [#B] =respond-to-cj-comments=: fallback when =humanizer= or =emacsclient= unavailable
+
+**** Branch workflow
+- [ ] [#A] =finish-branch=: fix base-branch detection
+- [ ] [#B] =finish-branch=: worktree-aware pull/merge safety
+- [ ] [#B] =start-work=: tool-availability + ceremony-scaling rules
+- [ ] [#B] =start-work=: claim-before-justify rollback risk
+
+**** Tests / TDD
+- [ ] [#B] =add-tests=: fix missing =typescript-testing.md= reference or add ruleset
+- [ ] [#B] =add-tests=: explicit exceptions to "all three categories per function"
+
+**** Debugging / RCA
+- [ ] [#B] =debug=: capture environment + recent-change context before hypotheses
+- [ ] [#B] =root-cause-trace=: constrain defense-in-depth to trust boundaries
+- [ ] [#B] =five-whys=: require evidence + counterfactual validation per why
+
+**** Brainstorming
+- [ ] [#B] =brainstorm=: timebox + research/source rules for high-stakes designs
+
+**** Architecture
+- [ ] [#B] =arch-decide=: timeless examples, drop unverifiable claims
+- [ ] [#B] =arch-decide=: standardize statuses + immutability language
+- [ ] [#B] =arch-design=: threat modeling + privacy/compliance as first-class inputs
+- [ ] [#B] =arch-design=: separate paradigms from tactical patterns
+- [ ] [#B] =arch-document=: arc42/Q42 quality scenarios
+- [ ] [#B] =arch-document=: staleness + ownership metadata for generated docs
+- [ ] [#B] =arch-evaluate=: confidence levels for framework-agnostic findings
+- [ ] [#B] =arch-evaluate=: report skipped tool checks explicitly
+
+**** C4 modeling
+- [ ] [#A] =c4-analyze= + =c4-diagram=: notation/output fallback (not draw.io-only)
+- [ ] [#B] =c4-analyze= + =c4-diagram=: clarify abstraction boundaries
+
+**** Global rules
+- [ ] [#B] =commits.md=: split DeepSat/Linear/Slack-specific from global rules
+- [ ] [#A] =commits.md= + publish flows: =humanizer=-unavailable fallback
+- [ ] [#B] =verification.md=: explicit "unable to verify" reporting standard
+- [ ] [#B] =testing.md=: property-based + mutation testing as escalation paths
+- [ ] [#B] =testing.md=: soften absolute TDD with explicit spike protocol
+- [ ] [#B] =subagents.md=: capability/availability + cost checks
+
+**** Languages
+- [ ] [#A] =python-testing.md=: revisit in-memory SQLite guidance
+- [ ] [#B] =python-testing.md=: separate "never mock ORM" from unit-test boundaries
+- [ ] [#B] =elisp.md=: drop tool-specific advice
+- [ ] [#B] =elisp-testing.md=: batch-mode + native-comp caveats
+
+**** Hooks
+- [ ] [#A] =hooks/README.md=: include =destructive-bash-confirm.py= in install/settings snippets
+- [ ] [#A] =hooks/git-commit-confirm.py= + =gh-pr-create-confirm.py=: inspect message/body files referenced by =-F= / =--body-file=
+- [ ] [#B] =hooks/destructive-bash-confirm.py=: shell-aware command parsing (not regex)
+
+*** TODO [#A] =playwright-js=: replace raw CSS/page actions and =networkidle= defaults with locator/assertion-first guidance
+
+Current examples lean on =page.click=, =page.fill=, =waitForSelector=, and
+=waitForLoadState('networkidle')=. Official Playwright guidance prefers
+locators based on user-visible attributes, web assertions for readiness, and
+calls =networkidle= discouraged for testing. Keep reconnaissance, but revise it
+to wait for a visible app-specific landmark instead of treating network quiet
+as readiness.
+
+*** TODO [#A] =playwright-js= and =playwright-py=: reconcile headless/visible-browser defaults
+
+=playwright-js= says visible Chromium by default; =playwright-py= says
+headless by default. That may be intentional, but the difference should be
+explicit: interactive visual debugging -> headed, CI/pytest smoke tests ->
+headless. Add a small decision table so agents don't flip modes by habit.
+
+*** TODO [#A] =playwright-js= and =playwright-py=: remove emoji console markers from examples
+
+The broader rules discourage emojis in shared engineering output. The
+Playwright examples print camera/check/cross emoji. Replace with plain ASCII
+status prefixes.
+
+*** TODO [#A] =frontend-design=: make accessibility non-optional and align with WCAG 2.2
+
+The workflow only loads =references/accessibility.md= for interactive
+components. Accessibility should be a baseline for all frontend work: keyboard
+operation, focus visibility/not-obscured, target size, contrast, reduced
+motion, labels, and semantic structure. Add WCAG 2.2-oriented gates before
+handoff.
+
+*** TODO [#A] =frontend-design=: harmonize aesthetic guidance with current UI anti-pattern rules
+
+The skill encourages gradient meshes, heavy texture, custom cursors, overlap,
+and maximalist directions. Those can conflict with the repo's newer frontend
+discipline against generic gradients, decorative blobs/orbs, text overlap,
+single-hue palettes, unreadable layouts, and marketing-style dashboards. Add a
+"creative but bounded" section: domain fit, readability, responsive stability,
+and no decorative effects that degrade the task workflow.
+
+*** TODO [#A] =security-check=: update OWASP coverage to the 2021 categories and WSTG test areas
+
+The current security checklist uses older category names and misses several
+current Top 10 items: Insecure Design, Software and Data Integrity Failures,
+Security Logging and Monitoring Failures, and SSRF. Expand the review table so
+each finding maps to either OWASP Top 10 2021 or a WSTG area, and add explicit
+checks for authorization object/function-level access, SSRF URL fetches,
+integrity of update/plugin paths, and security-relevant logging gaps.
+
+*** TODO [#A] =security-check=: add practical tooling and offline/network caveats
+
+Add optional use of project-configured scanners such as =gitleaks= or
+=trufflehog= for secrets, =semgrep= for source patterns, =pip-audit= / =npm
+audit= / OSV where configured, and lockfile diff review. Note that dependency
+audits may need network access and should report "not run" clearly rather than
+silently passing.
+
+*** TODO [#A] =pairwise-tests=: add t-way escalation guidance beyond pairwise
+
+Pairwise is a pragmatic default, but NIST's combinatorial testing work covers
+higher-strength t-way arrays too. Add a rule: start with pairwise for broad
+coverage, escalate selected high-risk parameter clusters to 3-way or higher
+when history, safety, security, or domain reasoning suggests faults require
+more than two interacting factors.
+
+*** TODO [#A] =pairwise-tests=: clarify negative value syntax and actual generator availability
+
+The examples use =~0= style values that are PICT-specific and easy to
+misread. Add a short "negative testing values are labels, not operators unless
+PICT treats them specially" explanation, and make the run path honest: if PICT
+or =pypict= is unavailable, produce the model and stop instead of implying
+cases were generated.
+
+*** TODO [#A] =create-v2mom=: rename "Metrics" to Salesforce's "Measures" or explicitly justify the deviation
+
+V2MOM's final M is officially "Measures." The skill uses "Metrics" throughout.
+Either rename the section and description to "Measures" or add a clear note
+that this fork intentionally says "Metrics" while preserving the V2MOM concept.
+
+*** TODO [#A] =create-v2mom=: prevent task migration from turning V2MOM into a backlog
+
+Salesforce presents V2MOM as a simple alignment framework. This skill's
+optional task-migration phase can make the V2MOM the entire todo system. Split
+strategy from execution: keep the V2MOM concise, and link to method-specific
+backlogs instead of embedding every task under the strategic document.
+
+*** TODO [#A] =create-v2mom=: add mitigation/owner fields for Obstacles
+
+The current Obstacles phase captures barriers but not consistently how each
+will be overcome. Add "mitigation, owner, and review cadence" per obstacle so
+the section becomes operational instead of just candid.
+
+*** TODO [#A] =prompt-engineering=: correct and narrow the Meincke citation
+
+The skill cites "Persuasion and Compliance in Large Language Models" but the
+paper found in research is "Call Me A Jerk: Persuading AI to Comply with
+Objectionable Requests." Revise the reference and avoid overgeneralizing the
+result: it shows persuasion can raise compliance with objectionable requests,
+which is a cautionary prompt-safety finding, not broad evidence that persuasion
+principles improve engineering prompt quality.
+
+*** TODO [#A] =prompt-engineering=: add an evaluation harness requirement for production prompts
+
+Prompt critique currently ends with a rewrite and checklist. Add a requirement
+for fragile or reusable prompts: create 3-5 adversarial/edge examples, run the
+old and new prompt against them, and record the observed behavioral delta.
+Without examples, prompt quality remains asserted rather than verified.
+
+*** TODO [#A] =codify=: add stale-entry review and privacy checks before writing project =CLAUDE.md=
+
+The skill has good gates, but it should explicitly scan for stale entries,
+private context, and team-visible leakage before appending. Add "would this be
+safe if the project were public?" and "does this belong in private memory
+instead?" as mandatory checks, not just table background.
+
+*** TODO [#A] =review-code=: resolve the local-verification vs CI boundary
+
+=review-code= says "Trust CI for lint, typecheck, test runs; don't re-run
+them." =verification.md= and =finish-branch= require fresh local evidence
+before completion. Clarify: code review should not duplicate CI while reading a
+PR, but pre-commit/pre-push workflows still need local verification or a clear
+"not run because..." statement.
+
+*** TODO [#A] =review-code=: handle public-artifact scope when citing =CLAUDE.md=
+
+The skill requires auditing and reporting =CLAUDE.md= adherence, while
+=commits.md= says personal tooling files should not be cited as authority in
+public artifacts. Add two output modes: private/internal review may cite
+=CLAUDE.md= directly; public/team review should translate the rule into the
+underlying engineering reason without naming personal rulesets.
+
+*** TODO [#A] =review-code=: relax mandatory "three strengths" for tiny or failing diffs
+
+"Three minimum" strengths can force filler on small diffs or bad PRs. Adjust to
+"up to three specific strengths; say none found when appropriate" so the review
+stays honest and avoids synthetic praise.
+
+*** TODO [#A] =respond-to-review=: remove review-process language from commit messages
+
+The skill suggests commits like =fix: Address review — [description]=, which
+conflicts with =commits.md='s "what changed and why, not the process" rule and
+also uses a non-ASCII dash. Replace with conventional subjects that name the
+actual fix, e.g. =fix: validate export filename=.
+
+*** TODO [#A] =respond-to-review=: use unresolved review threads and resolution state, not only flat comments
+
+Fetching inline and top-level comments via REST misses thread resolution and
+can re-process already-resolved feedback. Add the same thread-level workflow as
+the GitHub comment-addressing skill: gather unresolved threads, group by
+requested change, implement, reply, and resolve only after verification.
+
+*** TODO [#A] =respond-to-cj-comments=: remove personal absolute path references from public-writing instructions
+
+The skill embeds =/home/cjennings/code/rulesets/claude-rules/commits.md= in
+the public-writing section. That contradicts the public-artifact scope rule.
+Refer to "the commit/public-writing rules" internally, and ensure any emitted
+public text never cites the local path.
+
+*** TODO [#A] =respond-to-cj-comments=: add fallback when =humanizer= or =emacsclient= is unavailable
+
+The workflow requires =/humanizer= and opens long summaries in =emacsclient=.
+Neither is guaranteed in a fresh environment. Add tool-availability checks and
+fallbacks: apply the style passes inline if =humanizer= is absent, and write the
+summary file path without opening an editor if =emacsclient= fails.
+
+*** TODO [#A] =finish-branch=: fix base-branch detection
+
+Phase 2 says "determine base branch" but the command shown returns a merge-base
+commit SHA, not the branch name to check out, pull, merge into, or pass as PR
+base. Replace with explicit branch detection: upstream PR base if present,
+configured default branch from =origin/HEAD=, or user-selected branch, then
+compute merge-base separately.
+
+*** TODO [#A] =finish-branch=: make pull/merge steps safer and worktree-aware
+
+Option 1 runs =git pull= and =git merge --no-ff= after checkout. Add checks for
+dirty worktree, upstream tracking, protected branches, and rebase-vs-merge team
+policy. Worktree detection via grepping branch names is fragile; use =git
+worktree list --porcelain= or =git rev-parse --git-common-dir= based checks.
+
+*** TODO [#A] =start-work=: add tool-availability and ceremony-scaling rules
+
+The workflow assumes Linear MCP, GitHub CLI, =humanizer=, Playwright skills, and
+multi-commit TDD ceremony. Add a first-class "tools unavailable" path and a
+ceremony scale: trivial local fixes should not require the full ticket,
+branch, three approval gates, and commit-per-phase flow unless the user wants
+that process.
+
+*** TODO [#A] =start-work=: resolve the "claim before justify" rollback risk
+
+The skill marks Linear/GitHub/todo tasks in progress before the Justify gate,
+then says rolling back is required if justification fails. Consider moving
+claiming after Gate 1 for personal todo tasks, or make the rollback steps
+explicit per tracker with stored prior state.
+
+*** TODO [#A] =add-tests=: fix missing =typescript-testing.md= reference or add the ruleset
+
+Phase 3 references =typescript-testing.md=, but this repo currently has Python
+and Elisp testing rules only. Either add the TypeScript ruleset or change the
+skill to discover project-local JS/TS testing conventions instead of pointing
+to a missing file.
+
+*** TODO [#A] =add-tests=: add explicit exceptions to "all three categories per function"
+
+The Normal/Boundary/Error rule is useful, but some functions are pure adapters,
+generated code, tiny wrappers, or framework glue. Add an exception protocol:
+state why a category does not apply, and cover the behavior at the integration
+or E2E level when unit categories would test framework behavior.
+
+*** TODO [#A] =debug=: capture environment and recent-change context before hypotheses
+
+The debugging workflow covers reproduction and logs, but should explicitly
+record environment, versions, feature flags, data set, seed/time, concurrency,
+and recent commits/config changes. Many intermittent failures are environment
+or state transitions, not just local code paths.
+
+*** TODO [#A] =root-cause-trace=: constrain defense-in-depth to trust boundaries and invariants
+
+The skill says add defense at each intermediate layer that could have caught
+the bad value. That risks validation spam. Tighten it: add checks at ingress,
+trust boundaries, persistence boundaries, and invariant-owning layers; avoid
+duplicative null checks in every pass-through function.
+
+*** TODO [#A] =five-whys=: require evidence and counterfactual validation per why
+
+The skill says "one best-supported answer" but should require an evidence
+field for each link and a counterfactual check: if this cause were removed,
+would the next symptom plausibly disappear? This reduces monocausal storytelling.
+
+*** TODO [#A] =brainstorm=: add timebox and research/source rules for high-stakes designs
+
+The one-question-at-a-time flow can run long. Add a timebox and a rule that
+claims about markets, regulations, tools, vendors, or current APIs require
+fresh sources. The design doc should distinguish researched facts from
+assumptions.
+
+*** TODO [#A] =arch-decide=: make examples technically timeless and avoid unverifiable claims
+
+The sample ADRs include claims such as MongoDB lacking ACID for multi-document
+transactions "at decision time." Examples age and can teach stale facts. Replace
+with either clearly dated examples or domain-neutral placeholders, and require
+references for real technical claims in generated ADRs.
+
+*** TODO [#A] =arch-decide=: standardize statuses and immutability language
+
+The skill mixes Accepted, Decided, Deprecated, Superseded, Rejected, and "Not
+Accepted." Pick a canonical status set and state that accepted ADR content is
+not edited except for status/link metadata; changed decisions get new ADRs that
+supersede old ones.
+
+*** TODO [#A] =arch-design=: add threat modeling and privacy/compliance as first-class design inputs
+
+Security appears as one quality attribute, but architecture design should also
+ask about trust boundaries, data classification, abuse cases, privacy
+constraints, compliance evidence, and operational ownership. These influence
+architecture early and should not wait for =security-check=.
+
+*** TODO [#A] =arch-design=: separate architecture paradigms from tactical patterns
+
+The candidate table mixes paradigms (modular monolith, microservices,
+event-driven) with tactical or partial patterns (DDD, CQRS, event sourcing).
+Revise the matrix so candidates can compose patterns rather than treating each
+as a mutually exclusive architecture choice.
+
+*** TODO [#A] =arch-document=: strengthen quality scenarios using arc42/Q42 structure
+
+Section 10 currently says "Under [condition], the system should [response]
+within [measure]." Expand to a compact quality-scenario template: source,
+stimulus, environment, artifact, response, response measure. This better
+matches architecture-quality practice and makes requirements testable.
+
+*** TODO [#A] =arch-document=: add staleness and ownership metadata to generated docs
+
+arc42 docs are living documents. Add owner, source commit/date, review cadence,
+and "known stale when..." notes per section or in the README so generated docs
+do not become authoritative after the code has moved on.
+
+*** TODO [#A] =arch-evaluate=: add confidence levels for framework-agnostic findings
+
+Claude-read import graphs and public API comparisons can be incomplete in large
+or dynamic languages. Add confidence/provenance per finding and require "not
+fully checked because..." when scale or dynamic imports limit certainty.
+
+*** TODO [#A] =arch-evaluate=: report skipped tool checks explicitly
+
+The workflow says skip unconfigured language-specific tools silently, but the
+review checklist also wants checks run. For audit usefulness, list detected
+languages and "tool not configured" entries under Info instead of silent skips.
+
+*** TODO [#A] =c4-analyze= and =c4-diagram=: add notation/output fallback instead of draw.io-only
+
+C4 is notation-independent. These skills hard-require draw.io XML, PNG export,
+and opening draw.io desktop. Add supported outputs (Structurizr DSL, Mermaid,
+PlantUML, draw.io) and a fallback path when =drawio= or a GUI is unavailable.
+
+*** TODO [#A] =c4-analyze= and =c4-diagram=: clarify C4 abstraction boundaries
+
+Emphasize that C4 Containers are deployable/runnable units, not necessarily
+Docker containers, and that Components are not separately deployable. Add a
+check that every relationship and element stays at one abstraction level.
+
+*** TODO [#A] =commits.md=: split DeepSat/Linear/Slack-specific publishing rules from global commit rules
+
+The global commit rule file includes Linear status transitions and a hard-coded
+Slack channel. That is team-specific and may leak or misfire in unrelated
+projects. Move those steps to a project/team overlay, leaving global rules for
+author identity, attribution, commit format, review gate, and verification.
+
+*** TODO [#A] =commits.md= and publish flows: define fallback when =humanizer= is unavailable
+
+Several workflows make =humanizer= mandatory, but no =humanizer= skill exists
+in this repo. Either add the skill, install instructions, or a fallback
+plain-English pass that satisfies the same checks without an external skill.
+
+*** TODO [#A] =verification.md=: add explicit "unable to verify" reporting standard
+
+The rule says run tests/lint/typecheck/build before claiming done. Add the
+required final wording when a command cannot be run: command attempted, reason
+it could not run, risk left unverified, and the smallest next command for the
+user to run.
+
+*** TODO [#A] =testing.md=: add property-based and mutation testing as escalation paths
+
+The testing rules cover categories and pairwise matrices. Add guidance for
+property-based testing when invariants matter across broad input domains, and
+mutation testing when test quality is suspect despite high coverage.
+
+*** TODO [#A] =testing.md=: soften absolute TDD with an explicit spike protocol
+
+The rule currently treats TDD as non-negotiable. Keep TDD as the default, but
+define a disciplined spike exception: timebox, do not commit spike code, write
+the first failing test before productionizing the discovered approach.
+
+*** TODO [#A] =subagents.md=: add capability/availability and cost checks
+
+The rule assumes subagents exist and should handle failures. Add "if the
+environment lacks subagents, continue locally and preserve the same scope
+boundaries" plus a cost check for tasks where context handoff exceeds the work.
+
+*** TODO [#A] =languages/python/claude/rules/python-testing.md=: revisit in-memory SQLite guidance
+
+"Prefer in-memory SQLite for speed in unit tests" is risky for Django or
+SQLAlchemy projects whose production database is PostgreSQL/MySQL; query
+semantics, constraints, transactions, JSON, time zones, and indexes differ.
+Recommend production-like DBs for ORM/query behavior and reserve SQLite for
+pure unit tests that do not depend on database semantics.
+
+*** TODO [#A] =languages/python/claude/rules/python-testing.md=: separate "never mock ORM" from true unit-test boundaries
+
+For domain services, real model methods and validation are usually right. For
+thin orchestration units, a repository/interface fake may be cleaner than
+hitting a real database. Clarify the boundary: do not mock ORM internals, but
+do inject fakes at deliberate data-access ports.
+
+*** TODO [#A] =languages/elisp/claude/rules/elisp.md=: update editing workflow to avoid tool-specific advice
+
+The rule says prefer Write over repeated Edits. That advice is Claude-tooling
+specific and can conflict with environments that require patch-based edits.
+Rephrase around the intent: for nontrivial Elisp, make cohesive edits and run
+paren/byte-compile checks immediately.
+
+*** TODO [#A] =languages/elisp/claude/rules/elisp-testing.md=: add batch-mode and native-comp caveats
+
+ERT guidance is solid, but add rules for =emacs --batch= reproducibility,
+isolating =user-emacs-directory= / package state, and optionally catching
+native-comp or byte-compile warnings depending on the project's Emacs version.
+
+*** TODO [#A] =hooks/README.md=: include =destructive-bash-confirm.py= in install/settings snippets
+
+The table documents the destructive-command hook, but the manual install and
+settings JSON snippets only include the commit and PR hooks. Add the destructive
+hook to both snippets so documented installation matches the listed hooks.
+
+*** TODO [#A] =hooks/git-commit-confirm.py= and =hooks/gh-pr-create-confirm.py=: inspect message/body files
+
+=commits.md= uses =git commit -F /tmp/commit-*.md= and =gh pr create
+--body-file ...=. The hooks currently treat file-backed messages as
+unparseable or just display the file path, so attribution scanning may miss the
+actual committed/posted text. Read safe local files referenced by =-F=,
+=--file=, and =--body-file= before deciding whether the command is clean.
+
+*** TODO [#A] =hooks/destructive-bash-confirm.py=: replace regex command parsing with shell-aware parsing where possible
+
+The hook's regexes can miss quoted paths, variables, aliases, =env= wrappers,
+or compound commands, and can misidentify targets. Use =shlex= for simple
+commands, document unsupported shell constructs, and fail toward asking when a
+destructive pattern is ambiguous.
+
+** TODO [#B] Build =ov-1= skill for DoDAF OV-1 (High-Level Operational Concept Graphic)
+
+Triggered by SOFWeek (May 2026, Tampa) — DeepSat attending; DoD attendees
+may ask for architecture diagrams. OV-1 is the universal informal
+currency in DoD briefings ("show me the architecture" → OV-1 by default).
+
+Priority upgrades to =[#A]= if Craig confirms scenario 2 below (personal
+load-bearing need at the event); stays =[#B]= or drops to =[#C]= if
+scenario 1 (team already covers it, future asset only).
+
+*** Prior art (searched 2026-04-19)
+
+No existing Claude Code skill exists for DoDAF / OV-1 / SV-1 / SysML.
+
+- =anthropics/skills= — 17 skills, zero DoDAF/SysML/defense coverage.
+- =awesome-claude-code= list — zero hits for DoDAF/OV-1/SysML/UAF.
+- =mfsgr/sysml2dodaf= — empty repo (0 stars, no code). Vapor.
+- =HowardKao-1130/mini-NEXEN= — broad SE methodology skill that
+ name-drops DoDAF as a trigger keyword; no artifact generation. 0 stars.
+- =gaphor/gaphor= (Apache-2.0, 2.2k stars) — mature UML/SysML GUI
+ modeler. Not a skill; not a pipeline. Useful reference only.
+
+Nearest prior art to lean on when building:
+- DoDAF 2.02 Viewpoints & Models reference (dodcio.defense.gov) —
+ canonical OV-1 exemplars. Embed 3-5 layouts as skill =references/=.
+- Pattern from existing =c4-diagram= skill — same shape (prose → diagram
+ spec), swap the viewpoint vocabulary to DoDAF.
+- PlantUML for SV-1 (when that skill comes later); Mermaid or draw.io
+ XML for OV-1 lightweight visuals.
+
+*** Build scope (when triggered)
+
+*In scope:*
+- Input: prose description of a system + its operational context.
+- Output: structured OV-1 *spec* — performers, external actors (other
+ systems, forces, adversaries), relationships (data/control flows),
+ narrative captions, classification marking, legend requirements.
+- DoDAF 2.02 completeness checklist as a quality gate — verify the
+ produced spec contains every element a correct OV-1 requires.
+- Optional lightweight visual: draw.io XML or Mermaid approximation for
+ quick review; NOT a finished rendering.
+
+*Out of scope:*
+- Icon libraries, pictorial assets, finished PowerPoint export. OV-1
+ final art belongs to a designer or Craig in Visio/PowerPoint; the
+ skill's job is the spec and the check, not the slide.
+- SV-1, SV-2, UAF, IDEF1X, other viewpoints. Build only when a
+ concrete need triggers each.
+
+Estimate: 4-6 hours.
+
+*** Craig's investigation before kickoff
+
+1. Does DeepSat's systems-engineering or marketing team already have an
+ OV-1 (or the equivalent briefing artifact) for SOFWeek?
+2. If yes (scenario 1) — skill is a future asset, not event-load-bearing.
+ Ship after SOFWeek. Priority drops to =[#C]=.
+3. If no, or if the scenario is "Craig may need to produce/iterate an
+ OV-1 on the fly during the event" (scenario 2) — skill is load-bearing
+ for the event. Priority upgrades to =[#A]=; build before SOFWeek.
+4. Confirm the classification level the skill needs to handle
+ (unclassified-only? or FOUO markings? affects the classification
+ block in the spec).
+5. Confirm the target rendering format DeepSat uses for OV-1
+ deliverables (PowerPoint slide? Cameo? Visio? affects whether the
+ skill emits draw.io XML vs Mermaid vs pure structured spec).
+
+*** Related
+
+See also the DoD-specific notations section under the later TODO
+(=c4-*= rename revisit) — OV-1 is flagged there as the highest-value
+starting point across the DoD notation landscape (SysML, DoDAF/UAF,
+IDEF1X). This entry is the execution plan for that starting point.
+
+** TODO [#A] Build =/lint-org= skill + wrap-up integration
+
+Spec: [[file:.ai/specs/lint-org-skill-spec.md]]
+
+A two-mode skill (=interactive=, =mechanical-only=) that runs =org-lint=,
+auto-fixes safe categories (item-number, missing-language-in-src-block,
+misplaced-planning-info, markdown-bold → single-asterisk), and walks judgment
+items (broken local-file links, invalid fuzzy links, verbatim-asterisk false
+positives, suspicious-language blocks) inline.
+
+Wrap-up integration: =wrap-it-up.org= invokes
+=/lint-org todo.org --mode=mechanical-only= after the existing
+=todo-cleanup.el --archive-done= pass. Judgment items defer to a
+carry-forward file that the next morning's daily-prep merges in, so
+wrap-up never blocks on a judgment call.
+
+Baseline that motivated this: the 2026-05-14 manual pass took =todo.org=
+from 55 → 1 lint warnings across two commits (=0d10458= signal,
+=9ad5b30= cosmetic). A nightly mechanical sweep keeps the count near
+zero forever — each day's drift is small.
+
+** TODO [#A] Build =/update-skills= skill for keeping forks in sync with upstream
+
+The rulesets repo has a growing set of forks (=arch-decide= from
+wshobson/agents, =playwright-js= from lackeyjb/playwright-skill, =playwright-py=
+from anthropics/skills/webapp-testing). Over time, upstream releases fixes,
+new templates, or scope expansions that we'd want to pull in without losing
+our local modifications. A skill should handle this deliberately rather than
+by manual re-cloning.
+
+*** Design decisions (agreed)
+
+- *Upstream tracking:* per-fork manifest =.skill-upstream= (YAML or JSON):
+ - =url= (GitHub URL)
+ - =ref= (branch or tag)
+ - =subpath= (path inside the upstream repo when it's a monorepo)
+ - =last_synced_commit= (updated on successful sync)
+- *Local modifications:* 3-way merge. Requires a pristine baseline snapshot of
+ the upstream-at-time-of-fork. Store under =.skill-upstream/baseline/= or
+ similar; committed to the rulesets repo so the merge base is reproducible.
+- *Apply changes:* skill edits files directly with per-file confirmation.
+- *Conflict policy:* per-hunk prompt inside the skill. When a 3-way merge
+ produces a conflict, the skill walks each conflicting hunk and asks Craig:
+ keep-local / take-upstream / both / skip. Editor-independent; works on
+ machines where Emacs isn't available. Fallback when baseline is missing
+ or corrupt (can't run 3-way merge): write =.local=, =.upstream=,
+ =.baseline= files side-by-side and surface as manual review.
+
+*** V1 Scope
+
+- [ ] Skill at =~/code/rulesets/update-skills/=
+- [ ] Discovery: scan sibling skill dirs for =.skill-upstream= manifests
+- [ ] Helper script (bash or python) to:
+ - Clone each upstream at =ref= shallowly into =/tmp/=
+ - Compare current skill state vs latest upstream vs stored baseline
+ - Classify each file: =unchanged= / =upstream-only= / =local-only= / =both-changed=
+ - For =both-changed=: run =git merge-file --stdout <local> <baseline> <upstream>=;
+ if clean, write result directly; if conflicts, parse the conflict-marker
+ output and feed each hunk into the per-hunk prompt loop
+- [ ] Per-hunk prompt loop:
+ - Show base / local / upstream side-by-side for each conflicting hunk
+ - Ask: keep-local / take-upstream / both (concatenate) / skip (leave marker)
+ - Assemble resolved hunks into the final file content
+- [ ] Per-fork summary output with file-level classification table
+- [ ] Per-file confirmation flow (yes / no / show-diff) BEFORE per-hunk loop
+- [ ] On successful sync: update =last_synced_commit= in the manifest
+- [ ] =--dry-run= to preview without writing
+
+*** V2+ (deferred)
+
+- [ ] Track upstream *releases* (tags) not just branches, so skill can propose
+ "upgrade from v1.2 to v1.3" with release notes pulled in
+- [ ] Generate patch files as an alternative apply method (for users who prefer
+ =git apply= / =patch= over in-place edits)
+- [ ] Non-interactive mode (=--non-interactive= / CI): skip conflict resolution,
+ emit side-by-side files for later manual review
+- [ ] Auto-run on a schedule via Claude Code background agent
+- [ ] Summary of aggregate upstream activity across all forks (which forks have
+ upstream changes waiting, which don't)
+- [ ] Optional editor integration: on machines with Emacs, offer
+ =M-x smerge-ediff= as an alternate path for users who prefer ediff over
+ per-hunk prompts
+
+*** Initial forks to enumerate (for manifest bootstrap)
+
+- [ ] =arch-decide= → =wshobson/agents= :: =plugins/documentation-generation/skills/architecture-decision-records= :: MIT
+- [ ] =playwright-js= → =lackeyjb/playwright-skill= :: =skills/playwright-skill= :: MIT
+- [ ] =playwright-py= → =anthropics/skills= :: =skills/webapp-testing= :: Apache-2.0
+
+*** Open questions
+
+- [ ] What happens when upstream *renames* a file we fork? Skill would see
+ "file gone from upstream, still present locally" — drop, keep, or prompt?
+- [ ] What happens when upstream splits into multiple forks (e.g., a plugin
+ reshuffles its structure)? Probably out of scope for v1; manual migration.
+- [ ] Rate-limit / offline mode: if GitHub is unreachable, should skill fail
+ or degrade gracefully? Likely degrade; print warning per fork.
+
+** TODO [#B] Build /research-writer — clean-room synthesis for research-backed long-form
+SCHEDULED: <2026-05-15 Fri>
+
+Gap in current rulesets: between =brainstorm= (idea refinement → design doc)
+and =arch-document= (arc42 technical docs), there's no skill for
+research-backed long-form prose — blog posts, essays, white papers,
+proposals with data backing, article-length content with citations.
+
+Craig writes documents across many contexts (defense-contractor work,
+personal, technical, proposals). The gap is real.
+
+*Evaluated 2026-04-19:* ComposioHQ/awesome-claude-skills has a
+=content-research-writer= skill (540 lines, 14 KB) that attempts this. *Not
+adopting:*
+- Parent repo has no LICENSE file — reuse legally ambiguous
+- Bloated: 540 lines of prose-scaffolding with no tooling
+- No citation-style enforcement (APA/Chicago/IEEE/MLA)
+- No source-quality heuristics (primary vs secondary, peer-review, recency)
+- Fictional example citations in the skill itself (models the hallucination
+ failure mode a citation-focused skill should prevent)
+- No citation-verification step
+- Overlaps with =humanizer= at polish with no composition guidance
+
+*Patterns worth lifting clean-room (from their better parts):*
+- Folder convention =~/writing/<article-name>/= with =outline.md=,
+ =research.md=, versioned drafts, =sources/=
+- Section-by-section feedback loop (outline validated → per-section
+ research validated → per-section draft validated)
+- Hook alternatives pattern (generate three hook variants with rationale)
+
+*Additions for the clean-room version (v1):*
+- Citation-style selection (APA / Chicago / MLA / IEEE / custom) with
+ style-specific examples and a pick-one step up front
+- Source-quality heuristics: primary > secondary; peer-reviewed; recency
+ thresholds by domain; publisher reputation; funding transparency
+- Citation-verification discipline: fetch real sources, never fabricate,
+ mark unverifiable claims with =[citation needed]= rather than inventing
+- Composition hand-off to =/humanizer= at the polish stage
+- Classification awareness: if the working directory or context signals
+ defense / regulated territory, flag any sentence that might touch CUI
+ or classified material before emission
+
+*Target:* ~150-200 lines, clean-room per blanket policy.
+
+*When to build:* wait for a real research-writing task to validate the
+design against actual document patterns. Building preemptively risks
+tuning for my guess at Craig's workflow rather than his real one.
+Triggers that would prompt "let's build it now":
+- Starting a white paper / proposal that needs citation discipline
+- Writing a technical blog post with external references
+- A pattern of hitting the same research-writing friction 3+ times
+
+Upstream reference (do not vendor): ComposioHQ/awesome-claude-skills
+=content-research-writer/SKILL.md=.
+
+** TODO [#C] Try Skill Seekers on a real DeepSat docs-briefing need
+SCHEDULED: <2026-05-15 Fri>
+
+=Skill Seekers= ([[https://github.com/yusufkaraaslan/Skill_Seekers]]) is a Python
+CLI + MCP server that ingests 18 source types (docs sites, PDFs, GitHub
+repos, YouTube videos, Confluence, Notion, OpenAPI specs, etc.) and
+exports to 20+ AI targets including Claude skills. MIT licensed, 12.9k
+stars, active as of 2026-04-12.
+
+*Evaluated: 2026-04-19 — not adopted for rulesets.* Generates
+*reference-style* skills (encyclopedic dumps of scraped source material),
+not *operational* skills (opinionated how-we-do-things content). Doesn't
+fit the rulesets curation pattern.
+
+*Next-trigger experiment (this TODO):* the next time a DeepSat task needs
+Claude briefed deeply on a specific library, API, or docs site — try:
+#+begin_src bash
+pip install skill-seekers
+skill-seekers create <url> --target claude
+#+end_src
+Measure output quality vs hand-curated briefing. If usable, consider
+installing as a persistent tool. If output is bloated / under-structured,
+discard and stick with hand briefing.
+
+*Candidate first experiments (pick one from an actual need, don't invent):*
+- A Django ORM reference skill scoped to the version DeepSat pins
+- An OpenAPI-to-skill conversion for a partner-vendor API
+- A React hooks reference skill for the frontend team's current patterns
+- A specific AWS service's docs (e.g. GovCloud-flavored)
+
+*Patterns worth borrowing into rulesets even without adopting the tool:*
+- Enhancement-via-agent pipeline (scrape raw → LLM pass → structured
+ SKILL.md). Applicable if we ever build internal-docs-to-skill tooling.
+- Multi-target export abstraction (one knowledge extraction → many output
+ formats). Clean design for any future multi-AI-tool workflow.
+
+*Concerns to verify on actual use:*
+- =LICENSE= has an unfilled =[Your Name/Username]= placeholder (MIT is
+ unambiguous, but sloppy for a 12k-star project)
+- Default branch is =development=, not =main= — pin with care
+- Heavy commercialization signals (website at skillseekersweb.com,
+ Trendshift promo, branded badges) — license might shift later; watch
+- Companion =skill-seekers-configs= community repo has only 8 stars
+ despite main's 12.9k — ecosystem thinner than headline adoption
+
+** TODO [#C] Revisit =c4-*= rename if a second notation skill ships
+
+Current naming keeps =c4-analyze= and =c4-diagram= as-is (framework prefix
+encodes the notation; "C4" is a discoverable brand). Suite membership is
+surfaced via the description footer, not the name.
+
+If a second notation-specific skill ever lands (=uml-*=, =erd-*=, =arc42-*=),
+the compound pattern =arch-analyze-<notation>= / =arch-diagram-<notation>=
+starts paying off: alphabetical clustering under 'a' amortizes across three+
+skills, and the hierarchy becomes regular. At that point, rename all
+notation skills together in one pass.
+
+Trigger: adding skill #2 in the notation family. Don't pre-rename.
+
+Candidate future notation skills (not yet in scope — noted for when a
+real need arrives, not pre-emptively):
+
+- *UML* (Unified Modeling Language): OO design notation, 14 diagram types
+ in practice dominated by class / sequence / state / component. Common
+ in DoD / safety-critical / enterprise-architecture contexts. Tooling:
+ PlantUML (text-to-diagram), Mermaid UML, draw.io. Would likely split
+ into =uml-class=, =uml-sequence=, =uml-state= rather than one monolith
+ — different audiences, different inputs.
+- *ERD* (Entity-Relationship Diagram): database schema modeling —
+ entities, attributes, cardinality. Crow's Foot notation dominates
+ practice; Chen is academic; IDEF1X is DoD-standard. Tooling:
+ dbdiagram.io, Mermaid ERD, PlantUML, ERAlchemy (code-to-ERD for SQL).
+ Natural fit as =erd-analyze= (extract from schema/migrations) and
+ =erd-diagram= (generate from prose/model definitions).
+- *arc42*: already partially covered by =arch-document= (which emits
+ arc42-structured docs). A standalone =arc42-*= skill would be
+ redundant unless the arc42-specific visualizations need separation.
+
+Each answers a different question:
+
+- C4 → "What systems exist and how do they talk, at what zoom?"
+- UML class/sequence → "What does the code look like / what happens when X runs?"
+- ERD → "What's the database shape?"
+- arc42 → "What's the full architecture document?"
+
+Deferred pending an actual need that's blocked on not having one of these.
+
+*** DoD-specific notations (DeepSat context)
+
+Defense-contractor work uses a narrower, different notation set than
+commercial software. Document the trigger conditions and starting point
+so a future decision to build doesn't have to re-derive the landscape.
+
+**** SysML (Systems Modeling Language)
+
+UML 2 profile, dominant in DoD systems engineering. Six diagrams account
+for ~all practical use:
+
+- *Block Definition Diagram (BDD)* — structural; like UML class but for
+ system blocks (components, subsystems, hardware).
+- *Internal Block Diagram (IBD)* — parts within a block and how they
+ connect (flow ports, interfaces).
+- *Requirement diagram* — unique to SysML; traces requirements to
+ satisfying blocks. Essential in regulated environments.
+- *Activity diagram* — behavioral flow.
+- *State machine* — same shape as UML.
+- *Sequence diagram* — same shape as UML.
+
+SysML v1.x is in the field; v2 is emerging but not yet adopted at scale
+(as of 2026-04). Tooling dominated by Cameo Systems Modeler / MagicDraw
+and Enterprise Architect. Text-based option: PlantUML + =plantuml-sysml=
+(git-friendly, growing niche).
+
+*Candidate skills*: =sysml-bdd=, =sysml-ibd=, =sysml-requirement=,
+=sysml-sequence=. Three or more in this cluster triggers the
+=arch-*-<notation>= rename discussion from the parent entry.
+
+**** DoDAF / UAF (architecture frameworks)
+
+Not notations themselves — frameworks that specify *which* viewpoints a
+program must deliver. Viewpoints are rendered using UML/SysML diagrams.
+
+- *DoDAF (DoD Architecture Framework)* — legacy but still
+ contract-required on many programs.
+- *UAF (Unified Architecture Framework)* — DoDAF/MODAF successor,
+ SysML-based. Gaining adoption on newer contracts.
+
+Common required viewpoints (formal CDRL deliverables or PDR/CDR
+review packages):
+
+- *OV-1* — High-Level Operational Concept Graphic. The "cartoon" showing
+ the system in operational context with icons, arrows, surrounding
+ actors/environment. *Universally asked for — informal or formal.*
+ Starting point for any DoD diagram skill.
+- *OV-2* — Operational resource flows (nodes and flows).
+- *OV-5a/b* — Operational activities.
+- *SV-1* — Systems interfaces. Maps closely to C4 Container.
+- *SV-2* — Systems resource flows.
+- *SV-4* — Systems functionality.
+- *SV-10b* — Systems state transitions.
+
+*Informal ask ("send me an architecture diagram") → OV-1 + SV-1 satisfies
+90% of the time.* Formal CDRL asks specify the viewpoint set contractually.
+
+*C4 gap*: C4 is rare in DoD. C4 System Context ≈ OV-1 in intent but not
+in visual convention. C4 Container ≈ SV-1. Expect a mapping step or
+reviewer pushback if delivering C4-shaped artifacts to a DoD audience.
+
+*Candidate skills*: =dodaf-ov1=, =dodaf-sv1= first (highest-value);
+=uaf-viewpoint= if newer contracts require UAF.
+
+**** IDEF1X (data modeling)
+
+FIPS 184 — federal standard for data modeling. Used in classified DoD
+data systems, intelligence databases, and anywhere the government
+specifies the data model. Same shape language as Crow's Foot but with
+different adornments and notation conventions.
+
+*Rule of thumb*: classified DoD data work → IDEF1X; unclassified
+contractor work → Crow's Foot unless the contract specifies otherwise.
+
+*Candidate skills*: =idef1x-diagram= / =idef1x-analyze= (parallel to a
+future =erd-diagram= / =erd-analyze= pair).
+
+**** Tooling baseline
+
+- *Cameo Systems Modeler / MagicDraw* (Dassault) — commercial SysML
+ dominant in DoD programs.
+- *Enterprise Architect (Sparx)* — widely used for UML + SysML + DoDAF.
+- *Rhapsody (IBM)* — SysML with code generation; strong in avionics /
+ embedded (FACE, ARINC).
+- *Papyrus (Eclipse)* — open source SysML; free but clunkier.
+- *PlantUML + plantuml-sysml* — text-based, version-controllable. Fits a
+ git-centric workflow better than any GUI tool.
+
+**** Highest-value starting point
+
+If DeepSat contracts regularly require architecture deliverables, the
+highest-ROI first skill is =dodaf-ov1= (or whatever naming convention
+the rename discussion lands on). OV-1 is the universal currency in
+briefings, proposals, and reviews; it's the one artifact that shows up
+in every program regardless of contract specifics.
+
+Trigger for building: an actual DoD deliverable that's blocked on not
+having a skill to generate or check OV-1-shaped artifacts. Don't build
+speculatively — defense-specific notations are narrow enough that each
+skill should be driven by a concrete contract need, not aspiration.
+
+** TODO [#B] Add =make remove= for interactive ruleset removal via fzf
+
+Add a Makefile target that lists every currently-installed ruleset entry
+and lets me pick one or more to remove via fzf. Granular alternative to
+=make uninstall= (removes everything) and =make uninstall-hooks= (removes
+only hooks).
+
+*** Why this matters
+
+Tearing down a single skill, rule, hook, or config file currently means
+either running =make uninstall= and re-installing what I want to keep,
+or =rm=ing the symlink directly and remembering the exact path. Both are
+friction. An interactive picker lets me filter, multi-select with Tab,
+and confirm with Enter — the typical fzf flow. Costs about 3-5 seconds
+per teardown instead of 15+ seconds of "what's the exact name?".
+
+*** Design
+
+The recipe builds a tab-separated list of every currently-installed item,
+categorized by type, and pipes it to =fzf --multi=. The user filters,
+marks with Tab, and confirms with Enter. The recipe parses the selections
+and =rm=s the matching symlinks.
+
+#+begin_example
+ skill debug
+ rule commits.md
+ hook destructive-bash-confirm.py
+ config settings.json
+ commands commands
+ bridge claude-rules
+#+end_example
+
+Each line is =<kind>\t<name>=. The recipe maps =<kind>= to the right path:
+
+- =skill= → =$(SKILLS_DIR)/<name>=
+- =rule= → =$(RULES_DIR)/<name>=
+- =hook= → =$(HOOKS_DIR)/<name>=
+- =config= → =$(CLAUDE_DIR)/<name>=
+- =commands= → =$(CLAUDE_DIR)/commands=
+- =bridge= → =$(SKILLS_DIR)/claude-rules=
+
+Source files in =rulesets/= stay untouched. =make install= re-creates the
+removed links if needed (the install loop is idempotent).
+
+*** Edge cases
+
+- Esc instead of Enter → empty selection → clean exit, no removal.
+- Filter to nothing then Enter → same as Esc.
+- Selected item already gone → =rm= fails visibly, processing continues
+ on the rest.
+- =fzf= not installed → fail fast with a clear error (matches the pattern
+ used by =install-lang=).
+
+*** Possible extensions
+
+- Parallel =make pick-install= target that lists not-yet-installed items
+ and installs the chosen ones. Symmetric UX, same fzf flow.
+- Confirmation prompt when more than N items selected (defense against
+ accidental select-all).
+- =--source= flag that also runs =git rm= against the rulesets source for
+ the selected item. Probably bad idea — too easy to lose work.
+- The =bridge → $(SKILLS_DIR)/claude-rules= entry above is stale — the
+ bridge symlink got removed in a later commit. Drop that bullet when the
+ recipe lands.
+
+** TODO [#B] Document the =mcp/= install pipeline in =mcp/README.org=
+
+=mcp/= has =install.py=, =servers.json=, =secrets.env.gpg=, =gcp-oauth.keys.json= (gitignored, regenerated at install). No README. Coming back to this in three months I'll re-discover how the bundle is structured, what =install.py= does, and how to rotate tokens. Saving that re-discovery is the whole point.
+
+*** What to cover
+
+- Layout: what each file is, which are tracked vs gitignored.
+- Secrets bundle shape: how vars are listed in =secrets.env=, the symmetric-encryption pattern (=gpg -c --cipher-algo AES256=), the base64-bundled OAuth artifacts (=GCP_OAUTH_KEYS_JSON_B64=, =GOOGLE_DOCS_PERSONAL_TOKEN_B64=, =GOOGLE_DOCS_WORK_TOKEN_B64=).
+- Install flow: =make install-mcp= → =install.py= decrypts, writes the keys file and Google Docs token caches at mode 600, expands =${VAR}= in =servers.json=, calls =claude mcp add --scope user= for unregistered servers. Idempotent.
+- Token rotation: when a refresh token gets revoked, the recovery flow (re-auth on one machine, re-bundle, recommit).
+- Adding a new server: edit =servers.json=, add any new =${VAR}= placeholders to the bundle, re-encrypt.
+- The OAuth dance for HTTP-transport servers (linear, notion) versus stdio (google-docs-*) — different paths, different gotchas.
+
+** TODO [#C] Add =make uninstall-mcp= + =mcp/install.py --check= for symmetry
+
+Currently the MCP install pipeline only flows one direction. No way to remove rulesets-managed MCP servers in one command. No way to ask "what's the drift between =servers.json= and =claude mcp list=" without eyeballing.
+
+*** =make uninstall-mcp=
+
+Iterate over =servers.json=, run =claude mcp remove <name> -s user= for each. Ignore "not registered" errors. Idempotent.
+
+*** =mcp/install.py --check=
+
+Dry-run mode. Decrypt secrets, but instead of registering, print the drift report:
+
+- Servers in =servers.json= not in =claude mcp list= → =MISSING=
+- Servers in =claude mcp list= not in =servers.json= → =EXTRA=
+- Servers in both → =ok=
+
+Useful for diagnosing connection failures and for the eventual =make doctor= integration.
+
+** TODO [#C] Update =README.org= with MCP install pipeline section
+
+=README.org= covers global install, per-project language bundles, and design principles, but doesn't mention =make install-mcp= or the =mcp/= directory. Add a short section after "Per-project language bundles" describing the user-scope MCP install pattern (decrypt → expand → register) and pointing at the eventual =mcp/README.org=.
+
+** TODO [#C] Token-rotation helper for =@a-bonus/google-docs-mcp= OAuth refresh
+
+When a Google refresh token gets revoked (re-grant scopes, removed Connected App, account password reset), recovery is currently manual: run =npx -y @a-bonus/google-docs-mcp= with the right env, follow the URL in a browser, kill the process, base64-encode the new =token.json=, decrypt =secrets.env.gpg=, replace the var, re-encrypt. A small =mcp/refresh-google-docs-token.sh <profile>= would chain that into one command.
+
+*** Sketch
+
+#+begin_src bash
+# usage: mcp/refresh-google-docs-token.sh personal
+profile="$1"
+gpg -d ... | grep -v "GOOGLE_DOCS_${profile^^}_TOKEN_B64" > /tmp/secrets.env.tmp
+GOOGLE_MCP_PROFILE="$profile" npx -y @a-bonus/google-docs-mcp &
+xdg-open <captured-url>
+# wait for ~/.config/google-docs-mcp/$profile/token.json to land
+kill %1
+echo "GOOGLE_DOCS_${profile^^}_TOKEN_B64=$(base64 -w0 ~/.config/google-docs-mcp/$profile/token.json)" >> /tmp/secrets.env.tmp
+gpg -c --cipher-algo AES256 -o mcp/secrets.env.gpg.new /tmp/secrets.env.tmp
+mv mcp/secrets.env.gpg.new mcp/secrets.env.gpg
+rm /tmp/secrets.env.tmp
+#+end_src
+
+The flow tonight worked but took a handful of manual steps. One script collapses it.
+
+** TODO [#C] Decide on category-3 rule copies in the deepsat tree
+
+While symlinking personal-project =.claude/rules/= mirrors to the rulesets canonical on 2026-05-07, two locations didn't fit the "personal mirror → symlink" pattern and were left untouched pending judgment:
+
+- =~/projects/work/deepsat/code/coding-rulesets/claude-rules/{testing,verification}.md= — looks like a vendored team-shared copy.
+- =~/projects/work/deepsat/code/orchestration_dashboard_mvp/.claude/rules/{testing,verification}.md= — could be project-specific overrides.
+
+For each: read the file, diff against the rulesets canonical, decide whether it's an intentional diverge (leave alone), stale (sync content), or should canonicalize (replace with symlink and accept the cross-repo dependency). The orchestration_dashboard_mvp pair is the project where Vrezh's PR review surfaced this whole thread, so any decision there has team-visibility implications.
+
+** TODO [#C] Audit language-specific rule files for cross-project duplication
+
+The four canonical rules (=commits=, =testing=, =verification=, =subagents=) are now symlinked across the five personal-project mirrors as of 2026-05-07. But several language-specific rule files exist in multiple project mirrors and may be duplicated or drifted:
+
+- =python-testing.md= in =~/projects/work/.claude/rules/=
+- =typescript-testing.md= in =~/projects/work/deepsat/code/.claude/rules/=
+- =elisp-testing.md= and =elisp.md= in =~/.emacs.d/=, =~/code/gloss/=, =~/code/chime/=
+
+The Elisp pair is the most suspicious — three repos using essentially the same rules. Audit: diff these across the projects, check for drift, then decide whether to canonicalize them under =~/code/rulesets/claude-rules/languages/<lang>/= and symlink, or leave them as project-local.
+
+** DOING [#A] Consolidate =.ai/= template infrastructure (fold + audit + install-ai + ratio) :feature:
+
+End-state: one repo (=rulesets=) is the single source of truth for =.ai/= template content. =make audit= verifies and applies drift across every =.ai/=-using project on the machine. =make install-ai= bootstraps new projects. Same setup propagated to ratio so both machines run the same way.
+
+Today (2026-05-15) the canonical-source rule got violated again: rulesets commit =372fb76= added a wrap-up subsection to =rulesets= without going through =claude-templates= first, and the next session's startup rsync was about to silently undo it. Two-repo coordination is the root cause; fold solves it.
+
+Build order: fold first (others depend on the new canonical path), then audit + install-ai in parallel, then test, then propagate to ratio.
+
+*** TODO [#A] Fold =claude-templates= into rulesets
+
+Two repos, one source of truth. =~/projects/claude-templates/= is the canonical =.ai/= template that gets rsync'd into every project at session start. Keeping it standalone means a second =git pull= in startup Phase A.0, a second remote to push to at wrap-up, and a split history any time a change touches both. Folding it into =rulesets/claude-templates/= gives one repo to clone on a fresh machine and one place to edit templates.
+
+**** Open design choices
+
+- *History.* =git subtree add --prefix=claude-templates ~/projects/claude-templates main= preserves the 84-commit history under the new prefix. Plain content copy (=cp -a= + =git add=) is simpler but loses history. Either is fine since the standalone repo stays archived on =cjennings.net=.
+- *Layout.* =rulesets/claude-templates/= mirrors the old repo name and sits next to =claude-rules/= cleanly. Alternative: absorb =.ai/= directly under a different name (=rulesets/.ai-template/= or similar). First option is clearer.
+- *bin/ai.* The standalone Makefile symlinks =$HOME/.local/bin/ai → bin/ai=. After the move, fold that into rulesets' Makefile as another install target.
+
+**** Mechanical steps
+
+1. Subtree-merge or copy =~/projects/claude-templates/= into =rulesets/claude-templates/=.
+2. Update 3 references in rulesets:
+ - =.ai/protocols.org= line 163 — pointer in the "Let's run/do the X workflow" section.
+ - =.ai/workflows/cross-agent-comms.org= line 8 — promotion-target path.
+ - =.ai/workflows/startup.org= lines 22, 96-98 — Phase A.0 pull + Phase A rsync sources.
+3. Update Phase A.0 of =startup.org= to pull rulesets instead of claude-templates. Inside rulesets sessions, the existing project-repo pull already covers it. Outside rulesets (every other project's session), Phase A.0 needs an explicit =git pull= on =~/code/rulesets/= before the rsync — otherwise the templates will be stale.
+4. Replace =~/projects/claude-templates/= with a symlink to =~/code/rulesets/claude-templates/= for transition continuity.
+5. After every active project has had one session start (and rsync'd the new =startup.org=), drop the symlink and archive =cjennings.net:git/claude-templates.git=.
+
+**** Bootstrap gap
+
+Every project on the machine has a =.ai/workflows/startup.org= that rsyncs from =~/projects/claude-templates/=. Until each project's startup.org gets refreshed (which happens via the rsync itself), the old path needs to keep resolving. The symlink at step 4 is the bridge: old paths resolve into the new location, the rsync delivers the updated startup.org, next session uses the new path directly.
+
+*** TODO [#A] Add =make audit= — drift detector across all =.ai/=-using projects
+
+Companion to =make doctor= (single-machine scope, checks =~/.claude/=). =audit= is cross-project scope: walks every directory on the machine that has a =.ai/=, diffs the synced template files against the canonical source, and reports drift. =--apply= flag rsyncs the drift into the project's working tree (no auto-commit). Catches stale projects without forcing a session start in each one.
+
+**** Open design choices
+
+- *Scope.* Template-sync drift is the useful flavor: for each project, diff =.ai/protocols.org=, =.ai/workflows/=, =.ai/scripts/= against the canonical source.
+- *Source path.* Post-fold: =~/code/rulesets/claude-templates/.ai/=. Build =audit= against the new path from day one.
+- *Project discovery.* Walk =~/code/=, =~/projects/=, =~/.emacs.d/= up to depth 3 for any directory containing =.ai/=. Skip the canonical source itself.
+- *Default mode is report-only.* =--apply= triggers rsync; =--force= overrides the dirty-skip safety.
+
+**** Per-project flow (designed 2026-05-15)
+
+For each discovered project, in order:
+
+1. Verify =.ai/= exists (path probe). If missing → =FAIL=, skip, continue loop.
+2. Detect git tracking via =git check-ignore .ai/= → =tracked= or =gitignored=.
+3. Verify no uncommitted =.ai/= changes (=git status --porcelain .ai/=). Dirty → =WARN=, skip rsync unless =--force=.
+4. Verify content matches canonical via three =rsync -a --dry-run --itemize-changes= calls (=protocols.org=, =workflows/=, =scripts/=). Zero items = clean.
+5. Action (=--apply= only, drift detected): three =rsync -a [--delete]= calls.
+6. Verify rsync converged (re-run the dry-runs; zero now).
+7. Verify working-tree state after rsync (tracked projects). Report deltas. Do not auto-commit.
+8. Verify no unpushed =.ai/= commits (=git log @{u}..HEAD -- .ai/=). Informational only.
+
+**** Output format (mirrors =doctor=)
+
+#+begin_example
+Claude-templates source:
+ ok rulesets/claude-templates is current (origin/main)
+
+Per-project .ai/ drift:
+ ok ~/projects/work
+ applied ~/projects/homelab 3 files changed
+ skipped ~/code/winvm uncommitted .ai/ (use --force)
+ ok ~/projects/clipper
+
+Summary: 18 ok, 3 applied, 1 skipped, 0 failed
+#+end_example
+
+Exit code: =0= if all clean, no skips, no failures. =1= otherwise.
+
+**** Why not extend =make doctor= instead
+
+=doctor= has a clean meaning today: "is this machine's =~/.claude/= consistent with rulesets?" Mixing in cross-project =.ai/= drift muddies the exit code. Keep them separate. =audit= can optionally invoke =doctor= as its last check since both ask "did the symlinks keep up with the source?". A future =make all-checks= can wrap both.
+
+*** TODO [#A] Add =make install-ai PROJECT=<path>= — bootstrap =.ai/= in a fresh project
+
+Separate target from =audit= because operating on projects that lack =.ai/= is a distinct action. The absence might be intentional, so =audit= skips them. Bootstrap is explicit opt-in.
+
+**** Flow
+
+1. Refuse if =.ai/= already exists in =PROJECT=. Message: "already installed; use =make audit --apply= to update."
+2. Verify =PROJECT= is a git checkout (warn if not — works without git, loses some lifecycle benefits).
+3. Create =PROJECT/.ai/= directory.
+4. Rsync canonical content: =protocols.org=, =workflows/=, =scripts/= (same three rsyncs as =audit=).
+5. Seed =PROJECT/.ai/notes.org= from a canonical template with project-name placeholder.
+6. Create empty =PROJECT/.ai/sessions/= (with =.gitkeep= for tracked projects).
+7. Track or gitignore =.ai/=? Default: ask. Flag: =--track= / =--gitignore=.
+8. Print next-steps banner: =make install-lang LANG=<lang> PROJECT=<path>=; open Claude Code in the project.
+
+**** Symmetry with existing install targets
+
+#+begin_example
+make install-lang LANG=python PROJECT=/path # language bundle (existing)
+make install-ai PROJECT=/path # .ai/ template (new)
+make install-lang # no args → fzf-pick
+make install-ai # no args → fzf-pick from
+ # ~/projects/* + ~/code/* dirs
+ # without an existing .ai/
+#+end_example
+
+*** TODO [#A] Test plan for audit + install-ai before propagating to ratio
+
+Test against the current state of this machine before pushing changes to ratio.
+
+**** =make audit= tests
+
+1. Dry-run report only (no =--apply=). Should show: claude-templates current; per-project drift; correct =ok=/=drift= classifications; summary line and exit code match.
+2. After the fold lands, every project should be reported as drift (their =startup.org= still points at the old path). Run =--apply= → rsync converges. Re-run audit → all =ok=.
+3. Manually edit one =.ai/workflows/foo.org= in a tracked project. Re-run audit → should report =skipped: uncommitted .ai/=. Run =--apply --force= → rsync clobbers the edit. Verify the edit is gone.
+4. Manually delete one =.ai/= dir. Re-run audit → =FAIL: .ai/ missing=. Loop continues.
+5. Idempotency: =--apply= twice in a row converges to all =ok= on the second pass.
+
+**** =make install-ai= tests
+
+1. Create =/tmp/test-fresh-project= as a git repo. Run =make install-ai PROJECT=/tmp/test-fresh-project=. Verify =.ai/= structure matches canonical, =notes.org= has placeholder, =sessions/= exists.
+2. Run =make install-ai PROJECT=/tmp/test-fresh-project= again → should refuse (=.ai/= already exists).
+3. Open Claude Code in the new project. Startup workflow runs cleanly (Phase A.0 + Phase A rsync should be a no-op since the install just ran).
+4. fzf form: =make install-ai= with no args. Lists candidate dirs (=~/projects/*=, =~/code/*= without =.ai/=).
+
+**** Pass criteria
+
+- =audit= behavior matches the per-project flow spec for every classification path.
+- =install-ai= produces a project indistinguishable from one that's been running sessions for a while.
+- =make doctor= still passes 36/0/0 after all the work.
+- =make test= (pytest + ERT) passes.
+
+*** TODO [#A] Migrate projects on ratio (second machine)
+
+After local fold + audit + install-ai are working, propagate to ratio.
+
+**** Steps
+
+1. On ratio: =git -C ~/code/rulesets pull= — picks up the folded =claude-templates/= subdir and updated =Makefile= targets.
+2. On ratio: archive or =mv= the standalone =~/projects/claude-templates/= aside, replace with symlink to =~/code/rulesets/claude-templates/= (same bridge mechanic as local).
+3. On ratio: =make audit= → see drift across ratio's projects.
+4. On ratio: =make audit --apply= → rsync into each tracked/gitignored project. Surface projects with uncommitted =.ai/= drift for manual handling.
+5. On ratio: =make doctor= → catch any =~/.claude/= install drift (likely some, since ratio hasn't seen recent rulesets updates).
+6. Verify by opening Claude Code in a few ratio projects. Startup should be a no-op or near-zero rsync.
+
+**** Known unknowns
+
+- Ratio may have its own project list overlapping with this machine's but not identical. =audit= discovers projects via the walk, so this is automatic.
+- Ratio might have uncommitted =.ai/= work in some projects that this machine doesn't. =audit= surfaces them; handle case-by-case.
+- If anything goes wrong, ratio's archived =~/projects/claude-templates/= is the safety net — restore the symlink target and re-run audit.
+
+**** Adjacent: cross-machine memory sync
+
+The =[#A] DOING= memory-sync investigation (todo.org:10) is adjacent. Both involve "make my Claude setup portable across machines." Coordinate so the memory-sync stow approach (if approved) doesn't conflict with this fold's symlink mechanics.
+
+** TODO [#C] Refactor =daily-prep.org= to delegate to =triage-intake.org= for the triage section
+
+=daily-prep.org= still does its own inline triage (Gmail × 3 accounts, Slack, Linear, GHE PRs, calendars) as part of the full prep flow. Now that =triage-intake.org= exists as a standalone scan over the same source set, daily-prep could call it and consume its synthesis instead of duplicating the source-scan logic — DRYs up a 57k-line workflow and keeps both flows in sync when sources change.
+
+Scope:
+- Identify the sections in =daily-prep.org= that do the inline triage (the email / Slack / Linear / PR / calendar fan-out, plus the "Sources checked: ..." footer at the top of each generated prep doc).
+- Replace those sections with "run =triage-intake.org=" and adapt the downstream sections (Heads-up, Day's Priorities, Carry-forwards) to read triage-intake's synthesis output rather than the inline scan results.
+- Verify the generated prep doc still has the same shape (Heads-up + Day's Priorities + Carry-forwards + Sources checked).
+
+Origin: came up while authoring =triage-intake.org= on 2026-05-11.
+
+* Rulesets Resolved
+** DONE [#A] Add =make doctor= — verify ~/.claude/ matches repo + settings.json :feature:
+
+A drift detector that scans =~/.claude/= and reports anything inconsistent with what the repo expects. Single-command answer to "is my machine consistent with rulesets?"
+
+*** Why this matters
+
+A 2026-05-06 sweep found =~/.claude/hooks/= didn't exist on this machine even though =settings.json= referenced =~/.claude/hooks/precompact-priorities.sh= as a PreCompact hook. Compaction would have silently failed to invoke the hook. The fix was =make install-hooks=, but the breakage was invisible until I happened to grep for it. =make doctor= run regularly (or even as part of session start) would catch this kind of drift in seconds instead of after the fact.
+
+*** Checks
+
+- Every entry in =settings.json= ="hooks"= block points at a file that exists.
+- Every entry in =enabledPlugins= has a matching install under =~/.claude/plugins/data/=.
+- Every skill in =$(SKILLS)= has a working symlink at =~/.claude/skills/<name>=.
+- Every rule in =$(RULES)= has a working symlink at =~/.claude/rules/<name>=.
+- Every default hook has a symlink at =~/.claude/hooks/<name>= (warn-only — opt-out is legitimate).
+- =settings.json= and =.mcp.json= symlinks resolve to the rulesets versions.
+- =mcp/install.py= state matches =claude mcp list= (every server in =servers.json= is registered).
+- No dangling symlinks anywhere under =~/.claude/=.
+
+*** Output
+
+One line per check: =ok= / =WARN= / =FAIL=. Final summary: =N ok, M warnings, K failures=. Exit non-zero on any failure so it can ride a pre-flight check.
+
+** DONE [#A] Build =voice= skill — combine =humanizer= with universal + personal style passes :feature:
+
+Combine =humanizer= with universal good-writing passes (Strunk & White, Orwell, Plain English) and the personal-style passes from =commits.md=. Two modes — =general= for arbitrary writing, =personal= for commits/PRs/comments — share a foundation and diverge on register.
+
+Built and shipped 2026-05-07: =voice/SKILL.md= with 39 numbered patterns walked sequentially. Patterns 1-25 carried over from humanizer, 26-31 are universal good-writing additions, 32-39 are personal-only. Migrated three callers (=commits.md=, =respond-to-cj-comments.md=, =start-work.md=). Removed the standalone =humanizer= skill since voice supersedes it.
+
+*** Why this matters
+
+Three transformations want to run together for personal-mode artifacts (commits, PR titles + bodies, PR comments) but lived in three places: =humanizer= as a skill, S&W-style universal rules nowhere (applied ad-hoc), and the personal-style passes as prose steps in =commits.md= that got re-applied by hand each time. Costs: (1) the "I forgot pass (e)" failure mode — skipping a pass without flagging is a defect but happens in practice. (2) No single-call invocation of the full transform. (3) General-mode writing (research notes, philosophy, history) got only humanizer with no universal-prose pass at all. Combining brings them under one skill with one invocation.
+
+*** Design
+
+Two modes:
+
+- *general* (default) — for arbitrary writing not bound for commit/PR/comment publishing (research notes, philosophy/history essays, emails, README prose). Runs:
+ - humanizer (current behavior — strip AI-generated-writing fingerprints)
+ - tier-1 universal passes (canonical good-writing rules)
+ - the 2 personal-style passes that have no register conflict (jargon-fragment rewrite, noun-ified verbs)
+
+- *personal* — for commits, PR titles + bodies, PR comments. Runs general PLUS:
+ - 8 personal-only passes (first-person rewrite, semicolons, contractions, sentence-split, felt-experience, sentence fragments, terse cut, public-artifact scope check)
+
+The 8 personal-only passes are explicitly *not* in general mode. They conflict with academic / literary / philosophical register. Forcing first-person on a Foucault essay or stripping felt-experience from a journal entry would damage the writing.
+
+*** Tier 1 universals (v1)
+
+From Strunk & White, Orwell's "Politics and the English Language", Plain English Campaign, and Garner's Modern English Usage. Each is a detection-pattern + rewrite-rule pair, mechanical enough to apply consistently across runs.
+
+- *Omit needless words* — curated phrase list (=the fact that= → =that=/=because=, =in order to= → =to=, =at this point in time= → =now=, =due to the fact that= → =because=, =for the purpose of= → =to=, =in spite of= → =despite=, etc.)
+- *Long word → short word* — Plain English wordlist (~150 entries: =utilize=→=use=, =commence=→=start=, =terminate=→=end=, =facilitate=→=help=, =demonstrate=→=show=, =sufficient=→=enough=, =prior to=→=before=, =subsequent to=→=after=, =in the event that=→=if=, =a great deal of=→=much=)
+- *Active over passive voice* — detect "to be + past-participle" patterns. Suggestion-only in v1 (auto-rewrite is risky in technical contexts where passive is appropriate); graduate to auto-rewrite for unambiguous cases in v2.
+- *Comma splices* — detect independent clauses joined only by comma; rewrite to period or semicolon-then-period.
+- *Cliché flag* — small curated list (=at the end of the day=, =moving forward=, =going forward=, =at this juncture=, =circle back=, =low-hanging fruit=, =deep dive=, =leverage= as verb).
+
+*** Tier 2 universals (v2)
+
+- *Positive over negative form* (S&W) — =not unlike= → =like=, =do not fail to= → =remember to=, =did not pay any attention= → =ignored=
+- *Garner-style word-pair corrections* — comprise/compose, less/fewer, that/which (restrictive vs nonrestrictive), affect/effect, principal/principle
+- *Parallelism in lists* — detect mismatched grammar in bullet items
+- *Tense consistency* — flag mid-paragraph tense shifts
+- *Acronym definition on first use* — detect uppercase tokens used before being expanded
+
+*** Tier 3 (v3, may not land)
+
+- *Concrete-over-abstract* preference
+- *Emphatic word at sentence end* (S&W rule 18)
+- *Vary sentence length / rhythm*
+- *Reading-grade-level scoring* (Hemingway-style)
+
+*** Personal-style pass placement
+
+| # | Pass | Mode | Why |
+|---|------|------|-----|
+| 1 | First-person voice rewrite | personal only | Forces "I" voice; wrong for academic prose where third-person and "we" are conventional |
+| 2 | Jargon-fragment → complete sentence | both | Universal clarity, no genre conflict |
+| 3 | Semicolon → period/comma | personal only | Semicolons are conventional in long-form / academic prose |
+| 4 | Contractions ("it's", "don't") | personal only | Academic and formal writing typically avoids contractions |
+| 5 | Sentence split on conjunctions | personal only | Foucault, Hegel, Adorno deliberately use long compound sentences |
+| 6 | Felt-experience narration ("I'll feel this every time") | personal only | Personal essays *use* felt-experience as content |
+| 7 | Noun-ified verbs ("the ask", "a learn", "the spend") | both | Targets corporate-speak with curated wordlist; doesn't catch philosophical nominalizations like "the becoming" |
+| 8 | Sentence fragments → complete (in prose) | personal only | Fragments are valid stylistic devices in literary prose |
+| 9 | Terse cut (rhetorical padding: "worth noting", "it's important to understand") | personal only | Tier 1 omit-needless-words covers the worst offenders universally; aggressive cut conflicts with academic register |
+| 10 | Public-artifact scope check (local paths, private repos, personal tooling) | personal only — *flag-only*, no auto-rewrite | Operational/safety check, not stylistic; auto-masking risks silently editing meaningful text |
+
+*** Inclusive-language pass — explicitly excluded
+
+Considered and rejected. Conflicts with planned writing on philosophy/history topics (Foucault on sexuality and gender, history of slavery in New Orleans). Wordlist substitutions would override deliberate vocabulary choices in those genres.
+
+*** V1 scope
+
+- [ ] Skill at =~/code/rulesets/voice/= with =SKILL.md=
+- [ ] Frontmatter with positive triggers (commit, PR, comment, "humanize", "voice pass") and negative triggers (code, structured data, plain bullet lists)
+- [X] Mode invocation: default = =general= when invoked bare; =personal= invoked explicitly by publish-context callers
+- [X] humanizer content migrated from =humanizer/= → =voice/=
+- [X] Tier 1 universal passes implemented (5 patterns: #26-30, plus #31 noun-ified verbs as a universal personal addition)
+- [X] 2 personal passes that run in both modes (#30 jargon-fragment, #31 noun-ified verbs)
+- [X] 8 personal passes that run in personal mode only (#32 first-person, #33 semicolons, #34 contractions, #35 sentence-split, #36 felt-experience, #37 fragments, #38 terse cut, #39 scope check)
+- [X] Each pass = detection-pattern + rewrite-rule pair (#39 is detection + flag-only)
+- [X] Total v1 pattern count: 31 in general mode (humanizer's 25 + 4 tier-1 + 2 universal personal); +8 personal-only = 39 in personal mode
+- [X] Update =commits.md= to invoke =/voice personal= instead of "run =humanizer= and apply five passes manually"
+- [X] Remove the existing =humanizer/= skill (no callers outside this repo, all migrated)
+- [X] =make doctor= still passes
+- [X] =make lint= clean
+
+*** v2 (deferred)
+
+- [ ] Tier 2 universals (positive form, word-pair corrections, parallelism, tense consistency, acronym definition)
+- [ ] Per-pass severity flags for Tier 1 active-voice (suggestion-only when actor is implicit; auto-rewrite when actor is named)
+- [ ] Reporting mode: list which passes fired and which were no-ops
+
+*** v3 (aspirational, may not land)
+
+- [ ] Tier 3 (concrete-over-abstract, emphatic-word position, sentence-length variation, reading-grade scoring)
+- [ ] Progressive disclosure split: =voice/SKILL.md= orchestrator + =voice/passes/<pass-name>.md= per pass with worked examples
+
+*** Migration (resolved)
+
+Decision: deleted =humanizer/= entirely. Three callers (=commits.md=, =respond-to-cj-comments.md=, =start-work.md=) all updated to invoke =/voice= directly. No alias needed since nothing outside the repo invoked humanizer.
+
+*** Naming alternatives considered
+
+- =voice= — chosen. Captures both modes; broad enough.
+- =polish= — descriptive of multi-pass nature; less prescriptive about whose voice.
+- =house-style= — signals "this is the house style"; appropriate for personal repo.
+- =commit-voice= — too narrow (passes apply to research notes, emails, etc. in general mode).
+- =humanize= (extending current) — undersells the universal + personal additions.
+
+*** Open questions before implementation
+
+Resolved during implementation:
+- Default mode when =/voice= is invoked bare: =general=. Personal-context callers (=commits.md= publish flow, =respond-to-cj-comments.md=) invoke =/voice personal= explicitly. Avoids accidentally first-person-ifying research notes.
+- Reporting: skill prints "Summary of changes" listing which patterns fired (audit value).
+- Public-artifact scope check (#39): flag-only, user resolves manually. Blocking would frustrate on legitimate path mentions.
+- Tier 1 active-voice detection: suggestion-only in v1. Auto-rewrite for unambiguous cases deferred to v2.
+
+** DONE [#B] Add =--archive-done= mode to =.ai/scripts/todo-cleanup.el= :feature:
+
+Opt-in mode that moves every level-2 subtree whose TODO state is DONE or CANCELLED out of the "Open Work" section and into the "Resolved" section of the same org file, subtree intact.
+
+- *Section matching.* Key on a top-level heading containing "Open Work" and one containing "Resolved" — that pairing is the only naming consistent across projects (=Work Open Work= / =Work Resolved= here; bare =Open Work= / =Resolved= elsewhere). Require exactly one match for each; otherwise skip with a clear message, no crash.
+- *Modes.* =--check= previews and writes nothing, same as the existing hygiene pass. Idempotent. Not run by default in the wrap-up flow — archiving is consequential, so it stays opt-in: =emacs --batch -q -l todo-cleanup.el --archive-done FILE=.
+- *Edge cases.* Source or target section missing; subtree at EOF; nested DONE subtree under an open parent stays put (only level-2 entries move); nothing to move → clean no-op.
+- *Tests.* TDD with ERT — the project's first elisp tests. Fixtures (synthetic) under =.ai/scripts/tests/=; run via =make test= (rulesets) or =make test-scripts= (claude-templates), which run pytest + every =tests/test-*.el= ERT suite. Cases: one DONE level-2 moves; multiple; CANCELLED also moves; structural (no-state) headings don't move; nested DONE under an open parent stays; level-2 DONE with open level-3 children moves intact; subtree at EOF; missing source/target section; ambiguous "Resolved"; lowercase headings; nothing-to-do; idempotency; =--check= preview + its idempotency; realistic-sample integration.
+
+Origin: came up while scrubbing a project's todo.org on 2026-05-11 — moving a big completed PROJECT subtree (plus a few smaller ones) into the Resolved section by hand was the cue to build a reusable tool.
+
+Built and shipped 2026-05-11: =--archive-done= added to =.ai/scripts/todo-cleanup.el= test-first; 13-test ERT suite (=tests/test-todo-cleanup.el=) + realistic synthetic fixture (=tests/fixtures/todo-sample.org=), wired into =make test= / =make test-scripts= alongside pytest. The CLI dispatch moved into =tc-main= behind a guard so the suite can =require= the file without firing it. Section matching is case-insensitive and tolerates the =<Project> Open Work= / =<Project> Resolved= naming variants. Opt-in only — not wired into the wrap-up flow. Source of truth is =~/projects/claude-templates/=; rsync'd into this repo.
+