@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 +3 -1
- package/commands/mdd-audit.md +3 -1
- package/commands/mdd-build.md +3 -0
- package/commands/mdd-rules-mcp.md +16 -0
- package/commands/mdd.md +1 -0
- package/package.json +1 -1
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)** -
|
|
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.
|
package/commands/mdd-audit.md
CHANGED
|
@@ -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.
|
package/commands/mdd-build.md
CHANGED
|
@@ -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
|
|