@thedecipherist/mdd 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -864,6 +864,7 @@ Every `.mdd/docs/<NN>-<feature-name>.md` file uses this YAML frontmatter:
864
864
  | `tags` | 4–8 domain-concept keywords surfaced in `.startup.md` so Claude can detect when a prompt relates to this feature (e.g. `[auth, jwt, login, sessions]`) |
865
865
  | `path` | Slash-delimited breadcrumb showing where this feature lives in the product (e.g. `Auth/Login`, `E-commerce/Cart/Checkout`). Used by dashboards and listing tools to group docs into a human-readable tree. Distinct from `depends_on` — this is for navigation, not build order. |
866
866
  | `known_issues` | Issues discovered during audits or implementation |
867
+ | `security_read_sites` | Optional. List of `file:line` entries where user-supplied file paths are read. Phase A1 cross-checks each against path-confinement calls - a listed site with no guard is a P1 finding. Leave empty or omit if the feature has no file-read attack surface. |
867
868
 
868
869
  **`depends_on` rules:**
869
870
  - Feature docs only - never list task docs (one-off, frozen, no ongoing contract)
@@ -1011,7 +1012,7 @@ MDD creates `.mdd/settings.json` on first run. It controls which rule files load
1011
1012
 
1012
1013
  **`phaseLogging: true` (default)** - Controls whether MDD writes phase timing data via `mdd-log-phase.sh`. Set to `false` to suppress all phase log output.
1013
1014
 
1014
- **`securityScan: false` (default)** - Enables the security rule generator. See the section below.
1015
+ **`securityScan: false` (default)** - Set to `true` to enable the security rule generator. See the section below.
1015
1016
 
1016
1017
  ### Stack-Specific Rule Files
1017
1018
 
@@ -1022,6 +1023,7 @@ mdd-rules-typescript.md # TypeScript-specific audit criteria and build checkli
1022
1023
  mdd-rules-express.md # Express error handling, middleware, route validation rules
1023
1024
  mdd-rules-jwt.md # JWT decode safety, expiry checks, secret validation
1024
1025
  mdd-rules-prisma.md # Prisma query safety, transaction patterns, migration checks
