From sdd
Performs fast drift checks on code files, directories, ADRs, or specs to detect misalignment with governing architecture decisions and specifications.
npx claudepluginhub joestump/claude-plugin-sdd --plugin sddThis skill uses the workspace's default tool permissions.
You are performing a fast, focused drift check on a specific target. This skill detects whether code aligns with its governing ADRs and specs.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Guides code writing, review, and refactoring with Karpathy-inspired rules to avoid overcomplication, ensure simplicity, surgical changes, and verifiable success criteria.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Share bugs, ideas, or general feedback.
You are performing a fast, focused drift check on a specific target. This skill detects whether code aligns with its governing ADRs and specs.
Resolve artifact paths: Follow the Artifact Path Resolution pattern from references/shared-patterns.md to determine the ADR and spec directories. If $ARGUMENTS contains --module <name>, resolve paths relative to that module; otherwise, in a workspace, aggregate across all modules. The resolved ADR directory is {adr-dir} and spec directory is {spec-dir}.
Cross-module aggregation: When in aggregate mode (no --module, workspace detected), check all modules and group findings by module in the output. Add a Module column to the findings table and organize findings under per-module subheadings. When --module is provided, check only that module — no module labels needed. When in single-module mode (no workspace), operate normally.
Parse the target: Extract the target from $ARGUMENTS.
src/auth/login.tssrc/auth/ADR-0001SPEC-0001$ARGUMENTS is empty, check all artifacts against the entire codebase.Validate the target exists:
{target}. Provide a valid file path, directory, ADR reference (ADR-XXXX), or SPEC reference (SPEC-XXXX)."{adr-dir}/ADR-{number}-*.md. If not found, report: "ADR-{XXXX} not found in {adr-dir}. Run /sdd:list adr to see available ADRs."{spec-dir}/*/spec.md and search for the matching SPEC number. If not found, report: "SPEC-{XXXX} not found in {spec-dir}. Run /sdd:list spec to see available specs."Locate design artifacts:
{adr-dir} for ADR files. If the directory does not exist, report: "The {adr-dir} directory does not exist. Run /sdd:adr [description] to create your first ADR."{spec-dir} for spec files. If the directory does not exist, report: "The {spec-dir} directory does not exist. Run /sdd:spec [capability] to create your first spec."/sdd:adr or a spec with /sdd:spec first."3a. Tier 3 staleness check (v5.0.0+):
On entry, check the qmd index's last-modified timestamp for this repo's collections (use the exact-prefix match algorithm from references/qmd-helpers.md § "This-Repo Collection Identification" to identify them, then take the maximum lastUpdated across them). If that timestamp is older than the configured staleness threshold, run a silent qmd update first.
The threshold default is 120 minutes and is configurable in CLAUDE.md ### SDD Configuration #### Index Freshness **Staleness Threshold** (e.g., 30m, 4h). Read it via the Config Resolution pattern in references/shared-patterns.md.
On stale → update path, emit a one-line note in the report header: Index was {age} stale — refreshed before running. On fresh, proceed silently. On qmd update failure, surface the error per references/qmd-helpers.md § "Error Handling" and continue (best-effort; the check still runs against the existing index).
Determine relevant artifacts:
Use qmd hybrid retrieval to identify the top-K candidate ADRs and specs governing the target before reading any artifact in full. The pre-v5 "read all ADRs and specs to find which ones govern the target" path is removed in v5.0.0 — qmd retrieval is the canonical mechanism.
If the target is a file or directory: construct a hybrid query per references/qmd-helpers.md § "Hybrid Retrieval" derived from the target's content. The query SHOULD include:
lex: the file path basename, exported symbol names from a quick scan, and any Governing: comment block content (if present)vec: a one-sentence summary of what the target file/dir does (e.g., for src/auth/login.go → "user authentication via JWT-based session login flow")intent: "/sdd:check {target} — find ADRs and specs governing this code"Filter to collections: ["{repo}-adrs", "{repo}-specs"] (or per-module variants in workspace mode). Set limit: 8 and minScore: 0.3. Read the top-K candidates in full before evaluating drift.
If the target is an ADR (ADR-XXXX): read the ADR directly. Then qmd-search {repo}-specs for related specs (those that implement or reference the ADR) and {repo}-code for code that should implement the decision. Same query structure as the file/dir case, with the ADR's title and decision as the vec query.
If the target is a SPEC (SPEC-XXXX): read the spec directly. Then qmd-search {repo}-adrs for governing ADRs and {repo}-code for implementing files. Same pattern.
On qmd unreachable / timeout per qmd-helpers.md § "Error Handling", surface the error and stop. Per ADR-0024 and SPEC-0019 REQ "qmd Assumption in Consumer Skills", fallback paths were eliminated in v5; the failure mode is "fix qmd, retry" not "scan the entire corpus."
Validate spec artifact pairing: For each spec directory found under {spec-dir}, check that both spec.md and design.md exist. If a spec.md exists without a corresponding design.md (or vice versa), report as [WARNING] under "Code vs. Spec" with finding: "Unpaired spec artifact: {path} exists but {missing-file} is missing. Per ADR-0003, spec.md and design.md are a paired unit." (Governing: ADR-0003, SPEC-0003)
Security lint scan: Scan source code files in the target for dangerous patterns that indicate security risks. Use text-based pattern matching (Grep tool with regex), NOT AST analysis. False positives are acceptable — flag patterns for human review.
For each pattern below, search applicable source files and report any matches as findings in the output table. All security lint findings use category Security Lint and severity [WARNING].
Pattern 1 — Unbounded body read: Reading an HTTP request body without enforcing a size limit allows a single request to allocate arbitrary memory.
io.ReadAll(r.Body) or ioutil.ReadAll(r.Body) without http.MaxBytesReader wrapping the body in the same function or file.req.on('data' accumulating chunks without a size check, or body-parser / express.json without a limit option.request.body or request.data without DATA_UPLOAD_MAX_MEMORY_SIZE or equivalent framework-level limit.http.MaxBytesReader in Go, { limit: '1mb' } in Express, DATA_UPLOAD_MAX_MEMORY_SIZE in Django) before reading."Pattern 2 — Template safety bypass: Disabling template auto-escaping injects raw HTML into rendered output, enabling XSS.
template.HTML( casting user-supplied or unsanitized content.dangerouslySetInnerHTML usage.|safe filter or {% autoescape false %} in Jinja/Django templates.Pattern 3 — User-controlled redirect: HTTP redirects where the target URL comes from request parameters allow open redirect attacks.
http.Redirect( where the URL argument references r.URL.Query(), r.FormValue, or r.PostFormValue.res.redirect(req.query or res.redirect(req.body or res.redirect(req.params.redirect(request.GET[ or redirect(request.POST[ or HttpResponseRedirect(request.GET[.Pattern 4 — Missing auth middleware: Route or endpoint registration without authentication middleware in the handler chain leaves the endpoint publicly accessible.
http.HandleFunc( or router.GET( / router.POST( / mux.Handle( where the handler chain does not reference an auth middleware function in the same registration block.app.get( / app.post( / router.get( / router.post( without an auth or authenticate or requireAuth middleware in the argument list.@login_required, @permission_required, or equivalent auth decorator.// Public: [justification]."Pattern 5 — DOM injection: Assigning to innerHTML bypasses DOM sanitization and is a common XSS vector.
.innerHTML = or .innerHTML += assignments in JavaScript files or inline <script> blocks.textContent for text content or use a DOM sanitization library (e.g., DOMPurify) before assigning to innerHTML."Pattern 6 — CDN without SRI: Loading external scripts or stylesheets without Subresource Integrity attributes allows compromised CDNs to inject malicious code.
<script src="https:// or <script src="http:// without an integrity attribute on the same tag. Also <link href="https:// or <link href="http:// with rel="stylesheet" without an integrity attribute.integrity and crossorigin attributes to all CDN-loaded <script> and <link> tags. Generate SRI hashes with shasum or an online SRI hash generator."Each finding MUST include: the file path with line number in the Location column, the matched pattern in the Finding column, and the remediation suggestion. Report findings even if they may be false positives — the goal is to flag patterns for human review.
Template quality scan: Scan HTML templates, JavaScript files, and frontend assets in the target for template quality patterns. Use text-based pattern matching (Grep tool) to detect the following 5 patterns. All template quality findings use category Template Quality.
Pattern 1 — Duplicate inline <script> blocks (Severity: [WARNING]): Identical or near-identical <script> blocks appearing in the same file or across multiple template files indicate code duplication.
<script> blocks (not <script src=). Compare content of inline script blocks within the same file and across template files. Flag when the same block (or substantially similar content) appears more than once.Pattern 2 — Duplicate form structure (Severity: [INFO]): The same form structure (same action, same field names) appearing in multiple template files signals a refactoring opportunity.
<form tags across template files. Compare form action attributes and field name attributes. Flag when two or more templates contain forms with the same structure.Pattern 3 — Duplicate navigation/sidebar (Severity: [WARNING]): Navigation or sidebar markup rendered in multiple templates without using a shared partial creates layout inconsistency risk.
<nav elements or elements with role="navigation" across template files. Flag when navigation markup appears in more than one template file without evidence of a shared partial/include (e.g., Go {{ template "nav" }}, Jinja {% include "nav.html" %}, EJS <%- include('nav') %>).Pattern 4 — Dev-only CDN URLs (Severity: [WARNING]): CDN URLs intended only for development (such as cdn.tailwindcss.com) should not appear in production templates.
<script or <link tags referencing known dev-only CDN URLs: cdn.tailwindcss.com, unpkg.com (when used for production), or any CDN URL containing /dev/ or /debug/ in the path.[url]. Replace with a production build (bundler, CLI tool, or self-hosted asset)."Pattern 5 — Multiple JS interaction frameworks (Severity: [INFO]): Loading more than one JS interaction framework (e.g., HTMX + Alpine.js + Hyperscript, or React + jQuery) signals framework sprawl and a missing architectural decision.
htmx.org, hx-get, hx-post, hx-swap), Alpine.js (alpinejs, x-data, x-bind), Hyperscript (hyperscript.org, _="on), React (react., ReactDOM, jsx), jQuery (jquery, $(document), $(function), Vue (vue.js, v-bind, v-model), Stimulus (stimulus, data-controller). Flag when more than one distinct framework is detected.Each finding MUST include the affected file paths in the Location column and the remediation suggestion.
Analyze for drift across three categories:
Code vs. Spec: Does the implementation match the spec's requirements and scenarios?
[CRITICAL][WARNING][WARNING]Code vs. ADR: Does the implementation follow the accepted ADR decisions?
[CRITICAL][WARNING]ADR vs. Spec: Are the ADR decisions consistent with spec requirements?
[CRITICAL][WARNING]Produce the findings table using the standard format:
## Drift Check: {target}
Checked {N} ADRs and {M} specs against {target}. Found {X} findings.
### Findings
| Severity | Category | Finding | Source | Location |
|----------|----------|---------|--------|----------|
| [CRITICAL] | Code vs. Spec | {one-sentence description} | SPEC-XXXX | src/path/file.ts:NN |
| [WARNING] | Code vs. ADR | {one-sentence description} | ADR-XXXX | src/path/file.ts:NN |
| [WARNING] | Security Lint | {pattern name}: {matched code}. {remediation} | ADR-0018 | src/path/file.go:NN |
| [WARNING] | Template Quality | {pattern name}: {description}. {remediation} | ADR-0019 | templates/page.html:NN |
### Summary
- Critical: {N}
- Warning: {N}
- Info: {N}
Add suggested actions at the end based on findings:
/sdd:audit {target} --review for deeper analysis/sdd:status to update/sdd:spec## Drift Check: {target}
Checked {N} ADRs and {M} specs against {target}. No drift detected.
All implementation in {target} aligns with governing ADRs and specs.
## Drift Check: {target}
Checked {N} ADRs and {M} specs across {K} modules against {target}. Found {X} findings.
### [api] Findings
| Severity | Category | Finding | Source | Location |
|----------|----------|---------|--------|----------|
| [CRITICAL] | Code vs. Spec | {description} | SPEC-XXXX | services/api/src/file.ts:NN |
### [worker] Findings
| Severity | Category | Finding | Source | Location |
|----------|----------|---------|--------|----------|
| [WARNING] | Code vs. ADR | {description} | ADR-XXXX | services/worker/src/file.ts:NN |
### Summary
| Module | Critical | Warning | Info | Total |
|--------|----------|---------|------|-------|
| [api] | N | N | N | N |
| [worker] | N | N | N | N |
| **Total** | **N** | **N** | **N** | **N** |
If a module has no findings, omit its section and show "No drift detected" in the summary row.
[CRITICAL][WARNING][INFO][WARNING][CRITICAL][WARNING] (false positives are acceptable — flag for human review)[WARNING], duplicate forms and framework sprawl are [INFO], dev-only CDN is [WARNING]--review./sdd:audit for a comprehensive six-category analysis.ADR-0001, SPEC-0002, Req 3. Do not abbreviate.src/auth/login.ts:45).## for the top-level heading (report title) and ### for sections within the report.--module is provided, check only that module — do not scan other modules### SDD Configuration #### Index Freshness **Staleness Threshold**), trigger silent qmd update and emit a one-line note. On fresh, proceed silently (Governing: ADR-0026, SPEC-0019 REQ "Tier 3 Staleness Threshold for Consumer Skills")references/qmd-helpers.md to identify top-K candidate ADRs/specs; deep-read only those candidates. The pre-v5 read-everything-then-filter path is removed — qmd retrieval is the canonical mechanism (Governing: ADR-0024, SPEC-0019 REQ "qmd-Smart Drift Skills")