--- name: brownfield description: "Scan and manage brownfield repository/worktree defaults for interviews" --- # /ouroboros:brownfield Scan a root directory for existing git repositories and linked worktrees, then manage default repos used as context in interviews. ## Usage ``` ooo brownfield # Scan repos and set defaults ooo brownfield scan # Scan only (no default selection) ooo brownfield defaults # Show current defaults ooo brownfield set 6,18,19 # Set defaults by repo numbers ooo brownfield detect [path] # Author mechanical.toml via one AI call ``` **Trigger keywords:** "brownfield", "scan repos", "default repos", "brownfield scan", "mechanical detect" --- ## How It Works ### Default flow (`ooo brownfield` with no args) **Step 1: Scan** Show scanning indicator: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Scanning for Existing Projects... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Looking for git repositories and worktrees up to two directories below the scan root. Local repos and repos with any remote name are eligible. This may take a moment... ``` **Implementation — use MCP tools only, do NOT use CLI or Python scripts:** **CRITICAL — deferred-schema guard (prevents "Invalid tool parameters"):** This skill can call `ouroboros_brownfield` across multiple turns (`scan`, `set_defaults`, `defaults`, and `set`). A deferred schema loaded for one turn is NOT guaranteed to remain loaded for the next. Immediately before EVERY `ouroboros_brownfield` call, re-run `tool discovery query: "+ouroboros brownfield"` (idempotent — a no-op when already loaded). If the load returns no matching tool (and the tool is not already callable — an empty load for an already-exposed tool is an expected no-op, not absence), stop with the MCP-not-available message instead of retrying the failing call. 1. Load the brownfield MCP tool: `tool discovery query: "+ouroboros brownfield"` 2. Call scan+register: ``` Tool: ouroboros_brownfield Arguments: { "action": "scan" } ``` This walks `scan_root` (up to two directory levels deep) for valid seed repos/worktrees and registers them in DB. Each repo or worktree found directly by the walk is registered self-only — Git worktree families are not expanded, so worktrees outside the depth-bounded walk (e.g. under `.ouroboros/worktrees`) are not pulled in. Existing defaults are preserved. The scan response `text` already contains a pre-formatted numbered list with `[default]` markers. **Do NOT make any additional MCP calls to list or query repos.** **Display the repos in a plain-text 2-column grid** (NOT a markdown table). Use a code block so columns align. Example: ``` Scan complete. 8 repositories registered. 1. repo-alpha 5. repo-epsilon 2. repo-bravo * 6. repo-foxtrot 3. repo-charlie 7. repo-golf * 4. repo-delta 8. repo-hotel ``` Include `*` markers for defaults exactly as they appear in the scan response. **If no repos found**, show: ``` No git repositories or worktrees found. ``` Then stop. ### Scan boundaries - The filesystem walk starts at `scan_root`; when omitted, `scan_root` defaults to the current user's home directory. - Repositories are discovered by walking directories inside `scan_root`, at most two levels deep (so `~/repo` and `~/group/repo` are found; deeper nesting is not). - Dot-prefixed directories and known noisy directories such as `node_modules` are not walked as seed locations. - Both normal repos (`.git` directory) and linked worktrees (`.git` file) are registered when the walk reaches them. Git worktree families are NOT expanded — a worktree is only registered if the walk finds it directly, not because its main repo's Git metadata reports it. - Local repos, repos without remotes, and repos whose remotes are not named `origin` are all eligible. **Step 2: Default Selection** **Do NOT use `AskUserQuestion` for this selection.** Two rendering constraints make it unusable here: - Assistant text emitted between tool calls (scan result → grid → question dialog) is not guaranteed to render, so the user may face the dialog without ever seeing the repo list. - Embedding the list in option `preview` fields does not work either — the preview box has a fixed height and silently truncates long lists ("N lines hidden"), and repo lists routinely exceed it. Instead, **end the turn with the repo grid as the final message** so its display is guaranteed, and collect the selection as a plain chat reply. Immediately below the grid (same message, same code block or right after it), append the selection prompt: **If defaults exist:** ``` Current defaults: (numbers ) Reply with repo numbers to change defaults (e.g. "6, 18, 19"), "keep" to keep the current defaults, or "none" to clear them. ``` **If no defaults exist:** ``` No defaults set. Reply with repo numbers to set defaults (e.g. "6, 18, 19"), or "none" to run interviews in greenfield mode. ``` Then **end the turn** — no tool calls after the grid. The RFC #1392 breadcrumb footer is still the last line of the message. On the next turn, parse the user's reply: - Numbers (any separator) → those indices - "keep" (defaults exist) → stop; no MCP call needed, confirm defaults unchanged - "none" → empty indices (clear all) - Anything else → ask again in plain text; do not guess Then re-run `tool discovery query: "+ouroboros brownfield"` and use ONE MCP call to update all defaults at once: ``` Tool: ouroboros_brownfield Arguments: { "action": "set_defaults", "indices": "" } ``` Example: if the user picks IDs 6, 18, 19 → `{ "action": "set_defaults", "indices": "6,18,19" }` This clears all existing defaults and sets the selected repos as default in one call. If "none" → `{ "action": "set_defaults", "indices": "" }` to clear all defaults. **Step 3: Confirmation** ``` Brownfield defaults updated! Defaults: grape, podo-app, podo-backend These repos will be used as context in interviews. ``` Or if "none" selected: ``` No default repos set. Interviews will run in greenfield mode. You can set defaults anytime with: ooo brownfield ``` Or if "keep" selected: ``` Defaults unchanged: ``` --- ### Subcommand: `scan` Scan only, no default selection prompt. Show the numbered list and stop. --- ### Subcommand: `defaults` Re-run `tool discovery query: "+ouroboros brownfield"`, then call: ``` Tool: ouroboros_brownfield Arguments: { "action": "scan" } ``` Display only the repos marked with `*` (defaults). If none, show: ``` No default repos set. Run 'ooo brownfield' to configure. ``` --- ### Subcommand: `set ` Directly set defaults without scanning. Parse the comma-separated indices from the user's input, re-run `tool discovery query: "+ouroboros brownfield"`, and call: ``` Tool: ouroboros_brownfield Arguments: { "action": "set_defaults", "indices": "" } ``` Show confirmation with updated defaults. --- ### Subcommand: `detect [path]` Runs one AI call against the target directory (defaults to the user's cwd) and writes `.ouroboros/mechanical.toml` with validated lint / build / test / static / coverage commands. Stage 1 of evaluation reads this file verbatim, so the toml is the authoritative Stage 1 contract — no hardcoded language presets exist anymore. Ouroboros auto-runs this detect the first time `ouroboros_evaluate` is invoked without a toml present, so most users never need to call it directly. Run it explicitly when: - you want to pre-author the toml before the first evaluate, - you moved to a new build tool and want to refresh (`--force`), - you want to review/edit the commands before Stage 1 trusts them. **Implementation:** invoke the CLI via Bash. ``` uvx --python '>=3.12' --from ouroboros-ai ouroboros detect [path] # or, if already installed: ouroboros detect [path] [--force] ``` Then print the resulting `.ouroboros/mechanical.toml` contents so the user can confirm the proposed commands or hand-edit them. If detect reports "could not propose any verifiable commands", surface the reason (no manifests found, LLM unavailable, every proposal dropped) and suggest the user write a minimal toml by hand — any single entry like `test = "pytest -q"` is enough to opt back in to Stage 1 for that check. ## RFC #1392 State Breadcrumb Footer Your final response MUST end with exactly one breadcrumb footer line: ``` ◆ → next: ``` Derive `` from live session state via `ouroboros_session_status` when that MCP projection is available; otherwise derive it from this skill's actual outcome. Never use a linear `Step N of M` footer because Ouroboros is an evolutionary loop. When the next action is genuinely a choice, list 2-3 honest options in the `next:` clause. The breadcrumb line must be the last line of the response.