diff --git a/CLAUDE.md b/CLAUDE.md
index 66b19d8..f981e52 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -89,7 +89,11 @@ Each file in `claude/commands/{name}.md` is a tiny wrapper that points at `.awos
## Architecture: Document-Centric Workflow
-AWOS is **spec-driven** — all project state lives in markdown files under `context/` in the user's project, not in chat history. An AI agent can rehydrate full context by reading the files alone. The canonical flow (each command is a markdown prompt under `commands/`):
+AWOS is **spec-driven** — all project state lives in markdown files under `context/` in the user's project, not in chat history. An AI agent can rehydrate full context by reading the files alone.
+
+**Brownfield projects** get automatic codebase awareness. `/awos:product` detects existing source code (during Creation Mode only) and creates `context/product/brownfield.md` with triaged findings about purpose, audience, and features. `/awos:roadmap` and `/awos:architecture` read that file and run their own focused explorations (capabilities and tech stack respectively), passing prior findings to avoid duplicate questions. All findings are triaged with the user (accept / correct / reject). `/awos:architecture` removes the file after all knowledge is absorbed into the product, roadmap, and architecture documents.
+
+The canonical flow (each command is a markdown prompt under `commands/`):
```
/awos:product → /awos:roadmap → /awos:architecture → /awos:hire
diff --git a/README.md b/README.md
index 4bf1391..9106cbe 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,8 @@ npx @provectusinc/awos
This sets up the `.awos/` directory (commands, templates, scripts), the `.claude/commands/awos/` wrappers, and the `context/` directory where your project documents will live. It also registers the AWOS plugin marketplace in your project settings.
> **Running on an existing codebase?** Start with an AI readiness audit to understand how AI-friendly your project is. Install the plugin with `/plugin install awos@awos-marketplace`, then run `/awos:ai-readiness-audit` to get a scored assessment with actionable recommendations for improvement. [Learn more](plugins/awos/README.md)
+>
+> AWOS integrates seamlessly with existing projects — the setup commands auto-detect your codebase and use it as context, so you won't start from a blank slate.
### Step 2: Foundation Setup
diff --git a/commands/architecture.md b/commands/architecture.md
index 73cea4f..284ba22 100644
--- a/commands/architecture.md
+++ b/commands/architecture.md
@@ -19,6 +19,7 @@ Your task is to manage the architecture file located at `context/product/archite
- **Template File:** `.awos/templates/architecture-template.md` (The required structure).
- **Prerequisite Input 1:** `context/product/product-definition.md` (The "what" and "why").
- **Prerequisite Input 2:** `context/product/roadmap.md` (The implementation phases).
+- **Optional Input:** `context/product/brownfield.md` (produced by `/awos:product`, extended by `/awos:roadmap`; deleted at end of this command).
- **Primary Input/Output:** `context/product/architecture.md` (The file to create or update).
---
@@ -49,12 +50,42 @@ Follow this logic precisely.
## Scenario 1: Creation Mode
1. Read and synthesize the product definition and roadmap, paying close attention to features planned for Phase 1.
-2. Work through the template section by section — not all at once.
+2. **Brownfield context.** Check if `context/product/brownfield.md` exists (produced by `/awos:product` when it detects an existing codebase). If it does:
+
+ a. Read `context/product/brownfield.md`.
+
+ b. Construct the Explore prompt by reading `context/product/brownfield.md` and embedding its full content between `` and `` tags. Then launch an `Explore` agent focused on the technology stack:
+
+ ```text
+ Agent(subagent_type="Explore", description="Discover existing tech stack", prompt="
+ Explore this codebase and document the existing technology stack. Focus on:
+ - Languages and frameworks (with versions from config files)
+ - Databases, ORMs, and data stores
+ - Infrastructure (Docker, cloud configs, deployment scripts)
+ - External services and APIs (auth providers, payment, analytics)
+ - Testing frameworks and tools
+ - Build tools, bundlers, CI/CD
+
+ The following findings were already confirmed by the user — do not repeat them:
+
+
+ {paste the full current contents of context/product/brownfield.md here}
+
+
+ Report only NEW findings not covered above. For each technology found, cite the file paths that evidence it. Be concise — report findings as bullet points.
+ ")
+ ```
+
+ c. Triage new findings with the user. Group related findings by category and use `AskUserQuestion` to batch up to four per call. For each finding, offer **Accept** and **Reject** as options. The user can also select "Other" to provide free-text feedback — treat it according to intent (correction, substitution, partial accept, or any other reaction). Discard rejected findings. Append accepted and corrected findings to `context/product/brownfield.md` under a `## Technology` heading. For corrected findings, record the corrected version, not the original.
+
+ d. Use the confirmed technology findings as the default for each section, but still walk every section with the user. The interview still covers every area; the exploration gives better defaults, not fewer questions.
+
+3. Work through the template section by section — not all at once.
- For each architectural area, propose a concrete title from the template placeholder.
- - For each component, propose a specific technology with one or more alternatives, justified by the project context.
+ - For each component, propose a specific technology with one or more alternatives, justified by the project context. When brownfield findings provided a known technology, present it as the default.
- If the user is unsure, ask clarifying questions about team skills, budget, or priorities. Do not proceed until the current section is confirmed.
- Repeat for every architectural area (Data, Infrastructure, etc.).
-3. Once all sections are confirmed, proceed to **Step 3: Finalization**.
+4. Once all sections are confirmed, proceed to **Step 3: Finalization**.
---
@@ -84,3 +115,9 @@ Give the user a quick read on whether the stack already has specialist agents
3. Report the saved path and the next commands:
- `/awos:hire` (always — it owns the canonical coverage report and installs missing specialists).
- `/awos:spec` after `/awos:hire`.
+
+---
+
+### Step 5: Brownfield Cleanup
+
+If `context/product/brownfield.md` exists, delete it. By this point all brownfield knowledge has been absorbed into `product-definition.md`, `roadmap.md`, and `architecture.md` — the brownfield file is no longer needed.
diff --git a/commands/product.md b/commands/product.md
index 101fc7f..55eb5ae 100644
--- a/commands/product.md
+++ b/commands/product.md
@@ -30,6 +30,7 @@ Your primary task is to **fill in** a product definition template using a guided
# OUTPUTS
1. **`context/product/product-definition.md`:** The complete, non-technical product definition, created by filling in the template.
+2. **Optional Output:** `context/product/brownfield.md`. Created on brownfield projects only. Downstream commands (`/awos:roadmap`, `/awos:architecture`) extend and eventually delete this file.
---
@@ -62,14 +63,34 @@ First, check if the file `context/product/product-definition.md` exists.
### Step 2B: Creation Mode
-1. If `` is non-empty, briefly note that you'll use it as a starting point, then refine from there.
-2. Walk the user through the sections of the template, explaining each one.
+1. **Brownfield detection.** Check whether the project already has source code by looking for common indicators (`src/`, `app/`, `lib/`, `package.json`, `requirements.txt`, `go.mod`, `Cargo.toml`, `pom.xml`, `Gemfile`, `build.gradle`, `*.csproj`, `Makefile`, `CMakeLists.txt`, `setup.py`, `pyproject.toml`, or similar). If any are found, ask the user whether to run codebase exploration using `AskUserQuestion` with two options: **Yes, explore the codebase** ("Use existing code as context for the product definition") and **No, start from scratch** ("Treat this as a new project — ignore existing code"). If the user chooses to skip, proceed to step 2 as if no source code was found. Otherwise, run a comprehensive exploration before starting the interview:
+
+ a. Launch an `Explore` agent focused on the product domain:
+
+ ```text
+ Agent(subagent_type="Explore", description="Understand existing product", prompt="
+ Explore this codebase and determine what this project does. Focus on:
+ - Purpose and problem being solved (README, docs, package metadata, comments)
+ - Target audience signals (UI copy, API design, documentation tone, onboarding flow)
+ - Main features and capabilities (entry points, routes, commands, key modules)
+ - User journey (how someone uses this from start to finish)
+
+ For each finding, cite the file paths that evidence it. Be concise — report findings as bullet points.
+ ")
+ ```
+
+ b. Triage findings with the user. Group related findings by category (e.g. all features in one call, audience signals in another) and use `AskUserQuestion` to batch up to four per call. For each finding, offer **Accept** and **Reject** as options. The user can also select "Other" to provide free-text feedback — treat it according to intent (correction, substitution, partial accept, or any other reaction). Discard rejected findings.
+
+ c. Create `context/product/brownfield.md` with a `## Product` heading. List all accepted and corrected findings under it — for corrected findings, record the corrected version, not the original. If every finding was rejected or the exploration surfaced nothing, still create the file with an empty `## Product` section; downstream commands (`/awos:roadmap`, `/awos:architecture`) key on the file's existence to run their own explorations.
+
+2. If `` is non-empty, briefly note that you'll use it as a starting point, then refine from there.
+3. Walk the user through the sections of the template. When step 1 produced brownfield findings, use the Product section to propose draft answers — frame questions as "does this match what you intend, or would you change it?" rather than asking from a blank slate. The interview still covers every section; the exploration gives better defaults, not fewer questions.
- **Project Name & Vision:** Ask for the project's name and its core purpose.
- **Target Audience & Personas:** Ask who the product is for and help create one simple persona.
- **Success Metrics:** Ask how they will measure the product's impact on the user.
- **Core Features & User Journey:** Ask for the 3-5 most important high-level features and a simple user workflow.
- **Project Boundaries:** Ask what is essential for the first version (In-Scope) and what can wait (Out-of-Scope).
-3. Once all sections are complete, proceed to **Step 3: File Generation**.
+4. Once all sections are complete, proceed to **Step 3: File Generation**.
---
diff --git a/commands/roadmap.md b/commands/roadmap.md
index 1bdadab..65bd3df 100644
--- a/commands/roadmap.md
+++ b/commands/roadmap.md
@@ -21,6 +21,7 @@ Your task is to manage the product roadmap file located at `context/product/road
- **Template File:** `.awos/templates/roadmap-template.md`. This is the required structure for the roadmap.
- **Prerequisite Input:** `context/product/product-definition.md`. This file MUST exist.
+- **Optional Input/Output:** `context/product/brownfield.md` (produced by `/awos:product` on brownfield projects; this command appends a `## Capabilities` section).
- **Primary Input/Output:** `context/product/roadmap.md`. This is the file you will create or update.
---
@@ -51,9 +52,36 @@ Follow this logic precisely.
## Scenario 1: Creation Mode
1. Read `context/product/product-definition.md` and the template at `.awos/templates/roadmap-template.md`.
-2. Generate a proposed roadmap by populating the template structure with the product definition's Core Features, grouped into logical sequential phases.
-3. Present the full draft to the user and ask for feedback.
-4. Iterate until the user is satisfied, then proceed to **Step 3: Finalization**.
+2. **Brownfield context.** Check if `context/product/brownfield.md` exists (produced by `/awos:product` when it detects an existing codebase). If it does:
+
+ a. Read `context/product/brownfield.md`.
+
+ b. Construct the Explore prompt by reading `context/product/brownfield.md` and embedding its full content between `` and `` tags. Then launch an `Explore` agent focused on existing capabilities:
+
+ ```text
+ Agent(subagent_type="Explore", description="Assess existing capabilities", prompt="
+ Explore this codebase and assess what's already built. Focus on:
+ - Features that are fully implemented and working (with evidence: routes, UI, tests)
+ - Features that appear partially implemented or scaffolded
+ - TODOs, FIXMEs, or planned features mentioned in code or docs
+
+ The following findings were already confirmed by the user — do not repeat them:
+
+
+ {paste the full current contents of context/product/brownfield.md here}
+
+
+ Report only NEW findings not covered above. For each finding, cite the file paths that evidence it. Be concise — report findings as bullet points.
+ ")
+ ```
+
+ c. Triage new findings with the user. Group related findings by category and use `AskUserQuestion` to batch up to four per call. For each finding, offer **Accept** and **Reject** as options. The user can also select "Other" to provide free-text feedback — treat it according to intent (correction, substitution, partial accept, or any other reaction). Discard rejected findings. Append accepted and corrected findings to `context/product/brownfield.md` under a `## Capabilities` heading. For corrected findings, record the corrected version, not the original.
+
+ d. Use the full set of confirmed capabilities (from brownfield.md) to anchor the roadmap: existing capabilities are noted as already done, and new phases focus on what comes next. Feed this into the roadmap generation in the next step.
+
+3. Generate a proposed roadmap by populating the template structure with the product definition's Core Features, grouped into logical sequential phases.
+4. Present the full draft to the user and ask for feedback.
+5. Iterate until the user is satisfied, then proceed to **Step 3: Finalization**.
---
diff --git a/tests/lint-prompts.test.js b/tests/lint-prompts.test.js
index e658340..3539859 100644
--- a/tests/lint-prompts.test.js
+++ b/tests/lint-prompts.test.js
@@ -657,6 +657,211 @@ test('SDD-07 recognizes the dual-model QA coverage', () => {
);
});
+// ---------------------------------------------------------------------------
+// Brownfield awareness contracts
+// ---------------------------------------------------------------------------
+
+test('product.md creates context/product/brownfield.md on brownfield detection', () => {
+ // /awos:product is the entry point for brownfield detection. When it finds
+ // source code indicators it must explore the codebase and write accepted
+ // findings to context/product/brownfield.md. Downstream commands (roadmap,
+ // architecture) depend on this file existing to avoid duplicate exploration.
+ const body = readUtf8(path.join(commandsDir, 'product.md'));
+ assert.ok(
+ body.includes('context/product/brownfield.md'),
+ 'commands/product.md must reference context/product/brownfield.md as the brownfield findings destination'
+ );
+ assert.ok(
+ /with a `## Product` heading/.test(body),
+ 'commands/product.md must write brownfield findings under a "## Product" heading (anchored to brownfield.md context)'
+ );
+});
+
+test('product.md brownfield detection includes source code indicators', () => {
+ // The whole brownfield entry point depends on product.md checking for
+ // source code indicators. If the indicator list is hollowed out,
+ // brownfield never fires and the entire downstream chain goes dead.
+ const body = readUtf8(path.join(commandsDir, 'product.md'));
+ assert.ok(
+ body.includes('package.json'),
+ 'commands/product.md must check for package.json as a brownfield indicator'
+ );
+ assert.ok(
+ body.includes('`src/`'),
+ 'commands/product.md must check for src/ as a brownfield indicator'
+ );
+});
+
+test('roadmap.md reads brownfield.md and appends a Capabilities section', () => {
+ // /awos:roadmap reads the brownfield file produced by /awos:product and
+ // runs its own focused exploration for capabilities. It must append its
+ // findings under a "## Capabilities" heading so /awos:architecture can
+ // see the accumulated context.
+ const body = readUtf8(path.join(commandsDir, 'roadmap.md'));
+ assert.ok(
+ body.includes('context/product/brownfield.md'),
+ 'commands/roadmap.md must reference context/product/brownfield.md to consume and extend brownfield findings'
+ );
+ assert.ok(
+ /under a `## Capabilities` heading/.test(body),
+ 'commands/roadmap.md must append brownfield findings under a "## Capabilities" heading (anchored to brownfield.md context)'
+ );
+});
+
+test('architecture.md reads brownfield.md and appends a Technology section', () => {
+ // /awos:architecture reads the accumulated brownfield file and runs a
+ // focused exploration for the tech stack. It must append its findings
+ // under a "## Technology" heading.
+ const body = readUtf8(path.join(commandsDir, 'architecture.md'));
+ assert.ok(
+ body.includes('context/product/brownfield.md'),
+ 'commands/architecture.md must reference context/product/brownfield.md to consume and extend brownfield findings'
+ );
+ assert.ok(
+ /under a `## Technology` heading/.test(body),
+ 'commands/architecture.md must append brownfield findings under a "## Technology" heading (anchored to brownfield.md context)'
+ );
+});
+
+test('architecture.md conditionally removes brownfield.md after onboarding completes', () => {
+ // /awos:architecture is the last command that uses brownfield.md. By this
+ // point all brownfield knowledge has been absorbed into product-definition.md,
+ // roadmap.md, and architecture.md. The brownfield file must be conditionally
+ // cleaned up here, not deferred to /awos:hire.
+ const body = readUtf8(path.join(commandsDir, 'architecture.md'));
+ assert.ok(
+ /If `context\/product\/brownfield\.md` exists, delete it/i.test(body),
+ 'commands/architecture.md must conditionally delete context/product/brownfield.md (guard + delete in one sentence)'
+ );
+});
+
+test('brownfield commands launch Explore agents', () => {
+ // The actual mechanism for brownfield awareness is the Explore agent.
+ // Without it, the headings and triage prose are dead letters. Assert
+ // that all three commands invoke the Explore subagent.
+ for (const cmd of ['product.md', 'roadmap.md', 'architecture.md']) {
+ const body = readUtf8(path.join(commandsDir, cmd));
+ assert.ok(
+ /subagent_type="Explore"/.test(body),
+ `commands/${cmd} must launch an Explore agent for brownfield analysis`
+ );
+ }
+});
+
+test('brownfield exploration passes existing findings to avoid duplicates', () => {
+ // Each downstream exploration (roadmap, architecture) must pass the
+ // current brownfield.md content to the Explore agent so it skips
+ // already-confirmed findings. The literal tag is
+ // the contract — if renamed, the Explore prompt silently ignores it.
+ // The "Report only NEW" instruction makes the tag actually work.
+ for (const cmd of ['roadmap.md', 'architecture.md']) {
+ const body = readUtf8(path.join(commandsDir, cmd));
+ assert.ok(
+ body.includes(''),
+ `commands/${cmd} must pass existing brownfield findings inside tags to the Explore agent`
+ );
+ assert.ok(
+ /Report only NEW/i.test(body),
+ `commands/${cmd} must instruct the Explore agent to report only NEW findings`
+ );
+ }
+});
+
+test('product.md does not consume existing_findings (it is the first command)', () => {
+ // product.md is always first in the brownfield chain — it must not
+ // consume since there are none before it. If it
+ // gained that tag, it would imply a circular dependency.
+ const body = readUtf8(path.join(commandsDir, 'product.md'));
+ assert.ok(
+ !//.test(body),
+ 'commands/product.md must not contain — it is the first brownfield command'
+ );
+});
+
+test('brownfield commands use accept/reject triage for findings', () => {
+ // All three brownfield-aware commands must triage findings with the
+ // user offering Accept and Reject options. The user can also provide
+ // free-text via the built-in "Other" field.
+ for (const cmd of ['product.md', 'roadmap.md', 'architecture.md']) {
+ const body = readUtf8(path.join(commandsDir, cmd));
+ assert.ok(
+ /Accept/.test(body),
+ `commands/${cmd} must offer "Accept" as a triage option for brownfield findings`
+ );
+ assert.ok(
+ /Reject/.test(body),
+ `commands/${cmd} must offer "Reject" as a triage option for brownfield findings`
+ );
+ }
+});
+
+test('brownfield exploration includes fill-in slot for brownfield.md content', () => {
+ // The fill-in slot tells the agent to interpolate brownfield.md contents
+ // into the Explore prompt. Without it, is empty and
+ // dedup silently dies while the tag still matches.
+ for (const cmd of ['roadmap.md', 'architecture.md']) {
+ const body = readUtf8(path.join(commandsDir, cmd));
+ assert.ok(
+ /\{paste the full current contents of context\/product\/brownfield\.md here\}/.test(
+ body
+ ),
+ `commands/${cmd} must include the fill-in slot for brownfield.md content interpolation`
+ );
+ }
+});
+
+test('brownfield commands append (not overwrite) findings to brownfield.md', () => {
+ // Each downstream command must append to brownfield.md, not overwrite it.
+ // The append verb + heading together protect the accumulate-don't-overwrite
+ // contract.
+ const roadmapBody = readUtf8(path.join(commandsDir, 'roadmap.md'));
+ assert.ok(
+ /Append.*under a `## Capabilities` heading/i.test(roadmapBody),
+ 'commands/roadmap.md must append findings under a ## Capabilities heading'
+ );
+ const archBody = readUtf8(path.join(commandsDir, 'architecture.md'));
+ assert.ok(
+ /Append.*under a `## Technology` heading/i.test(archBody),
+ 'commands/architecture.md must append findings under a ## Technology heading'
+ );
+});
+
+test('brownfield commands guard exploration on brownfield.md existence', () => {
+ // Roadmap and architecture must check if brownfield.md exists before
+ // running their explorations. Without this guard, greenfield projects
+ // would attempt brownfield exploration.
+ for (const cmd of ['roadmap.md', 'architecture.md']) {
+ const body = readUtf8(path.join(commandsDir, cmd));
+ assert.ok(
+ /brownfield\.md` exists/.test(body),
+ `commands/${cmd} must guard brownfield exploration on brownfield.md existence`
+ );
+ }
+});
+
+test('product.md lets the user opt out of brownfield exploration', () => {
+ // Even when source code is detected, the user may want to start from
+ // scratch (e.g. reinitializing a project). product.md must ask before
+ // launching the Explore agent.
+ const body = readUtf8(path.join(commandsDir, 'product.md'));
+ assert.ok(
+ /start from scratch/i.test(body),
+ 'commands/product.md must offer a "start from scratch" option to skip brownfield exploration'
+ );
+});
+
+test('product.md creates brownfield.md even when all findings are rejected', () => {
+ // product.md must always create brownfield.md when a brownfield project is
+ // detected, even if the user rejects every finding. The file acts as a
+ // sentinel — downstream commands key on its existence to run their own
+ // explorations.
+ const body = readUtf8(path.join(commandsDir, 'product.md'));
+ assert.ok(
+ /still create the file/i.test(body),
+ 'commands/product.md must create brownfield.md even when all findings are rejected (sentinel behavior)'
+ );
+});
+
test('context/ references in prompts are internally consistent', () => {
// Build a writer/reader map by scanning all prompts. A path is considered
// consistent if every reference to it appears in at least one prompt — i.e.