1026
+ mdd-rules-mcp.md # MCP tool input validation and rejection test enforcement
1025
1027
  ```
1026
1028
 
1027
1029
  Rules are additive - they append criteria to the existing phase rather than replacing anything. If a rule file doesn't exist for a stack entry, MDD warns once and continues. A misconfigured or missing `settings.json` never halts a session.
@@ -53,7 +53,9 @@ These checks require comparing feature docs to each other and to disk. They cann
53
53
 
54
54
  - For each feature, verify every path in `source_files` exists on disk. Missing files = P2 finding.
55
55
  - For each feature with `depends_on` that includes a feature with `integration_contracts`: verify this feature's `satisfies_contracts` is not empty. Missing acknowledgment = P2 finding.
56
+ - For each feature with `satisfies_contracts` entries: verify that EVERY file in the feature's `source_files` that performs the contracted operation has the required guard call — not just one file per entry. A single guarded file does not satisfy a contract that covers the whole feature. Any unguarded file = P2 finding (P1 if the contract is a security contract).
56
57
  - For each feature with `satisfies_contracts` entries where `status: pending`: flag every pending entry as P1 — contract was documented but never wired.
58
+ - For each feature with `security_read_sites` present and non-empty: read each listed `file:line` and confirm the immediately surrounding code calls the canonical path-confinement function. A listed site with no confinement call = P1 finding.
57
59
  - For each feature with `integration_contracts`: verify every listed `caller_feature` exists as a feature doc. Non-existent caller referenced = P3 finding.
58
60
 
59
61
  Record all findings from this step in a dedicated `audits/doc-findings-<date>.md` file. These are merged into the final report in Phase A5 as a separate "Feature Doc Issues" section.
@@ -188,7 +190,7 @@ Integration context: .mdd/jobs/audit-<date>/integration-context.md
188
190
  - "Immutable" rule arrays exported as plain mutable arrays — not `Object.freeze()` + `readonly`
189
191
  - Untrusted MCP/API/CLI input used without validation or sanitization
190
192
  - Data cached or stored without masking applied first
191
- - Local reimplementation of security logic — any function named `isConfined`, `isAllowed`, `isSafe`, `isBlocked`, or similar that replicates what a documented security module already provides. Require replacement with the canonical security module function.
193
+ - Local reimplementation of security logic — any function named `isConfined`, `isAllowed`, `isSafe`, `isBlocked`, or similar that replicates what a documented security module already provides. Require replacement with the canonical security module function. Also check for any object-literal property or anonymous helper that performs path resolution and containment (`resolve` + `relative` + `startsWith('..')`) without delegating to the canonical security module — these are the same violation regardless of whether they are named functions.
192
194
  - Contract function undefined — if `integration_contracts` specifies a function name, grep the entire package for that name as an export. If the function does not exist anywhere, flag P1 regardless of whether call sites are present.
193
195
 
194
196
  **Note:** `satisfies_contracts status: pending` is checked by main in Phase A1, not here — agents cannot read feature docs.
@@ -107,6 +107,8 @@ Before writing anything, gather context using **3 parallel Explore agents**. Lau
107
107
 
108
108
  **After all 3 return:** synthesize into a working context in the main conversation. If any agent fails, silently fall back to direct `Read`/`Glob` for that agent's data — never surface agent failures to the user unless all 3 fail.
109
109
 
110
+ **Shared-utilities check (when Agent B returns features with `depends_on` entries):** For each dependency feature, scan its `source_files` for shared infrastructure — error types, DB clients, utility functions — that the new feature would likely duplicate. If overlap is found, surface it before asking questions: "Feature `<NN>` already has `<type/client>` in `<file>`. Extract to a shared module before implementing?" Add an extraction block to the build plan if the user agrees. This check runs here — not at Phase 6 — so duplication is caught before documentation is written.
111
+
110
112
  **Detect task type before asking questions.** If `src/` has fewer than 3 TypeScript/source files AND the feature description contains words like `workflow`, `command`, `config`, `docs`, `tooling`, `hook`, `script`, or `prompt` — mark as a **tooling task** and skip the database and API questions entirely.
111
113
 
112
114
  Then ask the user targeted questions using AskUserQuestion. Ask ALL relevant questions upfront in a single interaction — don't spread them across multiple turns:
@@ -240,6 +242,7 @@ path: <Area/Section>
240
242
  integration_contracts: []
241
243
  satisfies_contracts: []
242
244
  known_issues: []
245
+ security_read_sites: [] # optional: list file:line entries where user-supplied paths are read; Phase A1 cross-checks each against path-confinement calls
243
246
  ---
244
247
 
245
248
  # <NN> — <Feature Title>
@@ -0,0 +1,16 @@
1
+ ## MDD Rules - MCP Tools
2
+
3
+ Rules loaded when `stack.frameworks` includes `mcp`. Applied additively to audit criteria and build checklists.
4
+
5
+ ### Audit Criteria
6
+
7
+ #### P2 - Missing Input Validation
8
+ - MCP tool handler does not call `validateMcpInput` (or project-equivalent input validation function) as its first statement before any tool logic executes - P2. Unvalidated MCP input is an untrusted external boundary and must be treated the same as HTTP request body input.
9
+
10
+ #### P3 - No Malformed Input Test
11
+ - MCP tool handler has no test asserting it rejects malformed or missing input - P3. The test must verify the handler returns an error (not throws unhandled) when required fields are absent or the wrong type.
12
+
13
+ ### Build Checklist (Phase 6)
14
+
15
+ - **validateMcpInput first:** Before writing any tool logic, confirm `validateMcpInput` is imported and called as the first statement in every new tool handler. Use the existing canonical reference tool in the codebase as the template.
16
+ - **Rejection test:** For every new MCP tool, add a test that passes malformed input and asserts the handler returns a structured error response rather than throwing.
package/commands/mdd.md CHANGED
@@ -160,6 +160,7 @@ For `package.json`, scan both `dependencies` and `devDependencies` for these kno
160
160
  | `mongoose` | orm | `mongoose` |
161
161
  | `jsonwebtoken`, `jose` | auth | `jwt` |
162
162
  | `passport` | auth | `passport` |
163
+ | `@modelcontextprotocol/sdk`, `@anthropic-ai/mcp` | frameworks | `mcp` |
163
164
 
164
165
  Write detected entries back into `settings.json` under `stack` (non-destructive — only updates `stack`, never touches `overrides`, `phaseLogging`, `autoDiscovery`, or `securityScan`).
165
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thedecipherist/mdd",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "description": "MDD — Manual-Driven Development workflow for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {