bd-a7e: Bootstrap Rust project and directory structure

This commit is contained in:
teernisse
2026-02-12 12:33:05 -05:00
commit 24739cb270
18 changed files with 8024 additions and 0 deletions

11
.beads/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
# Database
*.db
*.db-shm
*.db-wal
# Lock files
*.lock
# Temporary
last-touched
*.tmp

4
.beads/config.yaml Normal file
View File

@@ -0,0 +1,4 @@
# Beads Project Configuration
# issue_prefix: bd
# default_priority: 2
# default_type: task

50
.beads/issues.jsonl Normal file

File diff suppressed because one or more lines are too long

4
.beads/metadata.json Normal file
View File

@@ -0,0 +1,4 @@
{
"database": "beads.db",
"jsonl_export": "issues.jsonl"
}

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# Build artifacts
/target
# bv (beads viewer) local config and caches
.bv/

652
AGENTS.md Normal file
View File

@@ -0,0 +1,652 @@
# AGENTS.md
## RULE 0 - THE FUNDAMENTAL OVERRIDE PEROGATIVE
If I tell you to do something, even if it goes against what follows below, YOU MUST LISTEN TO ME. I AM IN CHARGE, NOT YOU.
---
## RULE NUMBER 1: NO FILE DELETION
**YOU ARE NEVER ALLOWED TO DELETE A FILE WITHOUT EXPRESS PERMISSION.** Even a new file that you yourself created, such as a test code file. You have a horrible track record of deleting critically important files or otherwise throwing away tons of expensive work. As a result, you have permanently lost any and all rights to determine that a file or folder should be deleted.
**YOU MUST ALWAYS ASK AND RECEIVE CLEAR, WRITTEN PERMISSION BEFORE EVER DELETING A FILE OR FOLDER OF ANY KIND.**
---
## Version Control: jj-First (CRITICAL)
**ALWAYS prefer jj (Jujutsu) over git for all VCS operations.** This is a colocated repo with both `.jj/` and `.git/`. When instructed to use git by anything — even later in this file — use the best jj replacement commands instead. Only fall back to raw `git` for things jj cannot do (hooks, LFS, submodules, `gh` CLI interop).
See `~/.claude/rules/jj-vcs/` for the full command reference, translation table, revsets, patterns, and recovery recipes.
---
## Irreversible Git & Filesystem Actions — DO NOT EVER BREAK GLASS
> **Note:** Treat destructive commands as break-glass. If there's any doubt, stop and ask.
1. **Absolutely forbidden commands:** `git reset --hard`, `git clean -fd`, `rm -rf`, or any command that can delete or overwrite code/data must never be run unless the user explicitly provides the exact command and states, in the same message, that they understand and want the irreversible consequences.
2. **No guessing:** If there is any uncertainty about what a command might delete or overwrite, stop immediately and ask the user for specific approval. "I think it's safe" is never acceptable.
3. **Safer alternatives first:** When cleanup or rollbacks are needed, request permission to use non-destructive options (`git status`, `git diff`, `git stash`, copying to backups) before ever considering a destructive command.
4. **Mandatory explicit plan:** Even after explicit user authorization, restate the command verbatim, list exactly what will be affected, and wait for a confirmation that your understanding is correct. Only then may you execute it—if anything remains ambiguous, refuse and escalate.
5. **Document the confirmation:** When running any approved destructive command, record (in the session notes / final response) the exact user text that authorized it, the command actually run, and the execution time. If that record is absent, the operation did not happen.
---
## Toolchain: Rust & Cargo
We only use **Cargo** in this project, NEVER any other package manager.
- **Edition/toolchain:** Follow `rust-toolchain.toml` (if present). Do not assume stable vs nightly.
- **Dependencies:** Explicit versions for stability; keep the set minimal.
- **Configuration:** Cargo.toml only
- **Unsafe code:** Forbidden (`#![forbid(unsafe_code)]`)
When writing Rust code, reference RUST_CLI_TOOLS_BEST_PRACTICES.md
### Release Profile
Use the release profile defined in `Cargo.toml`. If you need to change it, justify the
performance/size tradeoff and how it impacts determinism and cancellation behavior.
---
## Code Editing Discipline
### No Script-Based Changes
**NEVER** run a script that processes/changes code files in this repo. Brittle regex-based transformations create far more problems than they solve.
- **Always make code changes manually**, even when there are many instances
- For many simple changes: use parallel subagents
- For subtle/complex changes: do them methodically yourself
### No File Proliferation
If you want to change something or add a feature, **revise existing code files in place**.
**NEVER** create variations like:
- `mainV2.rs`
- `main_improved.rs`
- `main_enhanced.rs`
New files are reserved for **genuinely new functionality** that makes zero sense to include in any existing file. The bar for creating new files is **incredibly high**.
---
## Backwards Compatibility
We do not care about backwards compatibility—we're in early development with no users. We want to do things the **RIGHT** way with **NO TECH DEBT**.
- Never create "compatibility shims"
- Never create wrapper functions for deprecated APIs
- Just fix the code directly
---
## Compiler Checks (CRITICAL)
**After any substantive code changes, you MUST verify no errors were introduced:**
```bash
# Check for compiler errors and warnings
cargo check --all-targets
# Check for clippy lints (pedantic + nursery are enabled)
cargo clippy --all-targets -- -D warnings
# Verify formatting
cargo fmt --check
```
If you see errors, **carefully understand and resolve each issue**. Read sufficient context to fix them the RIGHT way.
---
## Testing
### Unit & Property Tests
```bash
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
```
When adding or changing primitives, add tests that assert the core invariants:
- no task leaks
- no obligation leaks
- losers are drained after races
- region close implies quiescence
Prefer deterministic lab-runtime tests for concurrency-sensitive behavior.
---
## MCP Agent Mail — Multi-Agent Coordination
A mail-like layer that lets coding agents coordinate asynchronously via MCP tools and resources. Provides identities, inbox/outbox, searchable threads, and advisory file reservations with human-auditable artifacts in Git.
### Why It's Useful
- **Prevents conflicts:** Explicit file reservations (leases) for files/globs
- **Token-efficient:** Messages stored in per-project archive, not in context
- **Quick reads:** `resource://inbox/...`, `resource://thread/...`
### Same Repository Workflow
1. **Register identity:**
```
ensure_project(project_key=<abs-path>)
register_agent(project_key, program, model)
```
2. **Reserve files before editing:**
```
file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true)
```
3. **Communicate with threads:**
```
send_message(..., thread_id="FEAT-123")
fetch_inbox(project_key, agent_name)
acknowledge_message(project_key, agent_name, message_id)
```
4. **Quick reads:**
```
resource://inbox/{Agent}?project=<abs-path>&limit=20
resource://thread/{id}?project=<abs-path>&include_bodies=true
```
### Macros vs Granular Tools
- **Prefer macros for speed:** `macro_start_session`, `macro_prepare_thread`, `macro_file_reservation_cycle`, `macro_contact_handshake`
- **Use granular tools for control:** `register_agent`, `file_reservation_paths`, `send_message`, `fetch_inbox`, `acknowledge_message`
### Common Pitfalls
- `"from_agent not registered"`: Always `register_agent` in the correct `project_key` first
- `"FILE_RESERVATION_CONFLICT"`: Adjust patterns, wait for expiry, or use non-exclusive reservation
- **Auth errors:** If JWT+JWKS enabled, include bearer token with matching `kid`
---
## Beads (br) — Dependency-Aware Issue Tracking
Beads provides a lightweight, dependency-aware issue database and CLI (`br` / beads_rust) for selecting "ready work," setting priorities, and tracking status. It complements MCP Agent Mail's messaging and file reservations.
**Note:** `br` is non-invasive—it never executes git commands directly. You must run git commands manually after `br sync --flush-only`.
### Conventions
- **Single source of truth:** Beads for task status/priority/dependencies; Agent Mail for conversation and audit
- **Shared identifiers:** Use Beads issue ID (e.g., `br-123`) as Mail `thread_id` and prefix subjects with `[br-123]`
- **Reservations:** When starting a task, call `file_reservation_paths()` with the issue ID in `reason`
### Typical Agent Flow
1. **Pick ready work (Beads):**
```bash
br ready --json # Choose highest priority, no blockers
```
2. **Reserve edit surface (Mail):**
```
file_reservation_paths(project_key, agent_name, ["src/**"], ttl_seconds=3600, exclusive=true, reason="br-123")
```
3. **Announce start (Mail):**
```
send_message(..., thread_id="br-123", subject="[br-123] Start: <title>", ack_required=true)
```
4. **Work and update:** Reply in-thread with progress
5. **Complete and release:**
```bash
br close br-123 --reason "Completed"
```
```
release_file_reservations(project_key, agent_name, paths=["src/**"])
```
Final Mail reply: `[br-123] Completed` with summary
### Mapping Cheat Sheet
| Concept | Value |
|---------|-------|
| Mail `thread_id` | `br-###` |
| Mail subject | `[br-###] ...` |
| File reservation `reason` | `br-###` |
| Commit messages | Include `br-###` for traceability |
---
## bv — Graph-Aware Triage Engine
bv is a graph-aware triage engine for Beads projects (`.beads/beads.jsonl`). It computes PageRank, betweenness, critical path, cycles, HITS, eigenvector, and k-core metrics deterministically.
**Scope boundary:** bv handles *what to work on* (triage, priority, planning). For agent-to-agent coordination (messaging, work claiming, file reservations), use MCP Agent Mail.
**CRITICAL: Use ONLY `--robot-*` flags. Bare `bv` launches an interactive TUI that blocks your session.**
### The Workflow: Start With Triage
**`bv --robot-triage` is your single entry point.** It returns:
- `quick_ref`: at-a-glance counts + top 3 picks
- `recommendations`: ranked actionable items with scores, reasons, unblock info
- `quick_wins`: low-effort high-impact items
- `blockers_to_clear`: items that unblock the most downstream work
- `project_health`: status/type/priority distributions, graph metrics
- `commands`: copy-paste shell commands for next steps
```bash
bv --robot-triage # THE MEGA-COMMAND: start here
bv --robot-next # Minimal: just the single top pick + claim command
```
### Command Reference
**Planning:**
| Command | Returns |
|---------|---------|
| `--robot-plan` | Parallel execution tracks with `unblocks` lists |
| `--robot-priority` | Priority misalignment detection with confidence |
**Graph Analysis:**
| Command | Returns |
|---------|---------|
| `--robot-insights` | Full metrics: PageRank, betweenness, HITS, eigenvector, critical path, cycles, k-core, articulation points, slack |
| `--robot-label-health` | Per-label health: `health_level`, `velocity_score`, `staleness`, `blocked_count` |
| `--robot-label-flow` | Cross-label dependency: `flow_matrix`, `dependencies`, `bottleneck_labels` |
| `--robot-label-attention [--attention-limit=N]` | Attention-ranked labels |
**History & Change Tracking:**
| Command | Returns |
|---------|---------|
| `--robot-history` | Bead-to-commit correlations |
| `--robot-diff --diff-since <ref>` | Changes since ref: new/closed/modified issues, cycles |
**Other:**
| Command | Returns |
|---------|---------|
| `--robot-burndown <sprint>` | Sprint burndown, scope changes, at-risk items |
| `--robot-forecast <id\|all>` | ETA predictions with dependency-aware scheduling |
| `--robot-alerts` | Stale issues, blocking cascades, priority mismatches |
| `--robot-suggest` | Hygiene: duplicates, missing deps, label suggestions |
| `--robot-graph [--graph-format=json\|dot\|mermaid]` | Dependency graph export |
| `--export-graph <file.html>` | Interactive HTML visualization |
### Scoping & Filtering
```bash
bv --robot-plan --label backend # Scope to label's subgraph
bv --robot-insights --as-of HEAD~30 # Historical point-in-time
bv --recipe actionable --robot-plan # Pre-filter: ready to work
bv --recipe high-impact --robot-triage # Pre-filter: top PageRank
bv --robot-triage --robot-triage-by-track # Group by parallel work streams
bv --robot-triage --robot-triage-by-label # Group by domain
```
### Understanding Robot Output
**All robot JSON includes:**
- `data_hash` — Fingerprint of source beads.jsonl
- `status` — Per-metric state: `computed|approx|timeout|skipped` + elapsed ms
- `as_of` / `as_of_commit` — Present when using `--as-of`
**Two-phase analysis:**
- **Phase 1 (instant):** degree, topo sort, density
- **Phase 2 (async, 500ms timeout):** PageRank, betweenness, HITS, eigenvector, cycles
### jq Quick Reference
```bash
bv --robot-triage | jq '.quick_ref' # At-a-glance summary
bv --robot-triage | jq '.recommendations[0]' # Top recommendation
bv --robot-plan | jq '.plan.summary.highest_impact' # Best unblock target
bv --robot-insights | jq '.status' # Check metric readiness
bv --robot-insights | jq '.Cycles' # Circular deps (must fix!)
```
---
## UBS — Ultimate Bug Scanner
**Golden Rule:** `ubs <changed-files>` before every commit. Exit 0 = safe. Exit >0 = fix & re-run.
### Commands
```bash
ubs file.rs file2.rs # Specific files (< 1s) — USE THIS
ubs $(jj diff --name-only) # Changed files — before commit
ubs --only=rust,toml src/ # Language filter (3-5x faster)
ubs --ci --fail-on-warning . # CI mode — before PR
ubs . # Whole project (ignores target/, Cargo.lock)
```
### Output Format
```
⚠️ Category (N errors)
file.rs:42:5 Issue description
💡 Suggested fix
Exit code: 1
```
Parse: `file:line:col` → location | 💡 → how to fix | Exit 0/1 → pass/fail
### Fix Workflow
1. Read finding → category + fix suggestion
2. Navigate `file:line:col` → view context
3. Verify real issue (not false positive)
4. Fix root cause (not symptom)
5. Re-run `ubs <file>` → exit 0
6. Commit
### Bug Severity
- **Critical (always fix):** Memory safety, use-after-free, data races, SQL injection
- **Important (production):** Unwrap panics, resource leaks, overflow checks
- **Contextual (judgment):** TODO/FIXME, println! debugging
---
## ast-grep vs ripgrep
**Use `ast-grep` when structure matters.** It parses code and matches AST nodes, ignoring comments/strings, and can **safely rewrite** code.
- Refactors/codemods: rename APIs, change import forms
- Policy checks: enforce patterns across a repo
- Editor/automation: LSP mode, `--json` output
**Use `ripgrep` when text is enough.** Fastest way to grep literals/regex.
- Recon: find strings, TODOs, log lines, config values
- Pre-filter: narrow candidate files before ast-grep
### Rule of Thumb
- Need correctness or **applying changes** → `ast-grep`
- Need raw speed or **hunting text** → `rg`
- Often combine: `rg` to shortlist files, then `ast-grep` to match/modify
### Rust Examples
```bash
# Find structured code (ignores comments)
ast-grep run -l Rust -p 'fn $NAME($$$ARGS) -> $RET { $$$BODY }'
# Find all unwrap() calls
ast-grep run -l Rust -p '$EXPR.unwrap()'
# Quick textual hunt
rg -n 'println!' -t rust
# Combine speed + precision
rg -l -t rust 'unwrap\(' | xargs ast-grep run -l Rust -p '$X.unwrap()' --json
```
---
## Morph Warp Grep — AI-Powered Code Search
**Use `mcp__morph-mcp__warp_grep` for exploratory "how does X work?" questions.** An AI agent expands your query, greps the codebase, reads relevant files, and returns precise line ranges with full context.
**Use `ripgrep` for targeted searches.** When you know exactly what you're looking for.
**Use `ast-grep` for structural patterns.** When you need AST precision for matching/rewriting.
### When to Use What
| Scenario | Tool | Why |
|----------|------|-----|
| "How is pattern matching implemented?" | `warp_grep` | Exploratory; don't know where to start |
| "Where is the quick reject filter?" | `warp_grep` | Need to understand architecture |
| "Find all uses of `Regex::new`" | `ripgrep` | Targeted literal search |
| "Find files with `println!`" | `ripgrep` | Simple pattern |
| "Replace all `unwrap()` with `expect()`" | `ast-grep` | Structural refactor |
### warp_grep Usage
```
mcp__morph-mcp__warp_grep(
repoPath: "/path/to/dcg",
query: "How does the safe pattern whitelist work?"
)
```
Returns structured results with file paths, line ranges, and extracted code snippets.
### Anti-Patterns
- **Don't** use `warp_grep` to find a specific function name → use `ripgrep`
- **Don't** use `ripgrep` to understand "how does X work" → wastes time with manual reads
- **Don't** use `ripgrep` for codemods → risks collateral edits
<!-- bv-agent-instructions-v1 -->
---
## Beads Workflow Integration
This project uses [beads_viewer](https://github.com/Dicklesworthstone/beads_viewer) for issue tracking. Issues are stored in `.beads/` and tracked in version control.
**Note:** `br` is non-invasive—it never executes VCS commands directly. You must commit manually after `br sync --flush-only`.
### Essential Commands
```bash
# View issues (launches TUI - avoid in automated sessions)
bv
# CLI commands for agents (use these instead)
br ready # Show issues ready to work (no blockers)
br list --status=open # All open issues
br show <id> # Full issue details with dependencies
br create --title="..." --type=task --priority=2
br update <id> --status=in_progress
br close <id> --reason="Completed"
br close <id1> <id2> # Close multiple issues at once
br sync --flush-only # Export to JSONL (then: jj commit -m "Update beads")
```
### Workflow Pattern
1. **Start**: Run `br ready` to find actionable work
2. **Claim**: Use `br update <id> --status=in_progress`
3. **Work**: Implement the task
4. **Complete**: Use `br close <id>`
5. **Sync**: Run `br sync --flush-only`, then `git add .beads/ && git commit -m "Update beads"`
### Key Concepts
- **Dependencies**: Issues can block other issues. `br ready` shows only unblocked work.
- **Priority**: P0=critical, P1=high, P2=medium, P3=low, P4=backlog (use numbers, not words)
- **Types**: task, bug, feature, epic, question, docs
- **Blocking**: `br dep add <issue> <depends-on>` to add dependencies
### Session Protocol
**Before ending any session, run this checklist (solo/lead only — workers skip VCS):**
```bash
jj status # Check what changed
br sync --flush-only # Export beads to JSONL
jj commit -m "..." # Commit code and beads (jj auto-tracks all changes)
jj bookmark set <name> -r @- # Point bookmark at committed work
jj git push -b <name> # Push to remote
```
### Best Practices
- Check `br ready` at session start to find available work
- Update status as you work (in_progress → closed)
- Create new issues with `br create` when you discover tasks
- Use descriptive titles and set appropriate priority/type
- Always run `br sync --flush-only` then commit before ending session (jj auto-tracks .beads/)
<!-- end-bv-agent-instructions -->
## Landing the Plane (Session Completion)
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until push succeeds.
**WHO RUNS THIS:** Solo agents run it themselves. In multi-agent sessions, ONLY the team lead runs this. Workers skip VCS entirely.
**MANDATORY WORKFLOW:**
1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
```bash
jj git fetch # Get latest remote state
jj rebase -d trunk() # Rebase onto latest trunk if needed
br sync --flush-only # Export beads to JSONL
jj commit -m "Update beads" # Commit (jj auto-tracks .beads/ changes)
jj bookmark set <name> -r @- # Point bookmark at committed work
jj git push -b <name> # Push to remote
jj log -r '<name>' # Verify bookmark position
```
5. **Clean up** - Abandon empty orphan changes if any (`jj abandon <rev>`)
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session
**CRITICAL RULES:**
- Work is NOT complete until `jj git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds
---
## cass — Cross-Agent Session Search
`cass` indexes prior agent conversations (Claude Code, Codex, Cursor, Gemini, ChatGPT, etc.) so we can reuse solved problems.
**Rules:** Never run bare `cass` (TUI). Always use `--robot` or `--json`.
### Examples
```bash
cass health
cass search "async runtime" --robot --limit 5
cass view /path/to/session.jsonl -n 42 --json
cass expand /path/to/session.jsonl -n 42 -C 3 --json
cass capabilities --json
cass robot-docs guide
```
### Tips
- Use `--fields minimal` for lean output
- Filter by agent with `--agent`
- Use `--days N` to limit to recent history
stdout is data-only, stderr is diagnostics; exit code 0 means success.
Treat cass as a way to avoid re-solving problems other agents already handled.
---
## Note for Codex/GPT-5.2
You constantly bother me and stop working with concerned questions that look similar to this:
```
Unexpected changes (need guidance)
- Working tree still shows edits I did not make in Cargo.toml, Cargo.lock, src/runtime.rs, src/scope.rs. Please advise whether to keep/commit/revert these before any further work. I did not touch them.
Next steps (pick one)
1. Decide how to handle the unrelated modified files above so we can resume cleanly.
```
NEVER EVER DO THAT AGAIN. The answer is literally ALWAYS the same: those are changes created by the potentially dozen of other agents working on the project at the same time. This is not only a common occurence, it happens multiple times PER MINUTE. The way to deal with it is simple: you NEVER, under ANY CIRCUMSTANCE, stash, revert, overwrite, or otherwise disturb in ANY way the work of other agents. Just treat those changes identically to changes that you yourself made. Just fool yourself into thinking YOU made the changes and simply don't recall it for some reason.
---
## Note on Built-in TODO Functionality
Also, if I ask you to explicitly use your built-in TODO functionality, don't complain about this and say you need to use beads. You can use built-in TODOs if I tell you specifically to do so. Always comply with such orders.
## TDD Requirements
Test-first development is mandatory:
1. **RED** - Write failing test first
2. **GREEN** - Minimal implementation to pass
3. **REFACTOR** - Clean up while green
## Key Patterns
Find the simplest solution that meets all acceptance criteria.
Use third party libraries whenever there's a well-maintained, active, and widely adopted solution (for example, date-fns for TS date math)
Build extensible pieces of logic that can easily be integrated with other pieces.
DRY principles should be loosely held.
Architecture MUST be clear and well thought-out. Ask the user for clarification whenever ambiguity is discovered around architecture, or you think a better approach than planned exists.
---
## Third-Party Library Usage
If you aren't 100% sure how to use a third-party library, **SEARCH ONLINE** to find the latest documentation and mid-2025 best practices.
---
````markdown
## UBS Quick Reference for AI Agents
UBS stands for "Ultimate Bug Scanner": **The AI Coding Agent's Secret Weapon: Flagging Likely Bugs for Fixing Early On**
**Install:** `curl -sSL https://raw.githubusercontent.com/Dicklesworthstone/ultimate_bug_scanner/master/install.sh | bash`
**Golden Rule:** `ubs <changed-files>` before every commit. Exit 0 = safe. Exit >0 = fix & re-run.
**Commands:**
```bash
ubs file.ts file2.py # Specific files (< 1s) — USE THIS
ubs $(git diff --name-only --cached) # Staged files — before commit
ubs --only=js,python src/ # Language filter (3-5x faster)
ubs --ci --fail-on-warning . # CI mode — before PR
ubs --help # Full command reference
ubs sessions --entries 1 # Tail the latest install session log
ubs . # Whole project (ignores things like .venv and node_modules automatically)
```
**Output Format:**
```
⚠️ Category (N errors)
file.ts:42:5 Issue description
💡 Suggested fix
Exit code: 1
```
Parse: `file:line:col` → location | 💡 → how to fix | Exit 0/1 → pass/fail
**Fix Workflow:**
1. Read finding → category + fix suggestion
2. Navigate `file:line:col` → view context
3. Verify real issue (not false positive)
4. Fix root cause (not symptom)
5. Re-run `ubs <file>` → exit 0
6. Commit
**Speed Critical:** Scope to changed files. `ubs src/file.ts` (< 1s) vs `ubs .` (30s). Never full scan for small edits.
**Bug Severity:**
- **Critical** (always fix): Null safety, XSS/injection, async/await, memory leaks
- **Important** (production): Type narrowing, division-by-zero, resource leaks
- **Contextual** (judgment): TODO/FIXME, console logs
**Anti-Patterns:**
- ❌ Ignore findings → ✅ Investigate each
- ❌ Full scan per edit → ✅ Scope to file
- ❌ Fix symptom (`if (x) { x.y }`) → ✅ Root cause (`x?.y`)
````

2759
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

36
Cargo.toml Normal file
View File

@@ -0,0 +1,36 @@
[package]
name = "swagger-cli"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4", features = ["derive"] }
colored = "3"
directories = "6"
fs2 = "0.4"
regex = "1"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
sha2 = "0.10"
tabled = "0.17"
thiserror = "2"
tokio = { version = "1", features = ["full"] }
toml = "0.8"
[dev-dependencies]
assert_cmd = "2"
criterion = "0.5"
mockito = "1"
predicates = "3"
tempfile = "3"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true

View File

@@ -0,0 +1,171 @@
No `## Rejected Recommendations` section exists in `prd-swagger-cli.md`, so all suggestions below are net-new.
**1. Add a canonical ingest pipeline (JSON + YAML + gzip) with streaming limits**
Current plan is effectively JSON-first and buffer-oriented. In practice, many OpenAPI specs are YAML and/or compressed; forcing JSON-only ingestion creates adoption friction and unnecessary memory pressure on large specs. A canonical ingest stage (detect format, decode, parse, normalize) gives one robust path for URL/file/stdin and makes future behaviors (ref resolution, provenance) cleaner.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ FR-1: Spec Fetching and Caching
-- ✓ Validate JSON is parseable before caching (no full OpenAPI structural validation)
+- ✓ Validate spec is parseable JSON or YAML before caching (no full OpenAPI structural validation)
+- ✓ Support compressed inputs (`.json.gz`, `.yaml.gz`, `Content-Encoding: gzip`)
+- ✓ Enforce `--max-bytes` during streaming download (fail before full buffering)
@@ OPTIONS:
+ --format <FORMAT> Input format hint: auto (default), json, yaml
@@ Cache directory layout
- ├── raw.json # Exact upstream bytes (lossless)
+ ├── raw.source # Exact upstream bytes (json|yaml|gz as fetched)
+ ├── raw.json # Canonical normalized JSON for pointers/show
@@ Core dependencies
+serde_yaml = "0.9"
+flate2 = "1.0"
```
**2. Add explicit fetch-time external-ref bundling (opt-in)**
You already correctly avoid external network fetches during `show --expand-refs`. The missing piece is specs that rely on external refs for core operations. Add an explicit fetch-time bundling mode with strict allowlists/limits. Default remains offline-safe and unchanged.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ FR-1 OPTIONS:
+ --resolve-external-refs Resolve and bundle external $ref targets at fetch-time (opt-in)
+ --ref-allow-host <HOST> Allowlist host for external ref resolution (repeatable)
+ --ref-max-depth <N> Max external ref chain depth (default: 3)
+ --ref-max-bytes <N> Total bytes cap for all external ref fetches
@@ FR-3 Decision rationale
-- External refs are NOT fetched (no network).
+- Query-time external refs are NOT fetched (no network).
+- Optional fetch-time bundling can resolve external refs under explicit policy flags.
+- Bundled snapshots preserve offline guarantees for all later commands.
```
**3. Add a global network policy switch for deterministic agent runs**
Manual `sync` is good, but a global network policy is better for CI/agent reproducibility. This prevents accidental network behavior in restricted environments and makes failure mode explicit.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ src/cli/mod.rs
+ /// Network policy: auto (default), offline, online-only
+ #[arg(long, global = true, default_value = "auto", value_parser = ["auto","offline","online-only"])]
+ pub network: String,
@@ Goals
+6. **Determinism:** Global network policy control for reproducible offline/CI execution
@@ Appendix B: Exit Code Reference
+| 15 | Offline mode blocked network operation | `OFFLINE_MODE` | No | Retry without `--network offline` |
```
**4. Strengthen integrity checks with raw-hash verification + pointer validation + safe auto-rebuild**
Current generation/index-hash integrity is good but incomplete for raw corruption and stale pointers. Add raw hash verification when raw is used, and validate every pointer at fetch/sync/doctor. Also allow safe index auto-rebuild from valid raw under lock to reduce operational toil.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ Read protocol:
- - Read index.json. Validate ALL THREE match meta.json:
+ - Read index.json. Validate ALL FOUR match meta.json:
1. meta.index_version == index.index_version
2. meta.generation == index.generation
3. meta.index_hash == sha256(index.json bytes)
+ 4. meta.content_hash == sha256(raw.json bytes) (commands that require raw)
+ - Validate every `operation_ptr` / `schema_ptr` resolves during fetch/sync; doctor re-checks all pointers.
+ - If index integrity fails but raw is valid: auto-rebuild index under alias lock (unless `--strict-integrity`).
@@ FR-9 doctor
+- ✓ Verify index pointers resolve to existing JSON nodes
+- ✓ Repair path prefers deterministic index rebuild before surfacing CACHE_INTEGRITY
```
**5. Make `sync --all` scalable and polite (bounded concurrency + host throttling + Retry-After)**
As alias count grows, sequential sync is slow; unconstrained parallel sync is abusive and unreliable. Add bounded concurrency plus per-host caps and Retry-After handling for robust large-team usage.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ FR-7 OPTIONS:
+ --jobs <N> Parallel aliases to sync (default: 4, bounded)
+ --per-host <N> Max concurrent requests per host (default: 2)
@@ Decision rationale:
+- `sync --all` uses bounded concurrency with per-host throttling.
+- Retries honor `Retry-After` when present; otherwise exponential backoff + jitter.
+- Robot output reports partial failures per alias without aborting the entire run.
```
**6. Upgrade search to a precomputed token index + deterministic fuzzy fallback**
Current contains-based scoring will degrade on larger specs and misses common misspellings. A small postings index in `index.json` keeps search fast and makes ranking better without adding a heavy FTS dependency.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ FR-5 Acceptance Criteria
+- ✓ Use precomputed token postings for O(query_terms + matches) lookup
+- ✓ Optional typo-tolerant matching (`--fuzzy`) with bounded edit distance
+- ✓ Deterministic fixed-point scoring (integer), stable tie-breaking retained
@@ Command: swagger-cli search
+ --fuzzy Enable bounded typo-tolerant token matching
+ --min-score <N> Filter low-relevance matches
@@ Data Models: SpecIndex
+ pub search_lexicon_version: u32,
+ pub search_postings: Vec<SearchPosting>,
```
**7. Add cross-alias discovery mode for `list` and `search`**
Single-alias operation is clean, but discovery across many APIs is a common real-world workflow. `--all-aliases` gives immediate utility to both humans and agents while preserving existing default behavior.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ FR-2 Command: swagger-cli list
+ --all-aliases Run query across all aliases; include `alias` per result
@@ FR-5 Command: swagger-cli search
+ --all-aliases Search across all aliases; include `alias` per result
@@ Robot output (list/search)
+ "alias": "petstore",
@@ Open Questions Q3
-Decision: Single alias per query in MVP; revisit if requested
+Decision: Default remains single alias; `--all-aliases` added for explicit federated discovery.
```
**8. Add cache lifecycle management (`cache` command)**
You report disk usage but dont provide lifecycle controls. Add prune/compact/stats to avoid long-term cache bloat and improve operational hygiene.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ Functional Requirements
+### FR-10: Cache Lifecycle Management
+**Description:** Manage cache growth and retention.
+**Command:** swagger-cli cache [OPTIONS]
+OPTIONS:
+ --stats Show per-alias and total cache usage
+ --prune-stale Delete aliases older than stale threshold
+ --max-total-mb <N> Enforce global cache cap via LRU eviction
+ --robot Machine-readable output
```
**9. Harden release/install supply chain (checksums + signatures)**
Current installer downloads and executes binaries without verification. Add checksum/signature artifacts and enforce verification in installer by default.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ Release stage
+ - sha256sum swagger-cli-* > SHA256SUMS
+ - minisign -Sm SHA256SUMS
+ - upload SHA256SUMS and SHA256SUMS.minisig with binaries
@@ install.sh
-# Download binary
+# Download binary + checksum manifest + signature
+# Verify signature + checksum before chmod +x
+VERIFY="${VERIFY:-true}"
+if [ "$VERIFY" = "true" ]; then
+ # fail closed on verification mismatch
+fi
```
**10. Add adversarial reliability tests (fault injection + concurrency stress + property tests)**
The plan has good tests, but not enough proof for crash consistency and lock behavior under contention. Add targeted destructive tests to validate the core reliability claims.
```diff
diff --git a/prd-swagger-cli.md b/prd-swagger-cli.md
@@ Testing Strategy
+### Reliability Stress Tests
+- Fault-injection tests at each write step (before/after fsync, before/after rename) to prove recoverability.
+- Multi-process lock contention tests (N>=32) validating bounded lock timeout and no deadlocks.
+- Property-based tests for deterministic ordering, stable tie-breaking, and pointer validity.
@@ Success Metrics Phase 1
+- Crash-consistency claim is validated by automated fault-injection test suite (not only unit tests).
```
If you want, I can now consolidate these into a single full unified patch for `prd-swagger-cli.md` with section-by-section wording ready to paste.

View File

@@ -0,0 +1,158 @@
Proposed revisions below are all new and avoid anything in your `## Rejected Recommendations` list.
1. **Add fetch-time policy enforcement (SSRF + insecure transport controls)**
Analysis: Right now external ref allowlisting is good, but primary `fetch` still permits risky network targets. Adding policy gates prevents accidental access to metadata endpoints/internal services and makes CI behavior more deterministic. This is a high-impact security and reliability improvement with low implementation risk.
```diff
@@ FR-1: Spec Fetching and Caching / Acceptance Criteria
+- ✓ Enforce fetch network policy by default: block loopback/link-local/RFC1918/multicast targets for remote URL fetches
+- ✓ Require HTTPS for remote URLs by default; plain HTTP requires explicit opt-in
+- ✓ Resolve and validate final connected IP after redirects to mitigate DNS-rebinding bypasses
@@ Command: swagger-cli fetch <url> [OPTIONS]
+ --allow-private-host <HOST> Allow specific private/internal hosts (repeatable)
+ --allow-insecure-http Permit http:// URLs (default: reject)
@@ Error cases
+| Policy blocked | 16 | `POLICY_BLOCKED` |
```
2. **Harden alias and filesystem path safety**
Analysis: Alias names currently appear to map directly to directory names, which creates path traversal and portability risk if not constrained. Strict alias validation plus canonical path handling for local files removes a whole class of corruption/security bugs.
```diff
@@ FR-1: Spec Fetching and Caching / Acceptance Criteria
+- ✓ Validate alias format: `^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$`
+- ✓ Reject aliases containing path separators, `..`, or reserved device names
+- ✓ Canonicalize local file paths before ingest; fail fast on unreadable targets
```
3. **Promote `diff` to Phase 2 with breaking-change classification**
Analysis: You already compute sync deltas; exposing this directly as a first-class command is highly compelling for CI, release checks, and agent workflows. It turns passive metadata into an actionable compatibility contract.
```diff
@@ Functional Requirements
+### FR-11: Spec Diff and Compatibility
+**Description:** Compare two spec states and classify changes as breaking/non-breaking.
+**Acceptance Criteria:**
+- ✓ Compare alias vs alias, alias vs URL, or alias generation vs generation
+- ✓ Classify endpoint and schema changes (`breaking`, `non_breaking`, `unknown`)
+- ✓ Robot mode emits machine-actionable compatibility summary
+**Command:**
+`swagger-cli diff <LEFT> <RIGHT> [--fail-on breaking] [--details] [--robot]`
@@ Phase 2 (Polish) - Week 2
+- ✓ Diff command with compatibility classification for CI gates
```
4. **Formalize robot contract with JSON Schema artifacts and compatibility policy**
Analysis: Golden tests are good, but schema files give stronger guarantees and external tooling compatibility. This materially improves long-term API stability for agent consumers.
```diff
@@ Appendix C: Robot Mode Output Schemas
+Canonical schemas are versioned and published:
+- docs/robot-schema/v1/success.schema.json
+- docs/robot-schema/v1/error.schema.json
+
+Compatibility policy:
+- Additive fields: no schema_version bump
+- Removed/renamed/type-changed fields: MUST bump schema_version
+- `meta.command_version` added for command-specific payload evolution
```
5. **Reduce write amplification from `last_accessed` updates**
Analysis: Updating metadata on every query can create unnecessary I/O, contention, and SSD churn, especially with frequent agent calls. Coalescing updates preserves LRU usefulness while improving performance/reliability under concurrency.
```diff
@@ FR-10 Decision rationale
-- **LRU eviction:** Uses `last_accessed` timestamp (updated on every query command) for fair eviction ordering.
+- **LRU eviction:** Uses coalesced `last_accessed` writes (e.g., write only when older than 10 minutes) to reduce lock contention and write amplification.
@@ src/core/cache.rs / Read protocol
-- Update meta.last_accessed timestamp on successful read (best-effort, no lock required).
+- Coalesce last_accessed updates with minimum write interval; skip metadata rewrite for hot-read bursts.
```
6. **Shift to async HTTP + explicit service layering**
Analysis: `sync --all` and retry/per-host controls are cleaner and more robust with async primitives. Separating CLI parsing from application services and infra adapters improves testability and lowers long-term maintenance cost.
```diff
@@ Technology Stack
-reqwest = { version = "0.13", default-features = false, features = ["json", "blocking", "rustls-tls"] }
+reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-tls", "http2"] }
+tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "sync"] }
+tracing = "0.1"
+tracing-subscriber = { version = "0.3", features = ["env-filter"] }
@@ Project Structure
+├── src/app/ # Use-case orchestration (fetch/list/show/sync services)
+├── src/infra/ # HTTP client, fs/cache, lock, clock abstractions
```
7. **Add resumable sync and failure budget controls**
Analysis: Large multi-alias sync runs can fail mid-way and currently require full reruns. Resume checkpoints and configurable failure budgets improve reliability for CI and large fleet use.
```diff
@@ FR-7: Sync and Updates / OPTIONS
+ --resume Resume from last interrupted --all sync checkpoint
+ --max-failures <N> Abort run after N alias failures (default: unlimited)
@@ FR-7 Acceptance Criteria
+- ✓ `sync --all` persists per-alias progress checkpoint for resumable execution
+- ✓ Supports controlled abort via failure budget to limit noisy upstream incidents
```
8. **Upgrade secret handling model beyond plaintext token field**
Analysis: You already warn on file perms, but adding env/keyring sources avoids persisting sensitive tokens where possible. This is a meaningful security upgrade with backward-compatible defaults.
```diff
@@ src/core/config.rs
-pub struct AuthConfig {
- pub url_pattern: String,
- pub auth_type: AuthType,
- pub token: String,
-}
+pub struct AuthConfig {
+ pub url_pattern: String,
+ pub auth_type: AuthType,
+ pub credential: CredentialSource,
+}
+
+pub enum CredentialSource {
+ Literal(String),
+ EnvVar(String),
+ Keyring { service: String, account: String },
+}
```
9. **Expand supply-chain controls (dependency policy + SBOM + provenance)**
Analysis: Checksums/signatures help artifact integrity, but you still need dependency and provenance gates in CI for stronger trust. This is especially valuable for an agent-facing CLI that may run in privileged automation.
```diff
@@ .gitlab-ci.yml
+security:deps:
+ stage: test
+ image: rust:1.93
+ script:
+ - cargo install cargo-deny cargo-audit
+ - cargo deny check
+ - cargo audit
+
+release:sbom:
+ stage: release
+ script:
+ - cargo install cargo-cyclonedx
+ - cargo cyclonedx --format json --output-file sbom.cdx.json
+ - cosign attest --predicate sbom.cdx.json --type cyclonedx $RELEASE_ARTIFACT
```
10. **Fix installer portability and cleanup behavior**
Analysis: `sha256sum` is not guaranteed on macOS, and current temp-file handling is not robust on interrupted runs. These fixes reduce installation friction and avoid leaving sensitive artifacts in `/tmp`.
```diff
@@ install.sh
-set -e
+set -euo pipefail
+TMP_DIR="$(mktemp -d)"
+trap 'rm -rf "$TMP_DIR"' EXIT
@@ checksum verification
-ACTUAL=$(sha256sum "$INSTALL_DIR/swagger-cli" | awk '{print $1}')
+if command -v sha256sum >/dev/null 2>&1; then
+ ACTUAL=$(sha256sum "$INSTALL_DIR/swagger-cli" | awk '{print $1}')
+else
+ ACTUAL=$(shasum -a 256 "$INSTALL_DIR/swagger-cli" | awk '{print $1}')
+fi
```
If you want, I can produce one consolidated full-PRD patch (single unified diff) applying all 10 changes in-place so you can drop it directly into the next iteration.

4154
prd-swagger-cli.md Normal file

File diff suppressed because it is too large Load Diff

1
src/cli/mod.rs Normal file
View File

@@ -0,0 +1 @@
// CLI command definitions

1
src/core/mod.rs Normal file
View File

@@ -0,0 +1 @@
// Core business logic modules

1
src/errors.rs Normal file
View File

@@ -0,0 +1 @@
// Error types - implemented by bd-ilo

7
src/lib.rs Normal file
View File

@@ -0,0 +1,7 @@
#![forbid(unsafe_code)]
pub mod cli;
pub mod core;
pub mod errors;
pub mod output;
pub mod utils;

8
src/main.rs Normal file
View File

@@ -0,0 +1,8 @@
#![forbid(unsafe_code)]
use std::process::ExitCode;
#[tokio::main]
async fn main() -> ExitCode {
ExitCode::SUCCESS
}

1
src/output/mod.rs Normal file
View File

@@ -0,0 +1 @@
// Output formatting

1
src/utils.rs Normal file
View File

@@ -0,0 +1 @@
// Utility functions