Code/Projects/ - TextFinder and PageValidator - are
concrete examples. Each has:
Constitution.md that is intentionally
language-agnostic. It defines what the project does, how it decomposes into
components, and the design principles that every implementation must follow
regardless of programming language. Written in plain imperative sentences;
one page maximum. Examples:
unwrap() in library code./Key [Value] tokens; exposes typed option valuesTokenizer ← Lexer ← Validator ← EntryPointNo component depends on anything to its right. Each component has one job and no knowledge of its callers.
DirEvent trait) so callers control behavior without modifying
library code.
Structure.md
governs the physical implementation: directory trees, file names, build-system
files, toolchain settings, build steps, and external dependencies. It is
language-specific - each language implementation has its own Structure.md.
## Package Layout
src/
lib.rs -- public API re-exports only
config.rs -- configuration types; no I/O
scanner.rs -- directory traversal; depends on config only
matcher.rs -- regex matching; depends on config only
reporter.rs -- output formatting; depends on scanner and matcher
main.rs -- entry point; depends on all others
## Rules
- scanner.rs must not import from matcher.rs
- reporter.rs must not perform I/O beyond writing to a provided Writer
Language: Rust (edition 2018)
Build: Cargo - each crate builds independently (no workspace manifest)
rs_textfinder/
├── Constitution.md
├── Structure.md
├── RustCmdLine/
│ ├── Cargo.toml ← library crate: rust_cmd_line
│ └── src/cmd_line_lib.rs
├── RustDirNav/
│ ├── Cargo.toml ← library crate: rust_dir_nav
│ └── src/dir_nav_lib.rs
├── EntryPoint/
│ ├── Cargo.toml ← binary crate: rust_text_finder
│ └── src/text_finder.rs
└── RustTfVerify/
├── Cargo.toml ← binary crate: tf_verify
└── src/main.rs ← integration verification harness
RustCmdLine RustDirNav
\ /
\ /
EntryPoint
RustTfVerify ──(subprocess)──► text_finder binary
Language: C++23 with named modules (.ixx files)
Build: CMake 3.28+ (FILE_SET CXX_MODULES support required)
CppTextFinder/
├── CMakeLists.txt ← top-level; sets standard, adds subdirectories
├── Constitution.md
├── Structure.md
├── CommandLine/
│ ├── CMakeLists.txt
│ └── src/
│ ├── CmdLine.ixx ← export module cmd_line;
│ └── test.cpp
├── DirNav/
│ └── src/DirNav.ixx ← export module dir_nav;
├── Output/
│ └── src/Output.ixx ← export module output;
└── EntryPoint/
└── src/main.cpp ← imports all three modules
Each part folder owns its own CMakeLists.txt.
No part's build file references another part's source directory directly.
Only the top-level CMakeLists.txt names the parts.
Language: Rust (edition 2021)
Build: Cargo workspace - each component is a separate crate
rs_page_validator/
├── Cargo.toml ← workspace root
├── Constitution.md
├── Structure.md
├── tokenizer/
│ ├── Cargo.toml ← library crate: tokenizer
│ ├── Spec.md
│ ├── Notes.md
│ └── src/lib.rs
├── lexer/
│ ├── Cargo.toml ← library crate: lexer
│ ├── Spec.md
│ ├── Notes.md
│ └── src/lib.rs
├── validator/
│ ├── Cargo.toml ← library crate: validator
│ ├── Spec.md
│ ├── Notes.md
│ └── src/lib.rs
└── entry_point/
├── Cargo.toml ← binary crate: rs_page_validator
├── Spec.md
├── Notes.md
└── src/main.rs
[workspace]
members = ["tokenizer", "lexer", "validator", "entry_point"]
resolver = "2"
Spec.md that documents each public function
or type: struct names, method signatures, return types, preconditions, postconditions,
algorithms, and invariants. The AI generates code from this spec; the spec is the
source of truth. A minimal example:
## fn scan(root: &Path, config: &Config) -> Result<Vec<Match>>
- root must exist and be a directory; returns Err otherwise
- traverses root recursively, following symlinks if config.follow_symlinks
- returns all Match records where config.pattern matches file content
- excludes files whose extension is not in config.extensions
- example: scan(Path::new("src"), &cfg) -> Ok(vec![Match{path: ..., line: 3}])
RustDirNav_Spec.md (TextFinder):
pub trait DirEvent {
fn do_dir(&mut self, d: &str);
fn do_file(&mut self, f: &str);
}
DirNav::new() -> DirNav<App>
recurse(p: bool) -> &mut Self // default: true
hide(p: bool) -> &mut Self // hide empty dirs, default: true
add_skip(s: &str) -> &mut Self // add dir name to skip list
add_pat(p: &str) -> &mut Self // add file extension filter
clear() -> &mut Self // reset skip list and patterns
visit(path: &str) // execute depth-first walk
get_dirs() -> usize // count of visited directories
get_files() -> usize // count of visited files
bin obj target build out __pycache__
.venv venv dist .git .vs .idea archive
do_dir before any do_file in that directoryValidator_Spec.md (PageValidator) - eight validation rules:
struct ValidationError {
rule: &'static str,
message: String,
line: usize,
col: usize,
}
struct Report {
file: PathBuf,
errors: Vec<ValidationError>,
// is_valid() -> bool
}
doctype document begins with <!DOCTYPE html>
root-element exactly one <html> wraps the document
head-required <head> present, contains at least one <title>
body-required <body> present as direct child of <html>
tag-nesting every open tag has a matching close in stack order
void-elements void elements carry no close tag
attr-quotes all attribute values are quoted
duplicate-id id attribute values are unique within the document
Spec.md sits a Notes.md that records the
conversation history with the AI used to develop that component. It captures:
claude, then: implement this component
following Spec.md. Claude Code reads the spec, creates or edits the
source file in place, and reports what it did. No copy-paste of generated code
is needed; the file is written directly.
generate_part.py scripts in each language variant.
A command like:
python generate_part.py CommandLine
reads the corresponding Spec.md, submits it to the Claude API, and writes
the generated source file. This means:
| Resource | Description |
|---|---|
| github.com/github/spec-kit | Inspiration for the lightweight spec approach used here. |
| AIBites: Spec-Driven Development | Original CodeBites page with full workflow examples. |
| SWDev Story: Software Design | The design chapter that underpins spec-driven development. |
| Anthropic Docs | Full API reference, model guides, and prompt engineering tips. |