Skip to content

feat(docs): design doc + implementation plan convention with CI check (closes #67 phase-1)#155

Merged
Wolfvin merged 1 commit into
mainfrom
feat/issue-67-design-doc-convention
Jul 3, 2026
Merged

feat(docs): design doc + implementation plan convention with CI check (closes #67 phase-1)#155
Wolfvin merged 1 commit into
mainfrom
feat/issue-67-design-doc-convention

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Closes #67 (phase-1)

Summary

Implements Phase 1 of issue #67 — Design doc + implementation plan convention. Establishes docs/design/ + docs/plans/ with templates, backfills design docs for 4 existing features, adds a GitHub Action CI check that requires a design doc on new-feature PRs, and updates CONTRIBUTING.md with the new requirement.

Phase 2 (VitePress homepage) and Phase 3 (live demo) are out of scope — they need external tooling and multi-week content work.

What changed

New files (11)

Templates + guide:

  • docs/README.md — index + "when do I need a design doc?" guide
  • docs/design/template.md — Problem/Goal/Changes/Trade-offs/Open Questions/Migration
  • docs/plans/template.md — phase-based implementation checklist

Retroactive design docs (4 — exceeds the "3+" acceptance criterion):

CI check:

  • scripts/check_design_doc.py — pure-logic check_pr() + CLI entry (356 lines)
  • .github/workflows/design-doc-check.yml — GitHub Action workflow
  • tests/test_design_doc_check.py — 48 tests (399 lines)

Modified files (1)

  • CONTRIBUTING.md — add "Design Doc Requirement" section to PR process (49 lines added)

How the CI check works

Feature detection (file pattern + status)

Pattern Status Triggers design doc requirement?
scripts/commands/*.py added Yes (new CLI command)
scripts/*_engine.py added Yes (new analysis engine)
scripts/formatters/*.py added Yes (new output format)
scripts/parsers/*_parser.py added Yes (new language parser)
scripts/parsers/fallback_*.py added No (regex shadow of existing parser)
Any existing file modified No (bug fix / refactor)
tests/*.py added No (test addition)
*.md any No (documentation)

Bypass mechanism

PRs with the skip-design-doc label bypass the check entirely. This is for genuinely trivial features (e.g., a one-line command alias) where a design doc would be pure overhead. The bypass is intentionally a label (not a commit message flag) so it's visible in the PR UI and reviewable by BOS.

Architecture

The check is split into two layers:

  1. Pure logic (check_pr(pr_files, pr_labels) -> dict) — no I/O, no API calls, unit-testable. Takes the PR's files and labels and returns {passed, reason, feature_files, design_docs, bypassed}.
  2. CLI entry (main()) — handles two modes: CI mode (reads GITHUB_TOKEN/GITHUB_REPOSITORY/PR_NUMBER env vars, fetches PR data via GitHub API) and local mode (--files/--status/--labels args for testing).

This split means the logic is fully testable without mocking the GitHub API.

Acceptance criteria (from issue body)

  • Phase 1: docs/design/ and docs/plans/ directories exist with templates — created docs/design/template.md and docs/plans/template.md
  • Phase 1: CI check fails PR without design doc for new feature — verified via test_check_pr_feature_without_design_doc_fails and end-to-end local-mode test (exit code 1)
  • Phase 1: 3+ existing features backfilled with design docs — 4 design docs created (taint engine, MCP server, plugin system, graph model)

Tests

  • New: 48 passed in tests/test_design_doc_check.py
    • TestIsFeatureFile (15 tests) — classifier unit tests
    • TestCheckPrNoFeatureFiles (5 tests) — bug fix / test-only / doc-only PRs pass
    • TestCheckPrFeatureWithoutDesignDoc (6 tests) — feature PRs without docs fail with helpful message
    • TestCheckPrFeatureWithDesignDoc (5 tests) — feature PRs with docs pass
    • TestCheckPrBypass (4 tests) — skip-design-doc label bypasses
    • TestEdgeCases (6 tests) — missing keys, mixed PRs, wrong-directory docs, plan-doc-doesn't-satisfy-design
    • TestCliEntryPoint (7 tests) — subprocess tests for CLI arg parsing + env-var handling
  • Regression check: test_formatters + test_cli + test_command_count + test_command_registry → 97 passed, 0 failed (no regressions)

End-to-end verification (local mode)

$ python3 scripts/check_design_doc.py --files scripts/commands/scan.py --status modified
[design-doc-check] PASS
[design-doc-check] PR does not add new feature files...
exit=0

$ python3 scripts/check_design_doc.py --files scripts/commands/newcmd.py --status added
[design-doc-check] FAIL
[design-doc-check] PR adds new feature file(s) (scripts/commands/newcmd.py) but does not include a design doc in docs/design/...
exit=1

$ python3 scripts/check_design_doc.py --files scripts/commands/newcmd.py docs/design/0005-newcmd.md --status added added
[design-doc-check] PASS
[design-doc-check] PR adds feature file(s) and includes design doc(s): docs/design/0005-newcmd.md.
exit=0

$ python3 scripts/check_design_doc.py --files scripts/commands/newcmd.py --status added --labels skip-design-doc
[design-doc-check] PASS
[design-doc-check] PR has 'skip-design-doc' label — design doc requirement bypassed.
exit=0

Design decisions

  1. Pure-logic / I/O split — The check logic (check_pr()) is a pure function that takes data and returns a result. The CLI entry handles all I/O (GitHub API, env vars, arg parsing). This makes the logic fully unit-testable without mocking. KISS — no mock framework needed.

  2. Label-based bypass, not commit-message bypass — A PR label is visible in the GitHub UI, reviewable by BOS, and doesn't pollute git history. A commit message flag ([skip-design-doc]) would be permanent in git history even if the bypass was later deemed inappropriate.

  3. Require design doc, recommend plan — The issue says "design + plan" but the acceptance criteria only mention "design doc". Pragmatically, the design doc captures the "why" (most important for future contributors); the plan captures the "how" (often in the PR description anyway). The plan template is provided as a tool for contributors who want it, but not enforced.

  4. File-pattern detection, not semantic detection — Detecting "is this a new feature?" by file pattern (new file in scripts/commands/) is robust and simple. Semantic detection (parsing the diff to see if a new MCP tool was added to mcp_server.py) would be fragile and complex. The trade-off: modifications to mcp_server.py that add a new tool won't trigger the check. Contributors adding a new MCP tool should add a design doc voluntarily; the CI check doesn't enforce it for in-place modifications.

  5. Retroactive design docs based on actual code — The 4 backfilled design docs (0001-0004) are written based on the actual engine source code and the CONTEXT.md snapshot. They document the design decisions that were already made, including the alternatives that were rejected. This is the "Open Questions" section's value — it records what's NOT yet decided.

  6. ADR-style numberingNNNN-feature-name.md (zero-padded to 4 digits) is the industry standard (Michael Nygard's ADR template). Ensures sort stability and easy referencing ("see design doc 0003").

  7. No external dependencies — The check script uses only stdlib (urllib, json, argparse). No requests, no PyGithub. KISS — the GitHub API is simple enough for urllib.

Findings (per pre-flight SKILL.md — outside scope, BOS decides)

  • The docs/ directory did not exist in the repo before this PR. The sparse-checkout set included docs but it was a no-op. This PR creates the directory structure.
  • The references/ directory exists with 6 files (agent-integration.md, changelog.md, parser-rules.md, query-examples.md, rule-schema.json, status-codes.md). These are reference docs, not design docs — they document "how to use" rather than "why it was designed this way". The new docs/design/ directory is complementary, not overlapping.
  • The existing CONTRIBUTING.md already had a detailed PR process section but no design doc requirement. The new section is additive — it inserts "Add a design doc" as step 2 and adds a subsection explaining the requirement.

Branch

feat/issue-67-design-doc-convention

…closes #67 phase-1)

Establishes docs/design/ + docs/plans/ convention with templates, 4
retroactive design docs for existing features, a GitHub Action CI check
that requires a design doc on new-feature PRs, and CONTRIBUTING.md
guidance.

New files:
- docs/README.md — index + 'when do I need a design doc?' guide
- docs/design/template.md — Problem/Goal/Changes/Trade-offs/Open Questions
- docs/design/0001-taint-engine.md — retroactive design doc
- docs/design/0002-mcp-server.md — retroactive design doc
- docs/design/0003-plugin-system.md — retroactive design doc
- docs/design/0004-graph-model.md — retroactive design doc
- docs/plans/template.md — phase-based implementation checklist
- scripts/check_design_doc.py — CI check logic (pure + CLI entry)
- .github/workflows/design-doc-check.yml — GitHub Action
- tests/test_design_doc_check.py — 48 tests

Modified:
- CONTRIBUTING.md — add 'Design Doc Requirement' section to PR process

CI check logic:
- Detects 'new feature' PRs by file pattern:
  - New file in scripts/commands/ (new CLI command)
  - New scripts/*_engine.py (new analysis engine)
  - New file in scripts/formatters/ (new output format)
  - New parser in scripts/parsers/ (excluding fallback_*.py)
- Requires a design doc (.md) in docs/design/ added/modified in the PR
- Bypassable via 'skip-design-doc' PR label for trivial features
- Pure-logic check_pr() is unit-testable; CLI entry handles GitHub API I/O

Verified:
- 48 new tests pass (test_design_doc_check.py)
- 145 passed total (test_design_doc_check + test_formatters + test_cli +
  test_command_count + test_command_registry — no regressions)
- End-to-end local-mode: bug fix PASSes, new command without doc FAILs,
  new command with doc PASSes, bypass label PASSes
- Workflow YAML syntax validated

Phase 2 (VitePress homepage) and Phase 3 (live demo) are out of scope —
they need external tooling and multi-week content work.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

sonarqubecloud Bot commented Jul 2, 2026

Copy link
Copy Markdown

@Wolfvin Wolfvin merged commit 1bb11e6 into main Jul 3, 2026
6 of 12 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.

[FEATURE] Homepage + design doc process — VitePress site + docs/design/ + docs/plans/ convention

1 participant