diff --git a/.blue/data/blue/blue.db b/.blue/data/blue/blue.db index a9211c4..ed51c34 100644 Binary files a/.blue/data/blue/blue.db and b/.blue/data/blue/blue.db differ diff --git a/.blue/repos/blue/docs/rfcs/0001-dialogue-sqlite-metadata.md b/.blue/repos/blue/docs/rfcs/0001-dialogue-sqlite-metadata.md new file mode 100644 index 0000000..e9f60d1 --- /dev/null +++ b/.blue/repos/blue/docs/rfcs/0001-dialogue-sqlite-metadata.md @@ -0,0 +1,198 @@ +# RFC 0001: Dialogue SQLite Metadata + +| | | +|---|---| +| **Status** | Draft | +| **Date** | 2026-01-24 | +| **Source Spike** | sqlite-storage-expansion | + +--- + +## Summary + +Dialogue files (.dialogue.md) are not indexed in SQLite. Can't query them, link them to RFCs, or track relationships. Need to add DocType::Dialogue and store metadata while keeping content in markdown. + +## Background + +Dialogues are transcripts of conversations - different from RFCs/spikes which are living documents with status transitions. + +Current state: +- Dialogues exist as `.dialogue.md` files in `docs/dialogues/` +- No SQLite tracking +- No way to search or link them + +## Proposal + +### 1. Add DocType::Dialogue + +```rust +pub enum DocType { + Rfc, + Spike, + Adr, + Decision, + Prd, + Postmortem, + Runbook, + Dialogue, // NEW +} +``` + +### 2. Dialogue Metadata (SQLite) + +Store in `documents` table: +- `doc_type`: "dialogue" +- `title`: Dialogue title +- `status`: "complete" (dialogues don't have status transitions) +- `file_path`: Path to .dialogue.md file + +Store in `metadata` table: +- `date`: When dialogue occurred +- `participants`: Who was involved (e.g., "Claude, Eric") +- `linked_rfc`: RFC this dialogue relates to (optional) +- `topic`: Short description of what was discussed + +### 3. New Tool: `blue_dialogue_create` + +``` +blue_dialogue_create title="realm-design-session" linked_rfc="cross-repo-realms" +``` + +Creates: +- Entry in documents table +- Metadata entries +- Skeleton .dialogue.md file + +### 4. Dialogue File Format + +```markdown +# Dialogue: Realm Design Session + +| | | +|---|---| +| **Date** | 2026-01-24 | +| **Participants** | Claude, Eric | +| **Topic** | Designing cross-repo coordination | +| **Linked RFC** | [cross-repo-realms](../rfcs/0001-cross-repo-realms.md) | + +--- + +## Context + +[Why this dialogue happened] + +## Key Decisions + +- Decision 1 +- Decision 2 + +## Transcript + +[Full conversation or summary] + +--- + +*Extracted by Blue* +``` + +### 5. Keep Content in Markdown + +Unlike other doc types, dialogue content stays primarily in markdown: +- Full transcripts can be large +- Human-readable format preferred +- Git diff friendly + +SQLite stores metadata only for: +- Fast searching +- Relationship tracking +- Listing/filtering + +### 6. New Tool: `blue_dialogue_get` + +``` +blue_dialogue_get title="realm-design-session" +``` + +Returns dialogue metadata and file path. + +### 7. New Tool: `blue_dialogue_list` + +``` +blue_dialogue_list linked_rfc="cross-repo-realms" +``` + +Returns all dialogues, optionally filtered by linked RFC. + +### 8. Integration with `blue_extract_dialogue` + +Existing `blue_extract_dialogue` extracts text from Claude JSONL. Extend to: + +``` +blue_extract_dialogue task_id="abc123" save_as="realm-design-session" linked_rfc="cross-repo-realms" +``` + +- Extract dialogue from JSONL +- Create .dialogue.md file +- Register in SQLite with metadata + +### 9. Migration of Existing Dialogues + +On first run, scan `docs/dialogues/` for `.dialogue.md` files: +- Parse frontmatter for metadata +- Register in documents table +- Preserve file locations + +## Security Note + +Dialogues may contain sensitive information discussed during development. Before committing: +- Review for credentials, API keys, or secrets +- Use `[REDACTED]` for sensitive values +- Consider if full transcript is needed vs summary + +## Example Transcript Section + +```markdown +## Transcript + +**Eric**: How should we handle authentication for the API? + +**Claude**: I'd recommend JWT tokens with short expiry. Here's why: +1. Stateless - no session storage needed +2. Can include claims for authorization +3. Easy to invalidate by changing signing key + +**Eric**: What about refresh tokens? + +**Claude**: Store refresh tokens in httpOnly cookies. When access token expires, +use refresh endpoint to get new pair. This balances security with UX. + +**Decision**: Use JWT + refresh token pattern. +``` + +## Implementation + +1. Add `DocType::Dialogue` to enum +2. Create `blue_dialogue_create` handler +3. Create `blue_dialogue_list` handler +4. Update `blue_search` to include dialogues +5. Add dialogue markdown generation + +## Test Plan + +- [ ] Create dialogue with metadata +- [ ] Link dialogue to RFC +- [ ] Dialogue without linked RFC works +- [ ] Search finds dialogues by title/topic +- [ ] List dialogues by RFC works +- [ ] List all dialogues works +- [ ] Get specific dialogue returns metadata +- [ ] Dialogue content stays in markdown +- [ ] Metadata stored in SQLite +- [ ] Existing dialogues migrated on first run +- [ ] Extract dialogue from JSONL creates proper entry + +--- + +*"Right then. Let's get to it."* + +— Blue diff --git a/.blue/repos/blue/docs/rfcs/0002-runbook-action-lookup.md b/.blue/repos/blue/docs/rfcs/0002-runbook-action-lookup.md new file mode 100644 index 0000000..9d2c190 --- /dev/null +++ b/.blue/repos/blue/docs/rfcs/0002-runbook-action-lookup.md @@ -0,0 +1,227 @@ +# RFC 0002: Runbook Action Lookup + +| | | +|---|---| +| **Status** | Draft | +| **Date** | 2026-01-24 | +| **Source Spike** | runbook-driven-actions | + +--- + +## Summary + +No way to discover and follow runbooks when performing repo actions. Claude guesses instead of following documented procedures for docker builds, deploys, releases, etc. + +## Proposal + +### 1. Action Tags in Runbooks + +Add `actions` field to runbook frontmatter: + +```markdown +# Runbook: Docker Build + +| | | +|---|---| +| **Status** | Active | +| **Actions** | docker build, build image, container build | +``` + +Store actions in SQLite metadata table for fast lookup. + +### 2. New Tool: `blue_runbook_lookup` + +``` +blue_runbook_lookup action="docker build" +``` + +Returns structured response: + +```json +{ + "found": true, + "runbook": { + "title": "Docker Build", + "file": ".blue/docs/runbooks/docker-build.md", + "actions": ["docker build", "build image", "container build"], + "operations": [ + { + "name": "Build Production Image", + "steps": ["...", "..."], + "verification": "docker images | grep myapp", + "rollback": "docker rmi myapp:latest" + } + ] + }, + "hint": "Follow the steps above. Use verification to confirm success." +} +``` + +If no match: `{ "found": false, "hint": "No runbook found. Proceed with caution." }` + +### 3. New Tool: `blue_runbook_actions` + +List all registered actions: + +``` +blue_runbook_actions +``` + +Returns: +```json +{ + "actions": [ + { "action": "docker build", "runbook": "Docker Build" }, + { "action": "deploy staging", "runbook": "Deployment" }, + { "action": "run tests", "runbook": "Testing" } + ] +} +``` + +### 4. Matching Algorithm + +Word-based matching with priority: + +1. **Exact match** - "docker build" matches "docker build" (100%) +2. **All words match** - "docker" matches "docker build" (90%) +3. **Partial words** - "build" matches "docker build" (80%) + +If multiple runbooks match, return highest priority. Ties broken by most specific (more words in action). + +### 5. Schema + +```sql +-- In metadata table +INSERT INTO metadata (document_id, key, value) +VALUES (runbook_id, 'action', 'docker build'); + +-- Multiple actions = multiple rows +INSERT INTO metadata (document_id, key, value) +VALUES (runbook_id, 'action', 'build image'); +``` + +### 6. Update `blue_runbook_create` + +``` +blue_runbook_create title="Docker Build" actions=["docker build", "build image"] +``` + +- Accept `actions` array parameter +- Store each action in metadata table +- Include in generated markdown + +### 7. CLAUDE.md Guidance + +Document the pattern for repos: + +```markdown +## Runbooks + +Before executing build, deploy, or release operations: + +1. Check for runbook: `blue_runbook_lookup action="docker build"` +2. If found, follow the documented steps +3. Use verification commands to confirm success +4. If something fails, check rollback procedures + +Available actions: `blue_runbook_actions` +``` + +## Security Note + +Runbooks should **never** contain actual credentials or secrets. Use placeholders: + +```markdown +**Steps**: +1. Export credentials: `export API_KEY=$YOUR_API_KEY` +2. Run deploy: `./deploy.sh` +``` + +Not: +```markdown +**Steps**: +1. Run deploy: `API_KEY=abc123 ./deploy.sh` # WRONG! +``` + +## Example Runbook + +```markdown +# Runbook: Docker Build + +| | | +|---|---| +| **Status** | Active | +| **Actions** | docker build, build image, container build | +| **Owner** | Platform Team | + +--- + +## Overview + +Build and tag Docker images for the application. + +## Prerequisites + +- [ ] Docker installed and running +- [ ] Access to container registry +- [ ] `.env` file configured + +## Common Operations + +### Operation: Build Production Image + +**When to use**: Preparing for deployment + +**Steps**: +1. Ensure on correct branch: `git branch --show-current` +2. Pull latest: `git pull origin main` +3. Build image: `docker build -t myapp:$(git rev-parse --short HEAD) .` +4. Tag as latest: `docker tag myapp:$(git rev-parse --short HEAD) myapp:latest` + +**Verification**: +```bash +docker images | grep myapp +docker run --rm myapp:latest --version +``` + +**Rollback**: +```bash +docker rmi myapp:latest +docker tag myapp:previous myapp:latest +``` + +## Troubleshooting + +### Symptom: Build fails with "no space left" + +**Resolution**: +1. `docker system prune -a` +2. Retry build +``` + +## Implementation + +1. Add `actions` parameter to `blue_runbook_create` +2. Store actions in metadata table +3. Implement `blue_runbook_lookup` with matching algorithm +4. Implement `blue_runbook_actions` for discovery +5. Parse runbook markdown to extract operations +6. Update runbook markdown generation + +## Test Plan + +- [ ] Create runbook with actions tags +- [ ] Lookup by exact action match +- [ ] Lookup by partial match (word subset) +- [ ] No match returns gracefully +- [ ] Multiple runbooks - highest priority wins +- [ ] List all actions works +- [ ] Actions stored in SQLite metadata +- [ ] Operations parsed from markdown correctly +- [ ] Malformed runbook returns partial data gracefully + +--- + +*"Right then. Let's get to it."* + +— Blue diff --git a/.blue/repos/blue/docs/rfcs/0003-per-repo-blue-folders.md b/.blue/repos/blue/docs/rfcs/0003-per-repo-blue-folders.md new file mode 100644 index 0000000..2981dcc --- /dev/null +++ b/.blue/repos/blue/docs/rfcs/0003-per-repo-blue-folders.md @@ -0,0 +1,155 @@ +# RFC 0003: Per Repo Blue Folders + +| | | +|---|---| +| **Status** | Draft | +| **Date** | 2026-01-24 | +| **Source Spike** | per-repo-blue-folder | + +--- + +## Summary + +Currently all docs flow to one central .blue folder. Each repo should have its own .blue folder so docs live with code and git tracking works naturally. + +## Current Behavior + +``` +blue/ # Central repo +├── .blue/ +│ ├── repos/ +│ │ ├── blue/docs/... # Blue's docs +│ │ └── other-repo/docs/ # Other repo's docs (wrong!) +│ └── data/ +│ └── blue/blue.db +``` + +All repos' docs end up in the blue repo's `.blue/repos/`. + +## Proposed Behavior + +``` +repo-a/ +├── .blue/ +│ ├── docs/ +│ │ ├── rfcs/ +│ │ ├── spikes/ +│ │ └── runbooks/ +│ └── blue.db +└── src/... + +repo-b/ +├── .blue/ +│ ├── docs/... +│ └── blue.db +└── src/... +``` + +Each repo has its own `.blue/` with its own docs and database. + +## Changes Required + +### 1. Simplify BlueHome structure + +```rust +pub struct BlueHome { + pub root: PathBuf, // Repo root + pub blue_dir: PathBuf, // .blue/ + pub docs_path: PathBuf, // .blue/docs/ + pub db_path: PathBuf, // .blue/blue.db +} +``` + +### 2. Change detect_blue behavior + +- Find git repo root for current directory +- Look for `.blue/` there (don't search upward beyond repo) +- Auto-create on first blue command (no `blue init` required) + +**Edge cases:** +- No git repo: Create `.blue/` in current directory with warning +- Monorepo: One `.blue/` at git root (packages share it) +- Subdirectory: Always resolve to git root + +### 3. Flatten docs structure + +Before: `.blue/repos//docs/rfcs/` +After: `.blue/docs/rfcs/` + +No need for project subdirectory when per-repo. + +### 4. Migration + +Automatic on first run: + +1. Detect old structure (`.blue/repos/` exists) +2. Find docs for current project in `.blue/repos//docs/` +3. Move to `.blue/docs/` +4. Migrate database entries +5. Clean up empty directories +6. Log what was migrated + +**Conflict resolution:** If docs exist in both locations, prefer newer by mtime. + +## Git Tracking + +Repos should commit their `.blue/` folder: + +**Track:** +- `.blue/docs/**` - RFCs, spikes, runbooks, etc. +- `.blue/blue.db` - SQLite database (source of truth) +- `.blue/config.yaml` - Configuration + +**Gitignore:** +- `.blue/*.db-shm` - SQLite shared memory (transient) +- `.blue/*.db-wal` - SQLite write-ahead log (transient) + +Recommended `.gitignore` addition: +``` +# Blue transient files +.blue/*.db-shm +.blue/*.db-wal +``` + +## Cross-Repo Coordination + +The daemon/realm system (RFC 0001) handles cross-repo concerns: +- Central daemon tracks active sessions +- Realms coordinate contracts between repos +- Each repo remains self-contained + +## FAQ + +**Q: Do I need to run `blue init`?** +A: No. Blue auto-creates `.blue/` on first command. + +**Q: What about my existing docs in the central location?** +A: Auto-migrated on first run. Check git status to verify. + +**Q: Should I commit `.blue/blue.db`?** +A: Yes. It's the source of truth for your project's Blue state. + +**Q: What if I'm in a monorepo?** +A: One `.blue/` at the git root. All packages share it. + +**Q: Can I use Blue without git?** +A: Yes, but with a warning. `.blue/` created in current directory. + +**Q: How do I see cross-repo status?** +A: Use `blue realm_status` (requires daemon running). + +## Test Plan + +- [ ] New repo gets `.blue/` on first blue command +- [ ] Docs created in repo's own `.blue/docs/` +- [ ] Database at `.blue/blue.db` +- [ ] Old structure migrated automatically +- [ ] Realm/daemon still works across repos +- [ ] No git repo falls back gracefully with warning +- [ ] Monorepo uses single `.blue/` at root + +--- + +*"Right then. Let's get to it."* + +— Blue diff --git a/.blue/repos/blue/docs/spikes/2026-01-24-per-repo-blue-folder.md b/.blue/repos/blue/docs/spikes/2026-01-24-per-repo-blue-folder.md new file mode 100644 index 0000000..6f31a23 --- /dev/null +++ b/.blue/repos/blue/docs/spikes/2026-01-24-per-repo-blue-folder.md @@ -0,0 +1,17 @@ +# Spike: Per Repo Blue Folder + +| | | +|---|---| +| **Status** | Complete | +| **Date** | 2026-01-24 | +| **Time Box** | 1 hour | + +--- + +## Question + +Should each repo have its own .blue folder with docs, or centralize in one location? What are the tradeoffs and what changes are needed? + +--- + +*Investigation notes by Blue* diff --git a/.blue/repos/blue/docs/spikes/2026-01-24-runbook-driven-actions.md b/.blue/repos/blue/docs/spikes/2026-01-24-runbook-driven-actions.md new file mode 100644 index 0000000..8c110ef --- /dev/null +++ b/.blue/repos/blue/docs/spikes/2026-01-24-runbook-driven-actions.md @@ -0,0 +1,17 @@ +# Spike: Runbook Driven Actions + +| | | +|---|---| +| **Status** | Complete | +| **Date** | 2026-01-24 | +| **Time Box** | 2 hours | + +--- + +## Question + +How can runbooks guide Claude Code through repo actions (docker builds, deploys, tests) so it follows the documented steps rather than guessing? + +--- + +*Investigation notes by Blue*