Skip to content

feat: SDD Compliance Dashboard — 7-layer spec scanner#87

Merged
djimit merged 1 commit into
mainfrom
feat/sdd-compliance-dashboard
Jul 23, 2026
Merged

feat: SDD Compliance Dashboard — 7-layer spec scanner#87
djimit merged 1 commit into
mainfrom
feat/sdd-compliance-dashboard

Conversation

@djimit

@djimit djimit commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

Implements a real feature using the SDD v1.1.0 (Spec-Driven Development) workflow to validate the end-to-end specification-driven development pipeline.

What's New

Server

  • SpecComplianceService (packages/server/src/services/spec-compliance-service.ts): Evaluates feature specs against the 7 information layers from Constitution v1.1.0
  • GET /api/compliance/specs: Scans specs/ directory, returns compliance report with per-spec scores

Dashboard

  • SpecComplianceWidget (packages/dashboard/src/components/SpecComplianceWidget.tsx):
    • Summary metrics (total, full, partial, non-compliant)
    • Per-spec score with color-coded layer indicators
    • Expandable detail view: click a spec to see layer-by-layer breakdown
    • Missing layers highlighted with action-required hints
    • Lifecycle state badge per spec
  • Integrated into DashboardPage: Visible on main dashboard

Tests

  • 6/6 service tests passing (layer detection, scoring, reports)
  • 19/19 total tests passing (E2E + telegram + compliance)

Constitution Compliance

All 7 information layers enforced:

  • L1: Language Precision (FR-### SHALL-format)
  • L2: Negative Requirements (Non-Goals)
  • L3: Measurable Criteria (SC-### with number + unit)
  • L4: Hard Constraints (Allowed/Forbidden tech)
  • L5: Codebase Anchoring (FR to file path mapping)
  • L6: Edge Cases (EC-### IF-THEN)
  • L7: Verified Library Specs (Library + version)

Validation

  • Type-check: 0 errors across all workspaces
  • Tests: 19/19 passing
  • Build: clean

Implements a real feature using the SDD v11.0 workflow to validate the
end-to-end specification-driven development pipeline.

Server:
- SpecComplianceService: evaluates specs against 7 information layers
- GET /api/compliance/specs: scans specs/ directory, returns compliance report
- Constitution v1.1.0 Specification Quality Gates enforced

Dashboard:
- SpecComplianceWidget: shows per-spec compliance scores (0-7 layers)
- Integrated into DashboardPage
- Real-time refresh, layer-level detail

Tests:
- 6/6 service tests passing (layer detection, scoring, reports)
- 19/19 total tests passing (E2E + telegram + compliance)

Type-check: 0 errors across all workspaces
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@kilo-code-bot

kilo-code-bot Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Kilo Code Review could not run — your account is out of credits.

Add credits or switch to a free model to enable reviews on this change.

Comment on lines +62 to +91
router.get('/specs', requirePermission('read:evidence'), (_req, res) => {
try {
const fs = require('fs');
const path = require('path');
const specsDir = path.resolve(process.cwd(), 'specs');
const archiveDir = path.resolve(process.cwd(), 'specs/archive');

const specs: Array<{ name: string; path: string; content: string }> = [];

// Scan specs/ directory
for (const dir of [specsDir, archiveDir]) {
if (!fs.existsSync(dir)) continue;
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const specFile = path.join(dir, entry.name, 'spec.md');
if (fs.existsSync(specFile)) {
const content = fs.readFileSync(specFile, 'utf-8');
specs.push({ name: entry.name, path: specFile, content });
}
}
}
}

const report = generateComplianceReport(specs);
res.json(report);
} catch (error) {
res.status(500).json({ error: { message: 'Failed to scan specs', details: error instanceof Error ? error.message : String(error) } });
}
});

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8dbeeae05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

setLoading(true);
setError(null);
try {
const res = await fetch('/api/compliance/specs');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use the authenticated API client for compliance fetches

On the protected dashboard, this direct fetch does not attach the stored Bearer token, while /api/compliance/specs is mounted behind requireAuth and then requirePermission('read:evidence'); in a normal token-authenticated session the widget will receive 401 and only render Error: HTTP 401. Route this through the existing API client or otherwise add the Authorization header so the auth boundary is preserved. .github/copilot-instructions.mdL62-L62

Useful? React with 👍 / 👎.

Comment on lines +66 to +67
const specsDir = path.resolve(process.cwd(), 'specs');
const archiveDir = path.resolve(process.cwd(), 'specs/archive');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve specs from the monorepo root

When the server is started through the documented workspace command (npm run dev:server), npm runs it with process.cwd() set to packages/server, so these paths resolve to packages/server/specs and packages/server/specs/archive; the repo's actual specs/ directory is then skipped and the endpoint reports zero specs. Resolve from the monorepo root/INIT_CWD (or a shared helper such as the existing root resolution used elsewhere) before appending specs. .github/copilot-instructions.mdL15-L15

Useful? React with 👍 / 👎.

Comment on lines +44 to +47
{ id: 'L4', name: 'Hard Constraints', pattern: /## Hard Constraints/ },
{ id: 'L5', name: 'Codebase Anchoring', pattern: /## Codebase Anchoring/ },
{ id: 'L6', name: 'Edge Cases', pattern: /EC-\d{3}.*IF.*THEN/ },
{ id: 'L7', name: 'Verified Library Specs', pattern: /## Verified Library Specs/ },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate L4-L7 contents instead of headings

For specs that contain the SDD headings but leave the required evidence empty, these regexes still set the layers to present; for example ## Codebase Anchoring passes without any FR-to-file mapping and ## Verified Library Specs passes without a library/version row. That can mark incomplete specs as fully compliant, so key these layers off the required contents (Allowed/Forbidden entries, FR path mappings, and library+version rows) rather than headings alone.

Useful? React with 👍 / 👎.

@djimit
djimit merged commit 20bdb29 into main Jul 23, 2026
5 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants