@thedecipherist/mdd 1.8.1 → 1.8.2

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.
@@ -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.2",
4
4
  "description": "MDD — Manual-Driven Development workflow for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {