@brunosps00/dev-workflow 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +6 -5
  3. package/lib/constants.js +6 -4
  4. package/lib/hooks.js +53 -11
  5. package/lib/init.js +49 -1
  6. package/package.json +4 -2
  7. package/scaffold/config/stack-mappings.json +40 -0
  8. package/scaffold/en/commands/dw-adr.md +49 -11
  9. package/scaffold/en/commands/dw-analyze-project.md +10 -1
  10. package/scaffold/en/commands/dw-brainstorm.md +103 -32
  11. package/scaffold/en/commands/dw-claude-run.md +8 -5
  12. package/scaffold/en/commands/dw-context-budget.md +9 -0
  13. package/scaffold/en/commands/dw-harness-audit.md +3 -0
  14. package/scaffold/en/commands/dw-learn.md +41 -0
  15. package/scaffold/en/commands/dw-plan.md +36 -5
  16. package/scaffold/en/commands/dw-review.md +1 -0
  17. package/scaffold/en/commands/dw-run.md +1 -0
  18. package/scaffold/en/templates/adr-template.md +8 -4
  19. package/scaffold/en/templates/idea-onepager.md +44 -2
  20. package/scaffold/pt-br/commands/dw-adr.md +49 -11
  21. package/scaffold/pt-br/commands/dw-analyze-project.md +10 -1
  22. package/scaffold/pt-br/commands/dw-brainstorm.md +105 -32
  23. package/scaffold/pt-br/commands/dw-claude-run.md +8 -5
  24. package/scaffold/pt-br/commands/dw-context-budget.md +9 -0
  25. package/scaffold/pt-br/commands/dw-harness-audit.md +3 -0
  26. package/scaffold/pt-br/commands/dw-learn.md +41 -0
  27. package/scaffold/pt-br/commands/dw-plan.md +36 -5
  28. package/scaffold/pt-br/commands/dw-review.md +1 -0
  29. package/scaffold/pt-br/commands/dw-run.md +1 -0
  30. package/scaffold/pt-br/templates/adr-template.md +8 -4
  31. package/scaffold/pt-br/templates/idea-onepager.md +44 -2
  32. package/scaffold/rules/README.md +22 -0
  33. package/scaffold/rules/common.md +29 -0
  34. package/scaffold/rules/csharp.md +18 -0
  35. package/scaffold/rules/python.md +18 -0
  36. package/scaffold/rules/react.md +18 -0
  37. package/scaffold/rules/rust.md +18 -0
  38. package/scaffold/rules/typescript.md +23 -0
  39. package/scaffold/rules-readme.md +8 -0
  40. package/scaffold/scripts/hooks/session-cost.mjs +126 -0
  41. package/scaffold/scripts/hooks/statusline.mjs +31 -0
  42. package/scaffold/scripts/lib/model-prices.json +12 -0
  43. package/scaffold/skill-registry.json +25 -1
  44. package/scaffold/skills/dw-cli-run/SKILL.md +13 -9
  45. package/scaffold/skills/dw-codebase-intel/SKILL.md +3 -1
  46. package/scaffold/skills/dw-debug-protocol/SKILL.md +4 -0
  47. package/scaffold/skills/dw-debug-protocol/references/agent-degradation.md +30 -0
  48. package/scaffold/skills/dw-domain-modeling/SKILL.md +84 -0
  49. package/scaffold/skills/dw-domain-modeling/references/adr-policy.md +48 -0
  50. package/scaffold/skills/dw-domain-modeling/references/glossary-format.md +66 -0
  51. package/scaffold/skills/dw-execute-phase/SKILL.md +13 -0
  52. package/scaffold/skills/dw-git-discipline/SKILL.md +1 -0
  53. package/scaffold/skills/dw-grilling/SKILL.md +98 -0
  54. package/scaffold/skills/dw-grilling/references/decision-tree.md +56 -0
  55. package/scaffold/skills/dw-grilling/references/interview-loop.md +52 -0
  56. package/scaffold/skills/dw-llm-eval/SKILL.md +12 -0
  57. package/scaffold/skills/dw-memory/SKILL.md +12 -1
  58. package/scaffold/skills/dw-memory/references/instincts.md +45 -0
  59. package/scaffold/skills/dw-review-rigor/SKILL.md +12 -0
  60. package/scaffold/skills/dw-review-rigor/references/false-positives.md +21 -0
  61. package/scaffold/skills/dw-review-rigor/references/self-eval-rubric.md +38 -0
  62. package/scaffold/skills/dw-silent-failure/SKILL.md +4 -2
  63. package/scaffold/skills/dw-simplification/SKILL.md +13 -0
  64. package/scaffold/skills/dw-simplification/references/dead-code-tools.md +23 -0
  65. package/scaffold/skills/dw-testing-discipline/SKILL.md +17 -0
  66. package/scaffold/skills/dw-ui-discipline/SKILL.md +1 -1
  67. package/scaffold/skills/dw-verify/SKILL.md +1 -1
  68. package/scaffold/skills/dw-verify/references/pre-check-and-status.md +28 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dev-workflow",
3
3
  "description": "Standalone, à-la-carte skills from the dev-workflow pipeline: minimalism, search-first, simplification, verification, security review, and more.",
4
- "version": "1.4.0",
4
+ "version": "1.6.0",
5
5
  "author": {
6
6
  "name": "Bruno Santos"
7
7
  },
package/README.md CHANGED
@@ -12,11 +12,11 @@ This will:
12
12
  1. Ask you to select a language (English or Portuguese)
13
13
  2. Create `.dw/commands/` with workflow commands
14
14
  3. Create `.dw/templates/` with document templates (PRD, TechSpec, Tasks, ADR, etc.)
15
- 4. Create `.dw/rules/` (populated by `/dw-analyze-project`)
15
+ 4. Create `.dw/rules/` (populated by `/dw-analyze-project`) + a curated `.dw/rules-library/` declarative baseline per stack (loaded lazily via `.dw/config/stack-mappings.json`)
16
16
  5. Install bundled skills (`dw-verify`, `dw-memory`, `dw-review-rigor`, `dw-ui-discipline`, `dw-testing-discipline`, `security-review`, etc.) to `.agents/skills/`
17
17
  6. Generate skill wrappers and project agents for Claude Code, Codex, Copilot, and OpenCode
18
18
  7. Configure MCP servers (Context7 + Playwright)
19
- 8. Install enforcement hooks (git guardrails) + a statusline into `.claude/settings.json` (merge-aware — your own hooks/statusline are never overwritten)
19
+ 8. Install enforcement hooks (git guardrails + a `SessionEnd` token-cost tracker → `.dw/metrics/costs.jsonl`) + a statusline (branch · active spec · minimalism mode · today's estimated spend) into `.claude/settings.json` (merge-aware — your own hooks/statusline are never overwritten)
20
20
 
21
21
  > **Compozy-inspired disciplines.** Since 0.5.0, dev-workflow bundles three primitives — `dw-verify`, `dw-memory`, `dw-review-rigor` — adapted from the [Compozy](https://github.com/compozy/compozy) project and invoked internally by existing commands. See [docs/compozy-integration.md](docs/compozy-integration.md) for what was ported and what was not.
22
22
 
@@ -42,7 +42,7 @@ Exportable skills (no `.dw/` pipeline required): `dw-minimalism`, `dw-search-fir
42
42
 
43
43
  ## Commands
44
44
 
45
- dev-workflow v1.4.0 ships **36 commands** organized into four tiers. Most users only invoke Tier 1 + Tier 2.
45
+ dev-workflow v1.6.0 ships **37 commands** organized into four tiers. Most users only invoke Tier 1 + Tier 2.
46
46
 
47
47
  ### Tier 1 — Gateway (3)
48
48
 
@@ -69,7 +69,7 @@ Use these when you want step-by-step control instead of `/dw-autopilot`.
69
69
  | **`/dw-commit`** | Atomic Conventional Commits for pending changes. Applies `dw-git-discipline` (one intent per commit, lint+tests+build green before). |
70
70
  | **`/dw-generate-pr [target]`** | Push the branch, draft a PR body with summary + test plan, open the browser. Hard gates: dw-verify PASS + secure-audit. |
71
71
 
72
- ### Tier 3 — Specialty (11)
72
+ ### Tier 3 — Specialty (12)
73
73
 
74
74
  | Command | What |
75
75
  |---------|------|
@@ -80,6 +80,7 @@ Use these when you want step-by-step control instead of `/dw-autopilot`.
80
80
  | **`/dw-context-budget`** | Audits context overhead from commands, skills, agents, instruction files, and MCPs. |
81
81
  | **`/dw-harness-audit`** | Deterministic health scorecard for the dev-workflow install, agents, wrappers, MCPs, and gates. |
82
82
  | **`/dw-skill-health`** | Audits installed skills and agents for bloat, duplication, and missing references. |
83
+ | **`/dw-learn`** | Synthesizes durable decisions (confidence-tagged), bugfixes, deviations, and git history into atomic confidence-weighted **instincts** you approve at `.dw/memory/instincts/`; can propose constitution principles. On-demand and human-in-the-loop — **no always-on observer**. |
83
84
  | **`/dw-new-project`** | Bootstrap a new project from empty directory. Stack interview, wraps official `create-*` tools, composes docker-compose for dev, seeds `.env`, scripts, CI, `.dw/rules/`. |
84
85
  | **`/dw-dockerize`** | Reads existing project, detects stack + runtime deps, proposes Dockerfile + docker-compose for dev/prod with explicit trade-offs (Conservative/Balanced/Bold). |
85
86
  | **`/dw-install-azure-skills`** | **Opt-in.** Clones curated Azure skills from [`MicrosoftDocs/Agent-Skills`](https://github.com/MicrosoftDocs/Agent-Skills) (CC-BY-4.0) into `.agents/skills/azure/` and registers the [Microsoft Learn MCP Server](https://learn.microsoft.com/en-us/training/support/mcp-get-started) (HTTP, no-auth). Interactive category selection (Compute / Data & Storage / AI & ML / Networking / Identity & Security / DevOps / Observability / Integration / Architecture / All). Re-run to refresh from upstream. Also available as CLI: `npx @brunosps00/dev-workflow install-azure-skills`. |
@@ -376,7 +377,7 @@ Optional Azure integration (v1.0.3). The `/dw-install-azure-skills` command and
376
377
 
377
378
  Session continuity and adaptive routing patterns adapted from [`tech-leads-club/agent-skills/tlc-spec-driven`](https://github.com/tech-leads-club/agent-skills/tree/main/packages/skills-catalog/skills/(development)/tlc-spec-driven) by Felipe Rodrigues (CC-BY-4.0, v1.0.2). Eight patterns were absorbed selectively after a comparative analysis confirmed that the majority of the skill duplicates existing dev-workflow capabilities (PRD/TechSpec/Tasks pipeline, constitution discipline, source-grounding, two-tier memory, verify-before-complete, brownfield mapping, sub-agent delegation, atomic commits). Patterns adopted: (1) `STATE.md` cross-session working memory at `.dw/STATE.md` + new `/dw-pause` and `/dw-resume` commands; (2) Auto-Sizing Matrix (Small/Medium/Large/Complex) formalized in `CLAUDE.md`/`AGENTS.md` above the Trigger Map; (3) Concerns Map (`.dw/rules/concerns.md`) generated by a new Step 9 in `/dw-analyze-project` and consumed on-demand by `/dw-plan`, `/dw-run`, and `/dw-bugfix`; (4) Context Budget discipline as a new section in `dw-memory` with reference `dw-memory/references/context-budget.md`; (5) Interactive UAT walkthrough as `/dw-qa --uat`; (6) Quick-mode persistence — bugfixes now land in `.dw/bugfixes/NNN-<slug>/{TASK.md, SUMMARY.md, fix-report.md}` and remain queryable via `/dw-intel`; (7) Safety valve in `/dw-bugfix` Step 5.0 that forces escalation to `/dw-plan` when scope exceeds 5 tasks or has cross-dependencies; (8) Cross-skill awareness — `/dw-intel --build` now indexes `.dw/bugfixes/*/SUMMARY.md` into `bugfixes.json`, and `dw-codebase-intel` documents the new `bugfix-history` and `risk-area` query shapes. Patterns explicitly REJECTED: `.specs/` directory structure (dev-workflow uses `.dw/`), Knowledge Verification Chain (already covered by `dw-source-grounding`), Specify/Design/Tasks/Execute naming (dev-workflow keeps PRD/TechSpec/Tasks/Run), Skill Integrations pattern with mermaid-studio/codenavi delegation, and literal text copying (everything is clean-room reimplementation from the conceptual patterns; CC-BY-4.0 attribution is for derivative ideas, not borrowed prose).
378
379
 
379
- Four patterns from [`mattpocock/skills`](https://github.com/mattpocock/skills) by Matt Pocock (MIT) were integrated **without adding new commands or skills** — instead they fold into the existing surface as internal modes and inline guidance: (1) **grill-with-docs** → `/dw-brainstorm` `grill` mode (interview discipline that stress-tests plan vocabulary against `.dw/rules/`); (2) **prototype** → `/dw-brainstorm` `prototype` mode (LOGIC terminal app or UI variant dispatch); (3) **improve-codebase-architecture** → `dw-simplification/references/deep-modules.md` (deletion test, locality, leverage, seam, adapter diagnostic invoked by the `refactor-audit` mode); (4) **zoom-out** → one-paragraph guidance in `agent-instructions.md`. The same release also collapses `/dw-brainstorm`'s six legacy flags into a single full-flow entry point that auto-dispatches modes based on project signals.
380
+ Patterns from [`mattpocock/skills`](https://github.com/mattpocock/skills) by Matt Pocock (MIT) were integrated **without adding any new public command** (the public command count is unchanged): (1) **grill** — a native, stateful alignment session reimplemented (clean-room, no upstream prose copied) from [`skills/engineering/grill-with-docs`](https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/SKILL.md), [`skills/productivity/grilling`](https://github.com/mattpocock/skills/blob/main/skills/productivity/grilling/SKILL.md), and [`skills/engineering/domain-modeling`](https://github.com/mattpocock/skills/blob/main/skills/engineering/domain-modeling/SKILL.md). It is the `/dw-brainstorm` `grill` mode, backed by two **internal, non-exported** bundled skills — `dw-grilling` (dependency-ordered decision-tree interview, one decision per turn with a recommended answer, facts looked up rather than asked, shared-understanding gate) and `dw-domain-modeling` (canonical glossary, fuzzy/overloaded-term challenge, rare ADRs). Intentional `.dw/` differences: the curated glossary lives in **`.dw/domain/**`** (not upstream's root `CONTEXT.md`, and not our auto-generated `.dw/rules/`); Grill requires **one explicit authorization** before it writes and is mutually exclusive with the option matrix; alignment emits an idea one-pager at **schema `1.1`** consumed by `/dw-plan` without re-asking; and ADR creation is gated on the 3-criteria test and routed via `/dw-adr --scope=repo|prd`. (2) **prototype** → `/dw-brainstorm` `prototype` mode (LOGIC terminal app or UI variant dispatch); (3) **improve-codebase-architecture** → `dw-simplification/references/deep-modules.md` (deletion test, locality, leverage, seam, adapter diagnostic invoked by the `refactor-audit` mode); (4) **zoom-out** → one-paragraph guidance in `agent-instructions.md`. The same line of work also collapses `/dw-brainstorm`'s six legacy flags into a single full-flow entry point that auto-dispatches modes based on project signals.
380
381
 
381
382
  Opportunity discovery and the explicit `/dw-refactor` surface were inspired by patterns observed in [`pedronauck/skills`](https://github.com/pedronauck/skills), especially `game-changing-features` (10x opportunity framing) and `refactoring-analysis` (Fowler-smell prioritization). dev-workflow does not install or depend on that repository at runtime, and the command text here is a clean-room adaptation of the workflow shape rather than copied skill content.
382
383
 
package/lib/constants.js CHANGED
@@ -1,9 +1,9 @@
1
1
  const COMMANDS = {
2
2
  en: [
3
- { name: 'dw-adr', description: 'Records an architectural decision and the trade-offs accepted, before they get lost.' },
3
+ { name: 'dw-adr', description: 'Records an architectural decision and the trade-offs accepted, before they get lost. --scope=repo writes .dw/adrs/ (works before any PRD); --scope=prd writes under the active PRD. Gated on hard-to-reverse + surprising + genuine trade-off.' },
4
4
  { name: 'dw-analyze-project', description: 'Scans the repo to learn its stack and conventions, then writes the rules other commands rely on.' },
5
5
  { name: 'dw-autopilot', description: 'Trigger when user asks to implement, build, create, or add a feature non-trivially. First invocation plans and stops; second invocation resumes via dw-goal, then commit and PR.' },
6
- { name: 'dw-brainstorm', description: 'Refine a concrete idea against the product\'s existing features. Modes: ideation, --research, --onepager, --council. Use dw-opportunities before you have an idea and dw-refactor for code-health audits.' },
6
+ { name: 'dw-brainstorm', description: 'Refine a concrete idea against the product\'s existing features. Auto-dispatches internal modes via --mode= (option-matrix / grill / prototype / council / research / refactor-audit / onepager). Grill is a native stateful alignment session (a direct grill-me phrase or --mode=grill) that writes canonical vocabulary to .dw/domain/. Use dw-opportunities before you have an idea and dw-refactor for code-health audits.' },
7
7
  { name: 'dw-bugfix', description: 'Trigger when user reports a bug, pastes an error, or describes broken behavior. Triages with three questions, then fixes or routes to PRD.' },
8
8
  { name: 'dw-claude-run', userInvoked: true, description: 'Trigger when user asks to run/fire Claude (claude -p headless) in a dedicated worktree to implement a prepared prompt/spec. Claude adapter over the dw-cli-run protocol: durable audit log, resumable session via --session-id, 0-10 dual evaluation, STOP for the gate. Never the main checkout; never merges.' },
9
9
  { name: 'dw-codex-run', userInvoked: true, description: 'Trigger when user asks to run/fire Codex (codex exec) in a dedicated worktree to implement a prepared prompt/spec. Codex adapter over the dw-cli-run protocol: durable audit log, resumable per-task session, 0-10 dual evaluation, STOP for the gate. Never the main checkout; never merges.' },
@@ -20,6 +20,7 @@ const COMMANDS = {
20
20
  { name: 'dw-install-aws-skills', description: 'Trigger when user asks to install AWS expertise, setup AWS MCP server, or add AWS agent skills. Opt-in: clones curated skills from aws/agent-toolkit-for-aws into .agents/skills/aws/ and registers the unified AWS MCP Server (stdio via mcp-proxy-for-aws). Requires uv, aws cli, and AWS credentials.' },
21
21
  { name: 'dw-install-azure-skills', description: 'Trigger when user asks to install Azure expertise, setup Microsoft docs MCP, or add Azure agent skills. Opt-in: clones curated skills from MicrosoftDocs/Agent-Skills into .agents/skills/azure/ and registers the Microsoft Learn MCP server.' },
22
22
  { name: 'dw-intel', description: 'Codebase intelligence: query mode (default) answers questions citing .dw/intel/ + .dw/rules/; --build mode (re)builds the index.' },
23
+ { name: 'dw-learn', description: 'Synthesizes durable decisions, bugfixes, deviations, and git history into atomic confidence-weighted instincts you approve; can propose constitution principles. On-demand and human-in-the-loop — no always-on observer.' },
23
24
  { name: 'dw-new-project', description: 'Interviews you about stack and infra, then scaffolds a working monorepo with docker-compose for dev, .env, scripts, CI, and seeded rules.' },
24
25
  { name: 'dw-opportunities', description: 'Scans the installed project for product, UX, automation, refactor, and security opportunities, then routes each idea to the right next dw-* command.' },
25
26
  { name: 'dw-pause', description: 'Trigger when user says "pause work", "end session", or "save where we are". Consolidates open loops, decisions, blockers, and todos into .dw/STATE.md so the next session can resume.' },
@@ -38,10 +39,10 @@ const COMMANDS = {
38
39
  { name: 'dw-update', description: 'Updates dev-workflow to the latest npm release in-place, with a snapshot you can roll back to.' },
39
40
  ],
40
41
  'pt-br': [
41
- { name: 'dw-adr', description: 'Registra uma decisao arquitetural e os trade-offs aceitos, antes que se percam.' },
42
+ { name: 'dw-adr', description: 'Registra uma decisao arquitetural e os trade-offs aceitos, antes que se percam. --scope=repo escreve em .dw/adrs/ (funciona antes de qualquer PRD); --scope=prd escreve sob o PRD ativo. Gated em dificil-de-reverter + surpreendente + trade-off real.' },
42
43
  { name: 'dw-analyze-project', description: 'Escaneia o repo para aprender stack e convencoes, e escreve as regras que os outros commands usam.' },
43
44
  { name: 'dw-autopilot', description: 'Trigger quando usuario pede pra implementar, criar ou adicionar uma feature nao-trivial. Primeira invocacao planeja e para; segunda retoma via dw-goal, depois commit e PR.' },
44
- { name: 'dw-brainstorm', description: 'Refina uma ideia concreta contra features existentes do produto. Modos: ideacao, --research, --onepager, --council. Use dw-opportunities antes de ter uma ideia e dw-refactor para auditoria de code health.' },
45
+ { name: 'dw-brainstorm', description: 'Refina uma ideia concreta contra features existentes do produto. Auto-dispatch de modos internos via --mode= (option-matrix / grill / prototype / council / research / refactor-audit / onepager). Grill e uma sessao nativa de alinhamento com estado (frase direta tipo me-questione ou --mode=grill) que escreve vocabulario canonico em .dw/domain/. Use dw-opportunities antes de ter uma ideia e dw-refactor para auditoria de code health.' },
45
46
  { name: 'dw-bugfix', description: 'Trigger quando usuario reporta bug, cola erro ou descreve comportamento quebrado. Tria com tres perguntas, depois corrige ou roteia pra PRD.' },
46
47
  { name: 'dw-claude-run', userInvoked: true, description: 'Trigger quando usuario pede pra rodar/disparar o Claude (claude -p headless) numa worktree dedicada pra implementar um prompt/spec preparado. Adapter Claude sobre o protocolo dw-cli-run: log de auditoria duravel, sessao resumivel via --session-id, dupla avaliacao 0-10, PARA pro gate. Nunca no checkout principal; nunca mergeia.' },
47
48
  { name: 'dw-codex-run', userInvoked: true, description: 'Trigger quando usuario pede pra rodar/disparar o Codex (codex exec) numa worktree dedicada pra implementar um prompt/spec preparado. Adapter Codex sobre o protocolo dw-cli-run: log de auditoria duravel, sessao resumivel por tarefa, dupla avaliacao 0-10, PARA pro gate. Nunca no checkout principal; nunca mergeia.' },
@@ -58,6 +59,7 @@ const COMMANDS = {
58
59
  { name: 'dw-install-aws-skills', description: 'Trigger quando usuario pede pra instalar expertise AWS, configurar MCP da AWS, ou adicionar agent skills AWS. Opt-in: clona skills curadas de aws/agent-toolkit-for-aws para .agents/skills/aws/ e registra o AWS MCP Server unificado (stdio via mcp-proxy-for-aws). Requer uv, aws cli e credenciais AWS.' },
59
60
  { name: 'dw-install-azure-skills', description: 'Trigger quando usuario pede pra instalar expertise Azure, configurar MCP do Microsoft docs, ou adicionar agent skills Azure. Opt-in: clona skills curadas de MicrosoftDocs/Agent-Skills para .agents/skills/azure/ e registra o Microsoft Learn MCP server.' },
60
61
  { name: 'dw-intel', description: 'Inteligencia do codebase: modo query (default) responde citando .dw/intel/ + .dw/rules/; modo --build (re)constroi indice.' },
62
+ { name: 'dw-learn', description: 'Sintetiza decisoes duraveis, bugfixes, deviations e historico git em instincts atomicos ponderados por confianca que voce aprova; pode propor principios de constitution. On-demand e human-in-the-loop — sem observador sempre-ligado.' },
61
63
  { name: 'dw-new-project', description: 'Entrevista voce sobre stack e infra, depois faz scaffold de um monorepo com docker-compose para dev, .env, scripts, CI e rules seed.' },
62
64
  { name: 'dw-opportunities', description: 'Escaneia o projeto instalado por oportunidades de produto, UX, automacao, refactor e seguranca, e roteia cada ideia para o proximo comando dw-* correto.' },
63
65
  { name: 'dw-pause', description: 'Trigger quando usuario diz "pausa o trabalho", "encerra a sessao" ou "salva onde paramos". Consolida pontas soltas, decisoes, bloqueios e todos em .dw/STATE.md para a proxima sessao retomar.' },
package/lib/hooks.js CHANGED
@@ -7,6 +7,8 @@ const HOOKS_DIR_MARKER = '.dw/scripts/hooks/';
7
7
  const GIT_GUARDRAILS_CMD = 'node .dw/scripts/hooks/git-guardrails.mjs';
8
8
  const STATUSLINE_CMD = 'node .dw/scripts/hooks/statusline.mjs';
9
9
  const GIT_GUARDRAILS_SCRIPT = 'git-guardrails.mjs';
10
+ const SESSION_COST_CMD = 'node .dw/scripts/hooks/session-cost.mjs';
11
+ const SESSION_COST_SCRIPT = 'session-cost.mjs';
10
12
 
11
13
  function isOurs(command) {
12
14
  return typeof command === 'string' && command.includes(HOOKS_DIR_MARKER);
@@ -31,13 +33,48 @@ function installHooks(projectRoot) {
31
33
  const before = JSON.stringify(settings);
32
34
 
33
35
  const hooksResult = reconcilePreToolUseGitGuardrails(settings);
36
+ const sessionCostResult = reconcileSessionEndCost(settings);
34
37
  const statusLineResult = reconcileStatusLine(settings);
35
38
 
36
39
  if (JSON.stringify(settings) !== before) {
37
40
  writeSettings(projectRoot, settings);
38
41
  }
39
42
 
40
- return { hooks: hooksResult, statusLine: statusLineResult };
43
+ return { hooks: hooksResult, sessionCost: sessionCostResult, statusLine: statusLineResult };
44
+ }
45
+
46
+ /**
47
+ * Reconcile the SessionEnd cost-tracking hook (marker-based, merge-aware — same
48
+ * contract as the git guardrail). No matcher: fires on every session end.
49
+ * Returns 'added' | 'updated' | 'unchanged'.
50
+ */
51
+ function reconcileSessionEndCost(settings) {
52
+ if (!settings.hooks || typeof settings.hooks !== 'object') settings.hooks = {};
53
+ if (!Array.isArray(settings.hooks.SessionEnd)) settings.hooks.SessionEnd = [];
54
+
55
+ const groups = settings.hooks.SessionEnd;
56
+
57
+ const existed = groups.some(
58
+ (g) => g && Array.isArray(g.hooks) && g.hooks.some((h) => h && typeof h.command === 'string' && h.command.includes(SESSION_COST_SCRIPT)),
59
+ );
60
+ const exactPresent = groups.some(
61
+ (g) => g && Array.isArray(g.hooks) && g.hooks.some((h) => h && h.command === SESSION_COST_CMD),
62
+ );
63
+
64
+ if (exactPresent) return 'unchanged';
65
+
66
+ // Drop any stale/relocated copies of OUR hook, preserving user hooks.
67
+ for (const group of groups) {
68
+ if (!group || !Array.isArray(group.hooks)) continue;
69
+ group.hooks = group.hooks.filter(
70
+ (h) => !(h && typeof h.command === 'string' && h.command.includes(SESSION_COST_SCRIPT)),
71
+ );
72
+ }
73
+ settings.hooks.SessionEnd = groups.filter((g) => g && Array.isArray(g.hooks) && g.hooks.length > 0);
74
+
75
+ settings.hooks.SessionEnd.push({ hooks: [{ type: 'command', command: SESSION_COST_CMD }] });
76
+
77
+ return existed ? 'updated' : 'added';
41
78
  }
42
79
 
43
80
  function reconcilePreToolUseGitGuardrails(settings) {
@@ -105,17 +142,21 @@ function removeHooks(projectRoot) {
105
142
  const settings = readSettings(projectRoot);
106
143
  let removed = 0;
107
144
 
108
- if (settings.hooks && Array.isArray(settings.hooks.PreToolUse)) {
109
- for (const group of settings.hooks.PreToolUse) {
110
- if (!group || !Array.isArray(group.hooks)) continue;
111
- const kept = group.hooks.filter((h) => !(h && isOurs(h.command)));
112
- removed += group.hooks.length - kept.length;
113
- group.hooks = kept;
145
+ // Remove OUR hook entries from every event (PreToolUse, SessionEnd, PostToolUse, …),
146
+ // identified by the .dw/scripts/hooks/ marker; never touch user-added hooks.
147
+ if (settings.hooks && typeof settings.hooks === 'object') {
148
+ for (const event of Object.keys(settings.hooks)) {
149
+ const groups = settings.hooks[event];
150
+ if (!Array.isArray(groups)) continue;
151
+ for (const group of groups) {
152
+ if (!group || !Array.isArray(group.hooks)) continue;
153
+ const kept = group.hooks.filter((h) => !(h && isOurs(h.command)));
154
+ removed += group.hooks.length - kept.length;
155
+ group.hooks = kept;
156
+ }
157
+ settings.hooks[event] = groups.filter((g) => g && Array.isArray(g.hooks) && g.hooks.length > 0);
158
+ if (settings.hooks[event].length === 0) delete settings.hooks[event];
114
159
  }
115
- settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter(
116
- (g) => g && Array.isArray(g.hooks) && g.hooks.length > 0,
117
- );
118
- if (settings.hooks.PreToolUse.length === 0) delete settings.hooks.PreToolUse;
119
160
  if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
120
161
  }
121
162
 
@@ -134,4 +175,5 @@ module.exports = {
134
175
  HOOKS_DIR_MARKER,
135
176
  GIT_GUARDRAILS_CMD,
136
177
  STATUSLINE_CMD,
178
+ SESSION_COST_CMD,
137
179
  };
package/lib/init.js CHANGED
@@ -170,6 +170,30 @@ async function run({ force = false, lang = null, mode = 'init', profile = null,
170
170
  console.log();
171
171
  }
172
172
 
173
+ // 3.9. Copy curated rules library + stack mappings (declarative baseline per stack,
174
+ // loaded lazily by the detected stack). Managed: reconciled on update/repair.
175
+ const rulesLibSrc = path.join(SCAFFOLD_DIR, 'rules');
176
+ if (require('fs').existsSync(rulesLibSrc)) {
177
+ console.log(' Rules library:');
178
+ const rlResults = copyDir(rulesLibSrc, path.join(projectRoot, '.dw', 'rules-library'), managedForce);
179
+ totalCreated += rlResults.created;
180
+ totalSkipped += rlResults.skipped;
181
+ totalOverwritten += rlResults.overwritten;
182
+ touchedFiles.push(...listFilesRecursive(path.join(projectRoot, '.dw', 'rules-library')));
183
+ console.log(` ${rlResults.created} created, ${rlResults.skipped} skipped, ${rlResults.overwritten} overwritten\n`);
184
+ }
185
+ const stackMapSrc = path.join(SCAFFOLD_DIR, 'config', 'stack-mappings.json');
186
+ if (require('fs').existsSync(stackMapSrc)) {
187
+ const cfgDir = path.join(projectRoot, '.dw', 'config');
188
+ ensureDir(cfgDir);
189
+ const stackMapDest = path.join(cfgDir, 'stack-mappings.json');
190
+ const smStatus = writeFile(stackMapDest, require('fs').readFileSync(stackMapSrc, 'utf-8'), managedForce);
191
+ if (smStatus === 'created') totalCreated++;
192
+ else if (smStatus === 'overwritten') totalOverwritten++;
193
+ else totalSkipped++;
194
+ touchedFiles.push(stackMapDest);
195
+ }
196
+
173
197
  // 4. Create .dw/rules/ with README
174
198
  if (!isUpdate) {
175
199
  console.log(' Rules:');
@@ -233,6 +257,30 @@ async function run({ force = false, lang = null, mode = 'init', profile = null,
233
257
  touchedFiles.push(gitkeepPath);
234
258
  }
235
259
 
260
+ // 5.25. Ensure .dw/metrics/ + .gitignore (runtime cost tracking; costs.jsonl is
261
+ // machine-local so it is gitignored). Created if missing on both init and update.
262
+ {
263
+ const metricsDir = path.join(projectRoot, '.dw', 'metrics');
264
+ ensureDir(metricsDir);
265
+ const metricsGitignore = path.join(metricsDir, '.gitignore');
266
+ const mStatus = writeFile(metricsGitignore, 'costs.jsonl\n', false);
267
+ if (mStatus === 'created') totalCreated++;
268
+ else totalSkipped++;
269
+ touchedFiles.push(metricsGitignore);
270
+ }
271
+
272
+ // 5.26. Ensure .dw/memory/instincts/ (durable learnings promoted by /dw-learn;
273
+ // format in the dw-memory skill's references/instincts.md). Init only; preserved on update.
274
+ if (!isUpdate) {
275
+ const instinctsDir = path.join(projectRoot, '.dw', 'memory', 'instincts');
276
+ ensureDir(instinctsDir);
277
+ const instinctsKeep = path.join(instinctsDir, '.gitkeep');
278
+ const ikStatus = writeFile(instinctsKeep, '', false);
279
+ if (ikStatus === 'created') totalCreated++;
280
+ else totalSkipped++;
281
+ touchedFiles.push(instinctsKeep);
282
+ }
283
+
236
284
  // 5.3. Create local ephemeral subtask handoff directories.
237
285
  ensureSubtaskLayout(projectRoot);
238
286
  touchedFiles.push(path.join(projectRoot, '.dw', 'subtasks', '.gitignore'));
@@ -317,7 +365,7 @@ async function run({ force = false, lang = null, mode = 'init', profile = null,
317
365
  // refreshes our entries, never touches user-defined hooks/statusLine).
318
366
  console.log(' Hooks & statusline:');
319
367
  const hookResults = installHooks(projectRoot);
320
- console.log(` git-guardrails: ${hookResults.hooks}, statusline: ${hookResults.statusLine}\n`);
368
+ console.log(` git-guardrails: ${hookResults.hooks}, session-cost: ${hookResults.sessionCost}, statusline: ${hookResults.statusLine}\n`);
321
369
  if (hookResults.statusLine === 'skipped-user') {
322
370
  console.log(' Note: a custom statusLine is set; to show dev-workflow state add `node .dw/scripts/hooks/statusline.mjs`.\n');
323
371
  }
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@brunosps00/dev-workflow",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "AI-driven development workflow commands for any project. Scaffolds a complete PRD-to-PR pipeline with multi-platform AI assistant support.",
5
5
  "bin": {
6
6
  "dev-workflow": "./bin/dev-workflow.js"
7
7
  },
8
8
  "scripts": {
9
+ "test": "node --test test/*.test.js",
9
10
  "validate": "node lib/validate.js",
10
- "build:plugin": "node lib/build-plugin.js"
11
+ "build:plugin": "node lib/build-plugin.js",
12
+ "pack:check": "npm pack --dry-run"
11
13
  },
12
14
  "files": [
13
15
  "bin/",
@@ -0,0 +1,40 @@
1
+ {
2
+ "_note": "Maps a detected stack to its curated baseline rule files (in .dw/rules-library/), relevant bundled skills, and safe default permissions. Consumed by /dw-analyze-project (detect + seed constitution) and /dw-review (declarative bar). Load ONLY the active stack's rules — never the whole library. Indicators: a bare filename means 'file exists'; 'file:substring' means the file contains the substring.",
3
+ "stacks": [
4
+ {
5
+ "id": "typescript",
6
+ "indicators": ["tsconfig.json", "package.json:typescript"],
7
+ "rules": ["common", "typescript"],
8
+ "skills": ["dw-testing-discipline", "dw-simplification"],
9
+ "permissions": { "allow": ["npx tsc", "npx eslint", "npm test", "pnpm test"], "deny": ["npm publish"] }
10
+ },
11
+ {
12
+ "id": "react",
13
+ "indicators": ["package.json:react"],
14
+ "rules": ["common", "typescript", "react"],
15
+ "skills": ["dw-ui-discipline", "vercel-react-best-practices", "dw-testing-discipline"],
16
+ "permissions": { "allow": ["npm test", "pnpm test", "npx vitest"], "deny": [] }
17
+ },
18
+ {
19
+ "id": "python",
20
+ "indicators": ["pyproject.toml", "requirements.txt", "setup.py"],
21
+ "rules": ["common", "python"],
22
+ "skills": ["dw-testing-discipline", "dw-silent-failure"],
23
+ "permissions": { "allow": ["pytest", "ruff", "mypy"], "deny": [] }
24
+ },
25
+ {
26
+ "id": "rust",
27
+ "indicators": ["Cargo.toml"],
28
+ "rules": ["common", "rust"],
29
+ "skills": ["dw-testing-discipline"],
30
+ "permissions": { "allow": ["cargo test", "cargo clippy", "cargo check"], "deny": [] }
31
+ },
32
+ {
33
+ "id": "csharp",
34
+ "indicators": [".csproj", ".sln"],
35
+ "rules": ["common", "csharp"],
36
+ "skills": ["dw-testing-discipline"],
37
+ "permissions": { "allow": ["dotnet test", "dotnet build"], "deny": [] }
38
+ }
39
+ ]
40
+ }
@@ -1,36 +1,71 @@
1
1
  <system_instructions>
2
- You are an architectural-decision recorder. Your job is to create an **Architecture Decision Record (ADR)** documenting an important technical decision made during the current PRD phase.
2
+ You are an architectural-decision recorder. Your job is to create an **Architecture Decision Record (ADR)** documenting an important technical decision — either repo-wide (`--scope=repo`, valid even before any PRD exists) or bound to an active PRD (`--scope=prd`).
3
3
 
4
4
  ## When to Use
5
5
  - Use when an architectural or design decision has been made and needs to be recorded for future reference (library choice, communication pattern, performance tradeoff, compliance-imposed constraint, etc.)
6
6
  - Use during `/dw-plan techspec` or `/dw-run` when the rationale for the decision does not fit in the techspec or the task file
7
+ - Use **before any PRD exists** to record a repo-wide decision — pass `--scope=repo` (writes to `.dw/adrs/`).
7
8
  - Do NOT use for trivial or cheaply-reversible decisions (variable names, import order)
8
9
  - Do NOT use to record bugs or incidents (use `/dw-bugfix` or operational notes)
9
10
 
11
+ <critical>Offer or create an ADR ONLY when all three criteria hold: (1) **hard to reverse**, (2) **surprising without context**, and (3) a **genuine trade-off** (a real alternative was considered and chosen against). If any one is missing, skip the ADR — do not turn the ADR log into noise. Creation ALWAYS needs explicit user approval, even when all three hold.</critical>
12
+
10
13
  ## Pipeline Position
11
- **Predecessor:** any point in the pipeline after `/dw-plan prd` | **Successor:** continue the previous flow (techspec, task, review)
14
+ **Predecessor:** any point (repo-scoped ADRs work even before `/dw-plan prd`) | **Successor:** continue the previous flow (techspec, task, review)
12
15
 
13
16
  The ADR is **additive**: it does not replace any pipeline stage. Any existing command can invoke `/dw-adr` when a non-trivial decision needs a permanent record.
14
17
 
18
+ ## Scope (`--scope=repo|prd`)
19
+
20
+ | Scope | Directory | When |
21
+ |-------|-----------|------|
22
+ | `repo` | `.dw/adrs/adr-NNN.md` | Repo-wide decision, and any decision made **before a PRD exists**. |
23
+ | `prd` | `{{PRD_PATH}}/adrs/adr-NNN.md` | Decision bound to a specific active PRD. |
24
+
25
+ **Default resolution** when `--scope` is not given (`--scope=` is always authoritative and overrides this):
26
+
27
+ 1. Determine the **candidate active PRDs** (see "Active PRD" below) — PRD directories in `.dw/spec/prd-*/` that are NOT terminal/historical.
28
+ 2. Exactly one candidate → default to `prd` (that PRD).
29
+ 3. Zero candidates (no PRD exists, or every PRD is terminal) → default to `repo`.
30
+ 4. Two or more candidates with no disambiguating signal → **ask** which PRD (or `repo`); never guess.
31
+
32
+ ### Active PRD (operational definition)
33
+
34
+ Distinguish an **active** PRD from a **historical/terminal** one deterministically and conservatively, using evidence already in the repo — in this precedence:
35
+
36
+ 1. **Explicit target** — a PRD named in the request or passed as `{{PRD_PATH}}`. Wins outright.
37
+ 2. **Active session** — the PRD referenced by `.dw/STATE.md` (the current working spec), when present.
38
+ 3. **Current branch** — a `feat/prd-<slug>` checkout points at `prd-<slug>`.
39
+
40
+ A PRD directory is **terminal/historical** (excluded from candidates) when its `prd.md` frontmatter/status marks it shipped, merged, delivered, done, archived, superseded, or cancelled. When none of signals 1–3 disambiguate and more than one non-terminal PRD remains, **ask** — do not guess. This reads only what the repo already records; it never invents state, a status field, or a migration.
41
+
42
+ Numbering (`NNN`) is sequential **within the chosen scope's** ADR directory — repo ADRs and per-PRD ADRs have independent counters.
43
+
15
44
  ## Input Variables
16
45
 
17
46
  | Variable | Description | Example |
18
47
  |----------|-------------|---------|
19
- | `{{PRD_PATH}}` | Path to the active PRD folder | `.dw/spec/prd-my-feature` |
48
+ | `{{SCOPE}}` | `repo` or `prd` (optional; resolved by default rules above) | `repo` |
49
+ | `{{PRD_PATH}}` | Path to the active PRD folder (only for `scope=prd`) | `.dw/spec/prd-my-feature` |
20
50
  | `{{TITLE}}` | Short imperative title of the decision | "Use PostgreSQL instead of MongoDB" |
21
51
 
22
- If `{{PRD_PATH}}` is not provided, ask the user which PRD is active (read `.dw/spec/` and list). If `{{TITLE}}` is not provided, ask.
52
+ If `{{SCOPE}}` is not provided, resolve it per the Scope section (unique PRD → `prd`; no PRD → `repo`; multiple PRDs → ask). For `scope=prd`, if `{{PRD_PATH}}` is not provided, ask the user which PRD is active (read `.dw/spec/` and list). If `{{TITLE}}` is not provided, ask.
23
53
 
24
54
  ## File Locations
25
55
 
26
- - ADR directory: `{{PRD_PATH}}/adrs/`
27
- - New file: `{{PRD_PATH}}/adrs/adr-NNN.md` (NNN zero-padded to 3 digits)
56
+ - **`scope=repo`** → directory `.dw/adrs/`, new file `.dw/adrs/adr-NNN.md`.
57
+ - **`scope=prd`** → directory `{{PRD_PATH}}/adrs/`, new file `{{PRD_PATH}}/adrs/adr-NNN.md`.
58
+ - NNN zero-padded to 3 digits, sequential within the chosen scope's directory.
28
59
  - Template: `.dw/templates/adr-template.md`
29
60
 
30
61
  ## Workflow
31
62
 
63
+ ### 0. Resolve scope
64
+ - Determine `scope` from `--scope=` or the default resolution (unique active PRD → `prd`; no PRD → `repo`; ambiguous multiple PRDs → ask). Set the target ADR directory accordingly (`.dw/adrs/` for repo, `{{PRD_PATH}}/adrs/` for prd).
65
+ - Confirm the three-criterion gate holds (hard to reverse + surprising + genuine trade-off) and get explicit user approval before writing.
66
+
32
67
  ### 1. Discover the next number
33
- - List files in `{{PRD_PATH}}/adrs/` (create the directory if missing)
68
+ - List files in the target ADR directory (create it if missing)
34
69
  - Next number is `max(existing) + 1`, or `1` if empty
35
70
 
36
71
  ### 2. Gather context (minimum questions)
@@ -52,8 +87,9 @@ id: NNN
52
87
  status: Proposed | Accepted | Deprecated | Superseded
53
88
  title: [ADR title]
54
89
  date: YYYY-MM-DD
55
- prd: [PRD slug]
56
- schema_version: "1.0"
90
+ scope: repo | prd
91
+ prd: [PRD slug for scope=prd, or "n/a" for scope=repo]
92
+ schema_version: "1.1"
57
93
  ---
58
94
 
59
95
  # ADR-NNN: [Title]
@@ -86,11 +122,13 @@ schema_version: "1.0"
86
122
 
87
123
  ### 4. Update cross-references
88
124
 
89
- If the ADR is created **during** a PRD execution, add a line to the "Related ADRs" section of related artifacts:
125
+ If the ADR is created with **`scope=prd`** (during a PRD execution), add a line to the "Related ADRs" section of related artifacts:
90
126
  - `prd.md`, `techspec.md`, or `[N]_task.md`, matching the decision's scope
91
127
 
92
128
  If the "Related ADRs" section does not exist in the file, add it at the end.
93
129
 
130
+ For **`scope=repo`** ADRs there is no owning PRD — set `prd: n/a` in the frontmatter and link related artifacts only when they genuinely apply (e.g. `.dw/constitution.md`, `.dw/rules/`). Repo ADRs are the natural home for decisions taken during a greenfield Grill session before any PRD exists.
131
+
94
132
  ### 5. Report
95
133
 
96
134
  Present to the user:
@@ -110,7 +148,7 @@ This command is inspired by the ADR pattern in `/tmp/compozy/.agents/skills/cy-c
110
148
 
111
149
  - Paths are `.dw/spec/<prd>/adrs/` instead of `.compozy/tasks/<name>/adrs/`
112
150
  - 4 minimum questions instead of Compozy's longer interactive flow (aligned with the concise style of other dw-* commands)
113
- - Explicit integration with `schema_version` of v1.0 templates
151
+ - Explicit integration with `schema_version` v1.1 templates (adds `scope`; the PRD link is conditional so repo-scoped ADRs are coherent)
114
152
 
115
153
  Credit: Compozy project.
116
154
 
@@ -32,6 +32,7 @@ The rules generated by this command are consumed by:
32
32
  <critical>This command ONLY generates documentation. Do NOT modify any project source code.</critical>
33
33
  <critical>Read actual source files to verify patterns — do not guess from file names alone.</critical>
34
34
  <critical>Include real code examples from the project in the generated rules.</critical>
35
+ <critical>PRESERVE the Grill flow's domain artifacts. `.dw/domain/**` (glossary / context-map / per-context files) is human-curated canonical vocabulary owned by `/dw-brainstorm` grill — this command must NEVER regenerate, merge, or overwrite it. When `.dw/domain/**` exists, READ it and LINK it from `.dw/rules/index.md`; do not copy its terms into the auto-generated `.dw/rules/` files. This command owns `.dw/rules/**`; the Grill flow owns `.dw/domain/**`.</critical>
35
36
 
36
37
  ## Objective
37
38
 
@@ -225,6 +226,10 @@ For each module/project detected, identify:
225
226
  | **Auth** | NextAuth, Passport, Keycloak, Auth0, etc. | Dependencies + auth-related files |
226
227
  | **API Style** | REST, GraphQL, tRPC, gRPC | Route definitions, schema files |
227
228
 
229
+ #### Curated baseline (rules-library)
230
+
231
+ After detecting the stack(s), consult `.dw/config/stack-mappings.json`: each matched stack points to its curated baseline in `.dw/rules-library/` (`common.md` + `<stack>.md`) — the declarative "what good code looks like here" default. **Reference** these files (do NOT copy them into `.dw/rules/`): the analytical rules you write describe what the code IS; the library describes what it SHOULD be. Load only the matched stacks' files to protect the context budget.
232
+
228
233
  #### Frontend Health Baseline
229
234
 
230
235
  When React is detected, run `npx react-doctor@latest --verbose` and include the health score in the generated rules as a baseline metric.
@@ -494,8 +499,11 @@ workspace-root/
494
499
 
495
500
  - See [{module}]({module}.md) for detailed rules per module
496
501
  - See [integrations.md](integrations.md) for inter-project communication (if monorepo)
502
+ - See [domain glossary](../domain/glossary.md) — or [context map](../domain/context-map.md) — for canonical vocabulary (only when `.dw/domain/` exists; owned by Grill, read-only here, never regenerated)
497
503
  ```
498
504
 
505
+ > When `.dw/domain/**` exists, add the Domain Vocabulary link(s) above to the generated `index.md` and leave the domain files untouched. When it does not exist, omit the link — this command never creates `.dw/domain/**` (only `/dw-brainstorm` grill does, after explicit authorization).
506
+
499
507
  #### 7.2 `.dw/rules/{module}.md` (per module)
500
508
 
501
509
  ```markdown
@@ -740,7 +748,7 @@ Three options:
740
748
 
741
749
  **Option A — Synthesize:**
742
750
 
743
- 1. Read `.dw/rules/index.md` + each `.dw/rules/{module}.md`.
751
+ 1. Read `.dw/rules/index.md` + each `.dw/rules/{module}.md`, plus the curated baseline for the detected stack(s) in `.dw/rules-library/` (`common.md` + `<stack>.md`). A baseline principle the project already follows is a well-grounded proposal — cite the rules-library file as its evidence.
744
752
  2. Propose 5–8 principles. Each must:
745
753
  - Have a unique `P-NNN` ID.
746
754
  - Map to an observation in `.dw/rules/` (cite the rule file + section).
@@ -873,6 +881,7 @@ Before declaring the analysis complete, verify:
873
881
  - [ ] Step 9 (concerns map) presented candidates, awaited approval, wrote `.dw/rules/concerns.md` (or noted no signals)
874
882
  - [ ] Step 10 (design authority) ran for frontend projects: existing authority respected, or `DESIGN.md` generated from real tokens, or curated-defaults bootstrap recommended
875
883
  - [ ] Preserved-marker blocks in concerns.md kept verbatim on refresh
884
+ - [ ] `.dw/domain/**` (glossary / context-map) preserved verbatim and linked from index.md when present — never regenerated or overwritten
876
885
  - [ ] Topology analysis completed (god nodes, coupling metrics, dependency graph)
877
886
  - [ ] Critical nodes table generated with Ca, Ce, instability
878
887
  - [ ] Circular dependencies identified and documented