From 1cb0a2141c938f53117c58643b61b03309d74ea8 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Mon, 13 Apr 2026 15:25:12 +0100 Subject: [PATCH 01/16] feat: add branch-based npm release workflow Automate npm prereleases from dev and stable releases from main so publishing follows a simple branch-based flow. Add local release verification, registry-based rc version resolution, and release documentation so package builds and publishes stay consistent in CI and locally. --- .github/workflows/release.yml | 74 ++++++++++++++++++++++ README.md | 11 ++++ docs/setup/RELEASING.md | 82 +++++++++++++++++++++++++ package.json | 5 ++ scripts/resolve-release-version.js | 99 ++++++++++++++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 docs/setup/RELEASING.md create mode 100644 scripts/resolve-release-version.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..2245a1f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,74 @@ +name: Release npm package + +on: + push: + branches: + - dev + - main + +concurrency: + group: npm-release-${{ github.ref_name }} + cancel-in-progress: false + +permissions: + contents: read + id-token: write + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + registry-url: https://registry.npmjs.org + + - name: Install dependencies + run: npm ci + + - name: Verify package is releasable + run: npm run release:check + + - name: Resolve publish version + id: resolve + run: node scripts/resolve-release-version.js "$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT" + + - name: Show resolved release plan + run: | + echo "branch=${GITHUB_REF_NAME}" + echo "package=${{ steps.resolve.outputs.package_name }}" + echo "channel=${{ steps.resolve.outputs.channel }}" + echo "version=${{ steps.resolve.outputs.version }}" + echo "publish_tag=${{ steps.resolve.outputs.publish_tag }}" + echo "should_publish=${{ steps.resolve.outputs.should_publish }}" + echo "reason=${{ steps.resolve.outputs.reason }}" + + - name: Apply publish version + if: steps.resolve.outputs.should_publish == 'true' + run: npm version "${{ steps.resolve.outputs.version }}" --no-git-tag-version + + - name: Publish package to npm + if: steps.resolve.outputs.should_publish == 'true' + run: npm publish --provenance --tag "${{ steps.resolve.outputs.publish_tag }}" + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Release summary + run: | + { + echo "## npm release" + echo "" + echo "- Branch: ${GITHUB_REF_NAME}" + echo "- Package: ${{ steps.resolve.outputs.package_name }}" + echo "- Channel: ${{ steps.resolve.outputs.channel }}" + echo "- Version: ${{ steps.resolve.outputs.version }}" + echo "- npm tag: ${{ steps.resolve.outputs.publish_tag }}" + echo "- Published: ${{ steps.resolve.outputs.should_publish }}" + echo "- Reason: ${{ steps.resolve.outputs.reason }}" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/README.md b/README.md index 1fcf811..622c6dd 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Quick links: - [Installation](docs/setup/INSTALLATION.md) - [Configuration](docs/setup/CONFIGURATION.md) +- [Releasing](docs/setup/RELEASING.md) - [Workflow Agents](docs/guides/AGENTS.md) - [Workflow Model](docs/guides/WORKFLOW.md) - [Plugin Tools](docs/guides/TOOLS.md) @@ -43,6 +44,16 @@ Quick links: - [Full Team Mode](docs/guides/TEAM_MODE_FULL.md) - [Documentation Structure](docs/core/documentation_structure.md) +## Release + +NomadWorks ships as the npm package `@neuralnomads/nomadworks`. + +- Local verification: `npm run release:check` +- Push to `dev`: auto-publish prerelease (`rc`) +- Push to `main`: auto-publish stable release + +For the full release setup, required secrets, and branch-based versioning behavior, see [Releasing](docs/setup/RELEASING.md). + ## Team Modes | Team Mode | Available Agents | Supported Task Complexity | Flow Guide | diff --git a/docs/setup/RELEASING.md b/docs/setup/RELEASING.md new file mode 100644 index 0000000..c9dcaf7 --- /dev/null +++ b/docs/setup/RELEASING.md @@ -0,0 +1,82 @@ +# Releasing + +NomadWorks publishes to npm as `@neuralnomads/nomadworks`. + +## Release Model + +- Versioning, build verification, and npm publishing are handled by the GitHub Actions workflow `Release npm package`. +- Pushes to `dev` automatically publish npm prereleases. +- Pushes to `main` automatically publish stable npm releases. +- The workflow does not commit or tag version changes back to the repository. It derives the publish version from `package.json` and npm's already-published versions. + +## Required Repository Secret + +Add this repository secret before publishing: + +- `NPM_TOKEN`: npm access token with permission to publish `@neuralnomads/nomadworks` + +## Workflow Behavior + +The release workflow performs these steps: + +1. Triggers automatically on pushes to `dev` and `main`. +2. Installs dependencies with `npm ci`. +3. Runs `npm run release:check`, which executes tests, builds `dist/`, and previews the publish tarball. +4. Resolves the publish version based on the current branch and npm registry history. +5. Applies that version locally with `npm version --no-git-tag-version`. +6. Publishes the package with `npm publish --provenance`. + +## Branch Behavior + +### `dev` + +- Publishes prereleases using the `rc` dist-tag. +- Reads the stable base version from `package.json`. +- Looks up already published versions on npm. +- Publishes the next version in the sequence: `-rc.N` + +Example: + +- `package.json`: `1.4.0` +- published prereleases: `1.4.0-rc.0`, `1.4.0-rc.1` +- next `dev` publish: `1.4.0-rc.2` + +### `main` + +- Publishes stable releases using the default `latest` dist-tag. +- Publishes the exact stable version in `package.json`. +- Skips publishing if that version already exists on npm. + +Example: + +- `package.json`: `1.4.0` +- push to `main` +- publish: `1.4.0` + +## Versioning Expectations + +- Keep `package.json` on a stable semver base such as `1.4.0`. +- Do not commit prerelease versions like `1.4.0-rc.2` into `package.json`. +- Use `dev` to publish release candidates for the current base version. +- When the package is ready, merge the versioned changes to `main` to publish the stable release. + +## Local Verification + +Before triggering a release, you can run the same verification locally: + +```bash +npm run release:check +``` + +This command: + +- runs the test suite +- builds `dist/` +- runs `npm pack --dry-run` to preview the package contents + +## Notes + +- `prepack` runs `npm run build`, so local `npm pack` and `npm publish` always include a fresh `dist/` build. +- `publishConfig.access` is set to `public` so the scoped package can publish correctly on npm. +- The prerelease counter is remembered via npm registry history, not via git tags or committed prerelease versions. +- If you need to dry-run a release locally without publishing, use `npm run release:check` and inspect the tarball preview output. diff --git a/package.json b/package.json index 761c56a..10da1d2 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,13 @@ "main": "dist/index.js", "scripts": { "build": "node scripts/build.js", + "prepack": "npm run build", + "release:check": "npm test && npm run build && npm pack --dry-run", "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js" }, + "publishConfig": { + "access": "public" + }, "files": [ "dist", "agents", diff --git a/scripts/resolve-release-version.js b/scripts/resolve-release-version.js new file mode 100644 index 0000000..9b4856c --- /dev/null +++ b/scripts/resolve-release-version.js @@ -0,0 +1,99 @@ +import { execFileSync } from "node:child_process"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); +const packageJson = JSON.parse(fs.readFileSync(path.join(ROOT, "package.json"), "utf8")); + +const branch = process.argv[2]; +const packageName = packageJson.name; +const baseVersion = packageJson.version; + +if (!branch) { + throw new Error("Branch name is required."); +} + +function fail(message) { + throw new Error(message); +} + +function isStableSemver(version) { + return /^\d+\.\d+\.\d+$/.test(version); +} + +function shellValue(value) { + return String(value).replace(/\r/g, " ").replace(/\n/g, " "); +} + +function loadPublishedVersions(name) { + try { + const raw = execFileSync("npm", ["view", name, "versions", "--json"], { + cwd: ROOT, + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"] + }).trim(); + + if (!raw) return []; + + const parsed = JSON.parse(raw); + if (Array.isArray(parsed)) return parsed; + if (typeof parsed === "string") return [parsed]; + return []; + } catch { + return []; + } +} + +const publishedVersions = loadPublishedVersions(packageName); + +let version = baseVersion; +let publishTag = "latest"; +let channel = "release"; +let shouldPublish = true; +let reason = "stable release from main"; + +if (branch === "dev") { + if (!isStableSemver(baseVersion)) { + fail(`dev prereleases require package.json version to be a stable base semver. Found '${baseVersion}'.`); + } + + const prefix = `${baseVersion}-rc.`; + const rcNumbers = publishedVersions + .filter(candidate => candidate.startsWith(prefix)) + .map(candidate => Number(candidate.slice(prefix.length))) + .filter(Number.isInteger) + .filter(candidate => candidate >= 0); + + const nextRc = rcNumbers.length === 0 ? 0 : Math.max(...rcNumbers) + 1; + version = `${baseVersion}-rc.${nextRc}`; + publishTag = "rc"; + channel = "prerelease"; + reason = rcNumbers.length === 0 + ? `first rc publish for ${baseVersion}` + : `incremented rc from ${Math.max(...rcNumbers)} to ${nextRc}`; +} else if (branch === "main") { + if (!isStableSemver(baseVersion)) { + fail(`main releases require package.json version to be stable semver. Found '${baseVersion}'.`); + } + + if (publishedVersions.includes(baseVersion)) { + shouldPublish = false; + reason = `version ${baseVersion} is already published on npm`; + } +} else { + fail(`Unsupported branch '${branch}'. Expected 'dev' or 'main'.`); +} + +const outputs = { + package_name: packageName, + version, + publish_tag: publishTag, + channel, + should_publish: shouldPublish, + reason +}; + +for (const [key, value] of Object.entries(outputs)) { + console.log(`${key}=${shellValue(value)}`); +} From 6c562c5e0027761daa28d6e6a1dcf165263d890e Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Mon, 13 Apr 2026 21:41:43 +0100 Subject: [PATCH 02/16] ci: switch npm publishing to trusted publishing Remove token-based npm authentication from the release workflow so CI can publish through npm Trusted Publishing with GitHub OIDC. Update the release guide to document the npm-side trusted publisher setup and clarify that no NPM_TOKEN secret is required. --- .github/workflows/release.yml | 2 -- docs/setup/RELEASING.md | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2245a1f..66a3cd0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,8 +56,6 @@ jobs: - name: Publish package to npm if: steps.resolve.outputs.should_publish == 'true' run: npm publish --provenance --tag "${{ steps.resolve.outputs.publish_tag }}" - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Release summary run: | diff --git a/docs/setup/RELEASING.md b/docs/setup/RELEASING.md index c9dcaf7..e29150e 100644 --- a/docs/setup/RELEASING.md +++ b/docs/setup/RELEASING.md @@ -7,13 +7,22 @@ NomadWorks publishes to npm as `@neuralnomads/nomadworks`. - Versioning, build verification, and npm publishing are handled by the GitHub Actions workflow `Release npm package`. - Pushes to `dev` automatically publish npm prereleases. - Pushes to `main` automatically publish stable npm releases. +- GitHub Actions publishes through npm Trusted Publishing with provenance enabled. - The workflow does not commit or tag version changes back to the repository. It derives the publish version from `package.json` and npm's already-published versions. -## Required Repository Secret +## Trusted Publishing Setup -Add this repository secret before publishing: +Configure npm Trusted Publishing for this GitHub repository before relying on CI publishes. -- `NPM_TOKEN`: npm access token with permission to publish `@neuralnomads/nomadworks` +At a minimum, npm must trust this repository's GitHub Actions workflow as a publisher for `@neuralnomads/nomadworks`. + +Expected setup: + +1. Open the npm package settings for `@neuralnomads/nomadworks`. +2. Configure a Trusted Publisher for this GitHub repository. +3. Allow GitHub Actions from this repository to publish the package. + +No `NPM_TOKEN` repository secret is required once Trusted Publishing is configured correctly. ## Workflow Behavior @@ -24,7 +33,7 @@ The release workflow performs these steps: 3. Runs `npm run release:check`, which executes tests, builds `dist/`, and previews the publish tarball. 4. Resolves the publish version based on the current branch and npm registry history. 5. Applies that version locally with `npm version --no-git-tag-version`. -6. Publishes the package with `npm publish --provenance`. +6. Publishes the package with `npm publish --provenance` using npm Trusted Publishing. ## Branch Behavior @@ -79,4 +88,5 @@ This command: - `prepack` runs `npm run build`, so local `npm pack` and `npm publish` always include a fresh `dist/` build. - `publishConfig.access` is set to `public` so the scoped package can publish correctly on npm. - The prerelease counter is remembered via npm registry history, not via git tags or committed prerelease versions. +- CI publishing depends on npm Trusted Publishing plus the workflow permission `id-token: write`. - If you need to dry-run a release locally without publishing, use `npm run release:check` and inspect the tarball preview output. From 0204ebd5acace2790191caa0979027f7b3743425 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 14 Apr 2026 08:34:08 +0100 Subject: [PATCH 03/16] fix: align package metadata with trusted publishing Add the repository URL npm expects for GitHub trusted publishing and document the exact npm-side repository, workflow, and environment values that must match the GitHub Actions release workflow. --- docs/setup/RELEASING.md | 8 ++++++++ package.json | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/docs/setup/RELEASING.md b/docs/setup/RELEASING.md index e29150e..5ac9798 100644 --- a/docs/setup/RELEASING.md +++ b/docs/setup/RELEASING.md @@ -22,6 +22,14 @@ Expected setup: 2. Configure a Trusted Publisher for this GitHub repository. 3. Allow GitHub Actions from this repository to publish the package. +Critical npm-side details: + +- GitHub organization or user: `NeuralNomadsAI` +- Repository: `NomadWorks` +- Workflow filename: `release.yml` +- If you use an optional environment in npm's Trusted Publisher settings, it must exactly match the GitHub Actions environment name used by the workflow. +- `package.json` must include a `repository.url` that exactly matches `https://github.com/NeuralNomadsAI/NomadWorks`. + No `NPM_TOKEN` repository secret is required once Trusted Publishing is configured correctly. ## Workflow Behavior diff --git a/package.json b/package.json index 10da1d2..d237671 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,10 @@ { "name": "@neuralnomads/nomadworks", "version": "0.1.0", + "repository": { + "type": "git", + "url": "git+https://github.com/NeuralNomadsAI/NomadWorks.git" + }, "type": "module", "main": "dist/index.js", "scripts": { From 5b4afee405df62ad5cfbd566dff204849007a957 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 14 Apr 2026 08:35:51 +0100 Subject: [PATCH 04/16] fix: satisfy npm trusted publishing requirements Run the release workflow on a supported Node.js version and align package repository metadata with npm's GitHub trusted publishing checks. Update the release guide to document the exact repository URL and runtime expectations needed for CI publishes. --- .github/workflows/release.yml | 6 +++--- docs/setup/RELEASING.md | 1 + package.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66a3cd0..d273f74 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,12 +20,12 @@ jobs: steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 24 cache: npm registry-url: https://registry.npmjs.org diff --git a/docs/setup/RELEASING.md b/docs/setup/RELEASING.md index 5ac9798..5351670 100644 --- a/docs/setup/RELEASING.md +++ b/docs/setup/RELEASING.md @@ -29,6 +29,7 @@ Critical npm-side details: - Workflow filename: `release.yml` - If you use an optional environment in npm's Trusted Publisher settings, it must exactly match the GitHub Actions environment name used by the workflow. - `package.json` must include a `repository.url` that exactly matches `https://github.com/NeuralNomadsAI/NomadWorks`. +- GitHub Actions must run on a supported Node.js version for npm Trusted Publishing. This workflow uses Node.js `24`. No `NPM_TOKEN` repository secret is required once Trusted Publishing is configured correctly. diff --git a/package.json b/package.json index d237671..3a440a4 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "repository": { "type": "git", - "url": "git+https://github.com/NeuralNomadsAI/NomadWorks.git" + "url": "https://github.com/NeuralNomadsAI/NomadWorks" }, "type": "module", "main": "dist/index.js", From d96ca933979a2bda70bf1dd87836df83aa56c552 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Thu, 16 Apr 2026 15:34:23 +0100 Subject: [PATCH 05/16] feat: add repo-overridable policy includes Move NomadWorks repo state under .nomadworks, add bundled policy defaults with repo-local overrides, and switch agent prompts to consume policy files for repository-specific opinions while keeping core workflow rules plugin-owned. --- Agents_Common.md | 34 ++--- README.md | 4 +- agents/business_analyst.md | 6 +- agents/developer.md | 7 +- agents/product_manager.md | 11 +- agents/qa_engineer.md | 5 +- agents/tech_lead.md | 10 +- agents/technical_architect.md | 5 +- agents/ui_ux_designer.md | 4 +- agents/workflow_runner.md | 11 +- docs/guides/TOOLS.md | 5 +- docs/product/DOMAIN_MAP.md | 2 +- docs/setup/CONFIGURATION.md | 21 ++- docs/setup/INSTALLATION.md | 5 +- package.json | 1 + policies/README.md | 54 ++++++++ policies/development-guidelines.md | 21 +++ policies/documentation-guidelines.md | 39 ++++++ policies/git-commit-messaging.md | 14 ++ policies/product-guidelines.md | 20 +++ policies/testing-guidelines.md | 29 ++++ policies/ui-ux-guidelines.md | 33 +++++ src/index.js | 192 ++++++++++++++++++++++----- templates/nomadworks.yaml.template | 5 +- 24 files changed, 448 insertions(+), 90 deletions(-) create mode 100644 policies/README.md create mode 100644 policies/development-guidelines.md create mode 100644 policies/documentation-guidelines.md create mode 100644 policies/git-commit-messaging.md create mode 100644 policies/product-guidelines.md create mode 100644 policies/testing-guidelines.md create mode 100644 policies/ui-ux-guidelines.md diff --git a/Agents_Common.md b/Agents_Common.md index 14f67c6..bef612b 100644 --- a/Agents_Common.md +++ b/Agents_Common.md @@ -54,19 +54,19 @@ That document defines: ## 5. Operational Guidelines * **Documentation Reading:** Whenever reading any file under `docs/` or `tasks/`, the file MUST be read fully to ensure complete understanding of the context and requirements. -* **Role-Specific Guidelines:** Every agent is responsible for reading their specific guideline file from `docs/core/` at the start of their session (e.g., `developer_guidelines.md`, `qa_guidelines.md`). +* **Role-Specific Guidelines:** Every agent is responsible for reading the core guidance and any applicable repository policy includes that are part of their prompt. * **Signed Agent Messages:** Agent-to-agent interactions must begin with a signed first message that clearly identifies the sending and receiving agents. Use this exact format on the first line: `[Agent Message] From: To: `. Example: `[Agent Message] From: product_manager To: tech_lead`. If a message does not begin with an agent signature, agents should assume they are speaking directly with the user. * **Pre-task Clarification:** Before starting any task, thoroughly review requirements. If anything is missing, ambiguous, or insufficient, immediately stop and clearly state what is needed, requesting clarification from the manager agent. Do not proceed until all requirements are clear. * **CodeMap-First Navigation:** Before broad repository search, agents should consult the most relevant `codemap.yml` chain for the area they are trying to understand. Use local, parent, root, or explicitly targeted module CodeMaps as the first navigation pass. If no suitable CodeMap exists or it is insufficient, agents may then expand into direct search and source inspection. * **Sync-up Mode Evaluation:** When in Sync-up Mode, critically evaluate the provided task definition for completeness and clarity. Identify missing information and explain its cruciality. * **Development Considerations:** Always keep in mind Security, Scalability, Maintainability, Error Handling, Performance, and Consistency. * **Concise Communication:** Agent responses should be brief, direct, and non-repetitive. Do not restate the same point multiple times, and do not become overly verbose unless the user explicitly asks for more detail. -* **.gitignore Updates:** Whenever project setups are completed (e.g., adding new dependencies, features, or environments), ensure the `.gitignore` file is updated to exclude sensitive, temporary, or unnecessary files from version control. +* **.gitignore Updates:** Whenever repository changes introduce generated, temporary, or sensitive files, ensure ignore rules are updated appropriately. * **Task Success Criteria:** No task is considered successful if there are failed tests, failed builds, or any other reason that prevents successful deployment. Any such issues must be fixed, even if the cause is not directly related to the current changes. * **Acceptance Criteria Traceability:** Every task must define numbered acceptance criteria (`AC-1`, `AC-2`, ...) and the final evidence must trace verification back to those criteria. * **Subagent Delegation:** No subagent simulation; we will be using actual subagents via the Task tool for every task delegation. When a task is assigned to a subagent, a task file MUST be provided, and the subagent MUST be instructed to read this file for detailed instructions. If a task is assigned without a task file, the subagent MUST strictly refuse to perform the task. * **Economical Task Planning:** All agents should plan their tasks to be economical and smart to reduce requests usage. One such trick could be to use batched requests when appropriate. -* **External Dependency Management:** When setting up or integrating external dependencies, always use the latest stable version. If a dependency provides a utility or script for setup/initialization (e.g., `npm install`, `init` scripts), prefer using that utility to ensure correct configuration. +* **External Dependency Management:** Follow the repository's development policy when selecting, updating, or initializing external dependencies. * **Post-Implementation Task Updates:** After completing their implementation step, each subagent MUST update the task file with a section titled `# Post Implementation Task Updates`, followed by a `## : Post Implementation Expectations` heading. Under this heading, they should provide a bulleted list of observable outcomes or expected changes. * **Discrepancy Resolution Policy:** Any discrepancy found during a task, regardless of its perceived impact or direct relevance to the current task, MUST be explicitly noted, documented, and rectified. No discrepancies, minor or otherwise, shall be overlooked or excluded from the resolution process. * **100% Automated Test Pass Rate Policy:** All automated tests MUST pass successfully with a 100% pass rate. No 'expected skips' or failures are acceptable. Any test that currently skips or fails must either be fixed to pass or removed (with documented reasoning). @@ -81,27 +81,19 @@ That document defines: * **Documentation Closure Ownership:** The Product Manager Agent is the final owner of confirming whether product and technical documentation updates were completed or explicitly marked unnecessary before task closure. * **Git Strategy:** PMA remains the final workflow-closure authority. Tech Lead is the default commit authority for direct execution paths, and Workflow Runner may perform the delegated final commit only in explicit full-team complex workflows. * **Authority Matrix:** Follow the canonical authority and output rules in `docs/core/role_contracts.md` for ownership, verification, commit authority, and closure decisions. -* **Commit Message Policy:** Every commit message must use a concise subject line in the format `: ` and must include a brief body explaining exactly what the commit is for. If the commit is associated with a task, include the task ID in the subject. -* **Implementation Evidence Collection:** Every `implementation` task must produce an **Evidence Packet** in `evidences/[feature_task_name]/`. This MUST include: - * `SUMMARY.md`: A brief explanation of what was tested and what the attached files prove. - * `logs/`: Terminal output from verification commands. - * `screenshots/`: Visual proof (mandatory for UI changes). +* **Commit Message Policy:** Every commit message must follow the repository's active commit messaging policy. +* **Implementation Evidence Collection:** Every `implementation` task must produce the verification artifacts required by the repository's testing and evidence policy. * **Atomic Commitment:** A task is only complete when the code AND the "Truth" documentation (`docs/product/`, `docs/architecture/`, etc.) are updated in a single atomic commit. The SCR file is then marked as `Implemented`. * **Batch Integrity:** In delegated workflow mode, the PMA should aim to complete the entire assigned batch. If a single task is blocked, it is isolated in `tasks/blocked/`, and the PMA continues with the rest of the batch if possible. -## 7. Mandatory Documentation Update Matrix +## 7. Repository Documentation Policy -Every task MUST ensure the following files are updated if relevant: +All documentation updates must follow the repository's documentation policy for: -| Document Level | File Path | Responsible Agent | -| :--- | :--- | :--- | -| **Product Overview** | `docs/product/PRODUCT_OVERVIEW.md` | Business Analyst | -| **Features List** | `docs/product/FEATURES_LIST.md` | Business Analyst | -| **Architecture** | `docs/architecture/TECHNICAL_ARCHITECTURE.md` | Technical Architect | -| **Feature Spec** | `docs/features/[feature]/SPECIFICATION.md` | BA & Architect | -| **Tech Guidelines** | `docs/core/technical_guidelines.md` | Tech Lead / Architect | -| **CodeMap** | `codemap.yml` | Developer / Architect | +- where steady-state product and technical truth belongs +- which documents must be updated for a given change +- documentation ownership, naming, and layout conventions - - - + + + diff --git a/README.md b/README.md index 622c6dd..7ef3a40 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ PMA will guide the repository setup flow and, when needed, initialize NomadWorks ## Configure -During setup, PMA can initialize the repository and create `.codenomad/nomadworks.yaml`. NomadWorks reads this file for repository-local defaults, feature flags, and per-agent overrides. +During setup, PMA can initialize the repository and create `.nomadworks/nomadworks.yaml`. NomadWorks reads this file for repository-local defaults, feature flags, policy extraction settings, and per-agent overrides. + +Repository-local policy overrides live in `.nomadworks/policies/`. If a policy file is not present there, NomadWorks falls back to the bundled plugin default automatically. NomadWorks supports two team presets: diff --git a/agents/business_analyst.md b/agents/business_analyst.md index 24b730e..bc00557 100644 --- a/agents/business_analyst.md +++ b/agents/business_analyst.md @@ -31,6 +31,6 @@ Critically evaluate the provided task definition. Ensure it contains all necessa * **Logical:** Constructs unambiguous user stories and acceptance criteria. * **Inquisitive:** Proactively identifies gaps and hidden assumptions in task definitions. - - - + + + diff --git a/agents/developer.md b/agents/developer.md index e98c5b2..63804b3 100644 --- a/agents/developer.md +++ b/agents/developer.md @@ -30,6 +30,7 @@ Critically evaluate the task definition. Ensure it has sufficient detail for you * **Consistent:** Adheres strictly to established project patterns and standards. * **Collaborative:** Communicates clearly and works effectively within the orchestrated workflow. - - - + + + + diff --git a/agents/product_manager.md b/agents/product_manager.md index 3c71c00..a2107fb 100644 --- a/agents/product_manager.md +++ b/agents/product_manager.md @@ -40,7 +40,7 @@ You are the Product Manager Agent (PMA). You are the central orchestrator for al - Orchestrate the Post-Task Sync yourself when you retain control of the task lifecycle. - Ensure evidence, documentation closure, finalization updates, final commit, and archiving are completed before closure. * **Delegated Batch Execution:** When the PO triggers a batch of implementation SCRs, execute them sequentially within the shared worktree. Investigation and spec tasks may still run in parallel when they are isolated from the active implementation task. -* **Post-Task Sync & Evidence:** You are the gatekeeper of the **Evidence Packet**. Ensure the Developer/QA has provided a `SUMMARY.md`, logs, and screenshots before calling the specialists for the Post-Task Sync. Instruct each specialist to **introduce themselves and their role** when providing verification feedback. +* **Post-Task Sync & Evidence:** You are the gatekeeper of implementation evidence. Ensure the Developer/QA has provided the verification artifacts required by the repository testing/evidence policy before calling the specialists for the Post-Task Sync. Instruct each specialist to **introduce themselves and their role** when providing verification feedback. * **Bounce Back Protocol:** If an implementation is rejected during the Post-Task Sync, reuse the original Task tool `task_id` when sending it back to the agent. This ensures they have the full execution history of the rejection. * **Formal Reopen Protocol:** If a task was marked done but later needs discrepancies fixed or minor same-scope changes after implementation, move that same task back into `Active`, append a `Reopen History` entry, and continue using the same task file ID. Reuse the same Task tool `task_id` when resuming delegated task work, and when resuming Workflow Runner execution, reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible. * **Commit Authority:** You own final closure in all modes. Tech Lead is the default commit authority for direct execution paths, while Workflow Runner may perform the final commit only when you explicitly delegated a full-team complex workflow to it. @@ -52,7 +52,8 @@ You are the Product Manager Agent (PMA). You are the central orchestrator for al * **Strategic:** Focused on long-term goals and how current decisions contribute to them. * **Decisive:** Able to make clear decisions and drive the product forward. - - - - + + + + + diff --git a/agents/qa_engineer.md b/agents/qa_engineer.md index 5d6af12..6c70524 100644 --- a/agents/qa_engineer.md +++ b/agents/qa_engineer.md @@ -33,6 +33,5 @@ All automated tests MUST pass successfully with a 100% pass rate. No 'expected s * **Analytical:** Interprets results to find the root cause of failures. * **User-Flow Focused:** Always views the system through the eyes of the end-user. - - - + + diff --git a/agents/tech_lead.md b/agents/tech_lead.md index bd25eb3..14e2d72 100644 --- a/agents/tech_lead.md +++ b/agents/tech_lead.md @@ -32,7 +32,9 @@ Critically evaluate the provided task definition. Ensure it contains all necessa * **Mentor-Minded:** Dedicated to leveling up the team and providing clear guidance. * **Decisive:** Able to resolve complex blockers and drive the team forward. - - - - + + + + + + diff --git a/agents/technical_architect.md b/agents/technical_architect.md index 45f4dbb..b1936a1 100644 --- a/agents/technical_architect.md +++ b/agents/technical_architect.md @@ -33,5 +33,6 @@ Critically evaluate the provided task definition. Ensure it contains all necessa * **Visionary:** Able to design robust patterns that anticipate future growth. * **Pragmatic:** Balances technical excellence with practical delivery goals. - - + + + diff --git a/agents/ui_ux_designer.md b/agents/ui_ux_designer.md index 6732009..71795d3 100644 --- a/agents/ui_ux_designer.md +++ b/agents/ui_ux_designer.md @@ -35,5 +35,5 @@ Critically evaluate the provided task definition for design clarity. Identify mi * **Minimalist:** Focused on clean, clutter-free, and intuitive design. * **Aesthetically Sharp:** An expert eye for hierarchy, color, and typography. - - + + diff --git a/agents/workflow_runner.md b/agents/workflow_runner.md index 9c88332..4445475 100644 --- a/agents/workflow_runner.md +++ b/agents/workflow_runner.md @@ -11,7 +11,7 @@ You are the NomadWorks Workflow Runner. Your sole responsibility is to execute t 2. **Workflow Adherence:** You MUST follow the NomadWorks orchestrated workflow exactly. 3. **Task File as Law:** Read the assigned task file (`tasks/todo/...`) immediately. 4. **Collective Syncing:** Use the `Task` tool to orchestrate specialists (BA, Tech Lead, UI/UX, QA) during syncs. -5. **Evidence Packet:** Generate and verify the Evidence Packet (`SUMMARY.md`, logs, screenshots). +5. **Evidence:** Generate and verify the verification artifacts required by the repository testing/evidence policy. 6. **Delegated Finalization Authority:** For `implementation` tasks in the full-team workflow-runner path, you are the delegated finalization executor. Once 100% approved in Post-Task Sync: * Update the SCR status to `Implemented` in the SCR file and `docs/scrs/current.md`. * Update all registries (`tasks/current.md` and `tasks/done.md`). @@ -29,7 +29,8 @@ You are the NomadWorks Workflow Runner. Your sole responsibility is to execute t 7. **Finalize:** For `implementation` tasks, complete delegated finalization and archiving. For `investigation` and `spec` tasks, return a concise final report and any produced artifacts to the PMA. 8. **Resume Awareness:** If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so the prior execution context remains available. - - - - + + + + + diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index 36f3853..a340e23 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -12,7 +12,8 @@ Initializes NomadWorks in the current repository. ### What it creates -- `.codenomad/nomadworks.yaml` +- `.nomadworks/nomadworks.yaml` +- `.nomadworks/policies/README.md` - `codemap.yml` - `tasks/current.md` - `tasks/done.md` @@ -52,7 +53,7 @@ Also provide: - Use `existing_discussion_id` plus `previous_message_count` to reopen an older discussion and include a small amount of newer conversation that happened before the reopen call. - Only one active discussion is allowed per session. - Discussion transcripts are stored in `tasks/discussions/`. -- Active discussion state is persisted in `.codenomad/runtime/discussions.json`. +- Active discussion state is persisted in `.nomadworks/runtime/discussions.json`. - Only discussion-capable agents should use these discussion tools. ## `nomadworks_stop_discussion` diff --git a/docs/product/DOMAIN_MAP.md b/docs/product/DOMAIN_MAP.md index b4d1f99..207d86d 100644 --- a/docs/product/DOMAIN_MAP.md +++ b/docs/product/DOMAIN_MAP.md @@ -37,5 +37,5 @@ This document maps the major product domains and the features that belong to the ### Plugin Setup And Configuration - **Purpose:** Defines how NomadWorks is installed, configured, and enabled in an OpenCode environment. -- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, agent overrides. +- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, agent overrides, policy overrides. - **Primary Docs:** `docs/setup/INSTALLATION.md`, `docs/setup/CONFIGURATION.md` diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index 94f172b..f6e787d 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -1,6 +1,6 @@ # Configuration -NomadWorks reads repository-local configuration from `.codenomad/nomadworks.yaml`. +NomadWorks reads repository-local configuration from `.nomadworks/nomadworks.yaml`. This file is typically created during the PMA-led repository setup flow. @@ -18,6 +18,9 @@ features: debug_dumps: true codemap_verification: true +policies: + extract_defaults: none + agents: product_manager: enabled: true @@ -29,6 +32,7 @@ agents: - `team_mode`: The supported team preset. Use `mini` for PMA + BA + Tech Lead only, or `full` for the complete collective. If omitted in an existing repository, NomadWorks defaults to `full`. - `defaults`: Shared defaults for providers, models, permissions, and other agent config fields. - `features`: Plugin feature flags such as debug dumps and validation behavior. +- `policies`: Policy extraction controls for generated reference policy files. - `agents`: Per-agent enablement and overrides. ## Supported team modes @@ -79,8 +83,19 @@ agents: - nomadworks_validate ``` +### Generate bundled policy references + +```yaml +policies: + extract_defaults: all +``` + +This writes the bundled default policy files to `.nomadworks/generated/policies/` for reference. Those generated files are not used directly at runtime. To customize one, copy it into `.nomadworks/policies/` and edit the copy. + ## Operational notes - The `product_manager` agent becomes the default primary agent when NomadWorks is enabled. -- Repository-local agent markdown overrides can live in `.codenomad/nomadworks/agents/`. -- Final agent prompts are dumped to `.nomadworks/agents/` when `features.debug_dumps` is enabled. +- Repository-local agent markdown overrides can live in `.nomadworks/agents/`. +- Repository-local policy overrides can live in `.nomadworks/policies/`. +- Generated reference policy files are written to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. +- Final agent prompts are dumped to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. diff --git a/docs/setup/INSTALLATION.md b/docs/setup/INSTALLATION.md index ef31c6c..02944ce 100644 --- a/docs/setup/INSTALLATION.md +++ b/docs/setup/INSTALLATION.md @@ -42,7 +42,8 @@ You do not need to manually run NomadWorks initialization commands as a first st When PMA initializes the repository, NomadWorks creates: -- `.codenomad/nomadworks.yaml` +- `.nomadworks/nomadworks.yaml` +- `.nomadworks/policies/README.md` - `codemap.yml` - `tasks/current.md` - `tasks/done.md` @@ -51,7 +52,7 @@ When PMA initializes the repository, NomadWorks creates: ## 5. Configure NomadWorks -Edit `.codenomad/nomadworks.yaml` to set defaults, features, and per-agent overrides. +Edit `.nomadworks/nomadworks.yaml` to set defaults, features, policy extraction behavior, and per-agent overrides. See: diff --git a/package.json b/package.json index 3a440a4..cbb6dd6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dist", "agents", "docs", + "policies", "templates", "Agents_Common.md" ], diff --git a/policies/README.md b/policies/README.md new file mode 100644 index 0000000..1d8aecd --- /dev/null +++ b/policies/README.md @@ -0,0 +1,54 @@ +# NomadWorks Policies + +NomadWorks keeps core workflow behavior in the plugin and lets repositories override opinionated delivery policies here. + +## How Policy Resolution Works + +For any `.md>` include, NomadWorks resolves policy files in this order: + +1. `.nomadworks/policies/.md` +2. bundled plugin default `policies/.md` + +Files under `.nomadworks/generated/policies/` are reference copies only. They are not read directly at runtime. + +## Available Policies + +- `development-guidelines.md` + - Repository-specific engineering rules, stack notes, and implementation conventions. + - Used by: `developer`, `technical_architect`, `tech_lead`, `workflow_runner` + +- `testing-guidelines.md` + - Testing, evidence, regression, and verification conventions. + - Used by: `developer`, `qa_engineer`, `tech_lead`, `workflow_runner` + +- `documentation-guidelines.md` + - Documentation layout, naming, ownership, and update expectations. + - Used by all agents through the shared prompt. + +- `git-commit-messaging.md` + - Commit subject and body rules. + - Used by: `tech_lead`, `workflow_runner` + +- `product-guidelines.md` + - User story, acceptance criteria, terminology, and product-truth conventions. + - Used by: `product_manager`, `business_analyst` + +- `ui-ux-guidelines.md` + - UI review standards and visual quality expectations. + - Used by: `ui_ux_designer` + +## Customizing A Policy + +1. Set `.nomadworks/nomadworks.yaml` `policies.extract_defaults` to `all` if you want reference copies of all bundled defaults. +2. Inspect `.nomadworks/generated/policies/` for the default files. +3. Copy the policy you want to customize into `.nomadworks/policies/`. +4. Edit the copied file. The repo-local version will override the plugin default automatically. + +## Policy Extraction + +`policies.extract_defaults` supports: + +- `none`: do not generate reference policy files +- `all`: write all bundled default policy files to `.nomadworks/generated/policies/` + +Only files in `.nomadworks/policies/` affect runtime prompt behavior. diff --git a/policies/development-guidelines.md b/policies/development-guidelines.md new file mode 100644 index 0000000..b72d6e2 --- /dev/null +++ b/policies/development-guidelines.md @@ -0,0 +1,21 @@ +# Development Guidelines + +These defaults are intended to be customized per repository when needed. + +## Stack Notes + +- Language: define in the repository if needed. +- Runtime / Framework: define in the repository if needed. +- Frontend stack: define in the repository if needed. +- Testing stack: define in the repository if needed. +- Database / storage: define in the repository if needed. + +## Default Engineering Conventions + +- Prefer clear module or feature boundaries over ad-hoc file placement. +- Keep external integrations behind stable interfaces or wrappers when practical. +- Update `.gitignore` when repository changes introduce generated, temporary, or sensitive files. +- Prefer stable dependency versions unless repository compatibility requires otherwise. +- Use dependency-provided setup or initialization utilities when they are the standard way to integrate the dependency safely. +- Document meaningful architecture changes in the repository's documentation before or alongside implementation. +- Keep code changes aligned with existing repository conventions unless the repository policy explicitly changes them. diff --git a/policies/documentation-guidelines.md b/policies/documentation-guidelines.md new file mode 100644 index 0000000..23d84ad --- /dev/null +++ b/policies/documentation-guidelines.md @@ -0,0 +1,39 @@ +# Documentation Guidelines + +## Documentation Goals + +- Keep documentation easy to locate and update. +- Separate steady-state truth from change proposals and workflow records. +- Update documentation in the same change set as the implementation whenever the documented truth changes. + +## Default Documentation Layout + +- `docs/product/`: whole-product truth and top-level feature inventory +- `docs/domains/`: stable product-area truth shared by multiple features +- `docs/features/`: one concrete capability or feature specification +- `docs/architecture/`: technical design, contracts, and cross-cutting decisions +- `docs/scrs/`: proposed and approved changes, not steady-state truth + +## Update Expectations + +Update the relevant documentation when work changes: + +- product behavior, terminology, or feature inventory +- architecture, interfaces, or technical invariants +- feature specifications or acceptance criteria +- documentation ownership, naming, or structure conventions + +## Default Ownership + +- Business Analyst: product, domain, and feature truth from the product perspective +- Technical Architect: architecture truth and technical design documentation +- Product Manager: verifies documentation closure during workflow execution +- Developer / Tech Lead / QA: contribute technical accuracy when implementation changes documented truth + +## Default Repository Matrix + +- Product overview: `docs/product/PRODUCT_OVERVIEW.md` +- Features list: `docs/product/FEATURES_LIST.md` +- Architecture: `docs/architecture/TECHNICAL_ARCHITECTURE.md` +- Feature specification: `docs/features//SPECIFICATION.md` +- CodeMap updates: relevant `codemap.yml` files for changed code areas diff --git a/policies/git-commit-messaging.md b/policies/git-commit-messaging.md new file mode 100644 index 0000000..bcdfe23 --- /dev/null +++ b/policies/git-commit-messaging.md @@ -0,0 +1,14 @@ +# Git Commit Messaging + +Use a concise subject line in this format: + +`: ` + +Examples: + +- `docs: update workflow guidance` +- `fix: TASK-014 correct task archive logic` + +Always include a brief body that explains what the commit is for and why the change exists. + +If the commit is associated with a task, include the task ID in the subject when practical. diff --git a/policies/product-guidelines.md b/policies/product-guidelines.md new file mode 100644 index 0000000..4c65289 --- /dev/null +++ b/policies/product-guidelines.md @@ -0,0 +1,20 @@ +# Product Guidelines + +## Product Writing Defaults + +- Write user stories and requirements in clear, unambiguous language. +- Keep acceptance criteria specific, testable, and easy to map to verification evidence. +- Use numbered acceptance criteria (`AC-1`, `AC-2`, ...) for tracked work. +- Maintain consistent product terminology across SCRs, tasks, and steady-state docs. + +## User Story And Acceptance Criteria Conventions + +- User stories may use the format: `As a , I want , so that .` +- Acceptance criteria should describe observable behavior or outcomes rather than implementation details. +- When requirements are incomplete or ambiguous, stop and push for clarification instead of inventing scope. + +## Product Truth Stewardship + +- Keep product documentation cross-linked and internally consistent. +- When behavior changes, update the relevant product-facing docs and SCR registries. +- If the repository establishes domain or feature naming conventions, apply them consistently. diff --git a/policies/testing-guidelines.md b/policies/testing-guidelines.md new file mode 100644 index 0000000..a384a83 --- /dev/null +++ b/policies/testing-guidelines.md @@ -0,0 +1,29 @@ +# Testing Guidelines + +## Test Levels + +1. Unit tests verify isolated logic, functions, and classes. +2. Integration tests verify interactions between multiple modules or external services. +3. End-to-end tests verify real user or system flows through the product. +4. Manual verification is allowed for visual or interaction checks that cannot be automated effectively. + +## Verification Policy + +- All automated tests must pass. No expected skips or tolerated failures are allowed by default. +- Tests should live close to the code they verify unless the repository uses a clearly defined alternative structure. +- Every `implementation` task must produce the verification artifacts needed for review. +- Verification artifacts should map back to the task's numbered acceptance criteria. +- Run the relevant regression coverage before handing implementation back for technical review. + +## Evidence Defaults + +By default, implementation evidence should include: + +- a short summary of what was verified +- command output or logs for relevant automated checks +- screenshots for UI changes or visual reviews + +## Non-Implementation Outputs + +- `investigation` tasks should produce findings, reproduction notes, useful logs, and a recommended next step. +- `spec` tasks should produce SCR or documentation updates that define the accepted change and its impact. diff --git a/policies/ui-ux-guidelines.md b/policies/ui-ux-guidelines.md new file mode 100644 index 0000000..15d3b94 --- /dev/null +++ b/policies/ui-ux-guidelines.md @@ -0,0 +1,33 @@ +# UI/UX Guidelines + +## Core Principles + +1. Prioritize ease of use, accessibility, and intuitive navigation. +2. Aim for a modern, clean, and polished visual design. +3. Keep UI elements visually consistent with the repository's design language. +4. Use layout, color, and typography to create clear visual hierarchy. + +## Review Workflow + +- Define the intended screens, interactions, and layout before implementation when UI work is involved. +- Review screenshots and other visual evidence from the task's evidence artifacts after implementation. +- Evaluate the result visually rather than by reading code. +- If the available evidence is insufficient, say so clearly and ask for better screenshots or artifacts. + +## Visual Quality Checklist + +Reject or request fixes when you see: + +- obvious misalignment against the page or component grid +- inconsistent spacing between similar elements +- weak typography hierarchy that makes the screen hard to scan +- interactive elements that do not look interactive +- low-contrast text or other readability issues +- cluttered, dated, or visibly unpolished presentation + +## Required Fix Triggers + +- overlapping UI or clipped text +- missing key interaction steps that were part of the intended flow +- ignored design system conventions for color, typography, or spacing +- an overall result that feels amateur or not ready for users diff --git a/src/index.js b/src/index.js index cb57251..6aaece1 100644 --- a/src/index.js +++ b/src/index.js @@ -9,34 +9,127 @@ import { nomadworks_validate_logic } from "./validate_logic.js"; const PKG_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const BUNDLE_AGENTS_DIR = path.join(PKG_ROOT, "agents"); +const BUNDLE_POLICIES_DIR = path.join(PKG_ROOT, "policies"); const TEMPLATES_DIR = path.join(PKG_ROOT, "templates"); const MANDATORY_AGENTS = new Set(["product_manager", "business_analyst", "tech_lead"]); const MINI_MODE_AGENTS = new Set(["product_manager", "business_analyst", "tech_lead"]); const DISCUSSION_BACKFILL_FETCH_LIMIT = 100; +const NOMADWORKS_DIRNAME = ".nomadworks"; +const LEGACY_NOMADWORKS_DIRNAME = ".codenomad"; const activeWorkflows = new Map(); // sessionId -> { pmaSessionId, taskPath, track } +function nomadworksDir(worktree) { + return path.join(worktree, NOMADWORKS_DIRNAME); +} + +function legacyNomadworksDir(worktree) { + return path.join(worktree, LEGACY_NOMADWORKS_DIRNAME); +} + +function repoConfigPath(worktree) { + return path.join(nomadworksDir(worktree), "nomadworks.yaml"); +} + +function legacyRepoConfigPath(worktree) { + return path.join(legacyNomadworksDir(worktree), "nomadworks.yaml"); +} + +function repoPoliciesDir(worktree) { + return path.join(nomadworksDir(worktree), "policies"); +} + +function generatedPoliciesDir(worktree) { + return path.join(nomadworksDir(worktree), "generated", "policies"); +} + +function generatedAgentsDir(worktree) { + return path.join(nomadworksDir(worktree), "generated", "agents"); +} + +function repoAgentsDir(worktree) { + return path.join(nomadworksDir(worktree), "agents"); +} + +function legacyRepoAgentsDir(worktree) { + return path.join(legacyNomadworksDir(worktree), "nomadworks", "agents"); +} + +function runtimeDiscussionRegistryPath(worktree) { + return path.join(nomadworksDir(worktree), "runtime", "discussions.json"); +} + +function legacyDiscussionRegistryPath(worktree) { + return path.join(legacyNomadworksDir(worktree), "runtime", "discussions.json"); +} + +function resolveConfigPath(worktree) { + const repoPath = repoConfigPath(worktree); + if (fs.existsSync(repoPath)) return repoPath; + + const legacyPath = legacyRepoConfigPath(worktree); + if (fs.existsSync(legacyPath)) return legacyPath; + + return repoPath; +} + +function normalizePolicyExtraction(value) { + if (typeof value !== "string") return "none"; + return value.trim().toLowerCase() === "all" ? "all" : "none"; +} + +function resolveIncludeFile(includeRef, repoRoot, bundleRoot) { + const trimmed = includeRef.trim(); + const scopedMatch = trimmed.match(/^([a-z]+):(.*)$/i); + const scope = scopedMatch?.[1]?.toLowerCase(); + const target = scopedMatch ? scopedMatch[2].trim() : trimmed; + + const resolveRelative = (baseDir, relativePath) => { + if (!relativePath) return null; + return path.isAbsolute(relativePath) ? relativePath : path.join(baseDir, relativePath); + }; + + if (scope === "plugin") { + const filePath = resolveRelative(bundleRoot, target); + return fs.existsSync(filePath) ? filePath : null; + } + + if (scope === "repo") { + const filePath = resolveRelative(nomadworksDir(repoRoot), target); + return fs.existsSync(filePath) ? filePath : null; + } + + if (scope === "policy") { + const repoPolicyPath = resolveRelative(repoPoliciesDir(repoRoot), target); + if (repoPolicyPath && fs.existsSync(repoPolicyPath)) return repoPolicyPath; + + const bundledPolicyPath = resolveRelative(BUNDLE_POLICIES_DIR, target); + return bundledPolicyPath && fs.existsSync(bundledPolicyPath) ? bundledPolicyPath : null; + } + + const repoPath = resolveRelative(repoRoot, target); + if (repoPath && fs.existsSync(repoPath)) return repoPath; + + const bundlePath = resolveRelative(bundleRoot, target); + return bundlePath && fs.existsSync(bundlePath) ? bundlePath : null; +} + /** - * Resolves markers recursively. - * Checks repo (worktree) first, then falls back to bundle root. + * Resolves markers recursively. + * Supported forms: + * - (legacy: repo root first, then plugin bundle) + * - + * - + * - (.nomadworks/policies first, then bundled defaults) */ function resolveIncludes(text, repoRoot, bundleRoot) { const includeRegex = //g; - return text.replace(includeRegex, (match, filename) => { - // Check repo first, then bundle - const repoPath = path.isAbsolute(filename) ? filename : path.join(repoRoot, filename); - const bundlePath = path.isAbsolute(filename) ? filename : path.join(bundleRoot, filename); - - let filePath = null; - if (fs.existsSync(repoPath)) { - filePath = repoPath; - } else if (fs.existsSync(bundlePath)) { - filePath = bundlePath; - } + return text.replace(includeRegex, (match, includeRef) => { + const filePath = resolveIncludeFile(includeRef, repoRoot, bundleRoot); if (!filePath) { - console.warn(`[NomadWorks] Include file not found: ${filename}`); - return `\n\n# ERROR: Include file not found: ${filename}\n\n`; + console.warn(`[NomadWorks] Include file not found: ${includeRef}`); + return `\n\n# ERROR: Include file not found: ${includeRef}\n\n`; } const content = fs.readFileSync(filePath, "utf8"); @@ -117,12 +210,10 @@ function slugifyTitle(input) { .slice(0, 80) || "discussion"; } -function discussionRegistryPath(worktree) { - return path.join(worktree, ".codenomad", "runtime", "discussions.json"); -} - function loadDiscussionRegistry(worktree) { - const registryPath = discussionRegistryPath(worktree); + const registryPath = fs.existsSync(runtimeDiscussionRegistryPath(worktree)) + ? runtimeDiscussionRegistryPath(worktree) + : legacyDiscussionRegistryPath(worktree); if (!fs.existsSync(registryPath)) { return { version: 1, active: {} }; } @@ -138,7 +229,7 @@ function loadDiscussionRegistry(worktree) { } function saveDiscussionRegistry(worktree, registry) { - const registryPath = discussionRegistryPath(worktree); + const registryPath = runtimeDiscussionRegistryPath(worktree); const runtimeDir = path.dirname(registryPath); if (!fs.existsSync(runtimeDir)) fs.mkdirSync(runtimeDir, { recursive: true }); fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8"); @@ -269,7 +360,9 @@ function isAgentEnabledForTeamMode(agentId, teamMode) { function applyTeamConfigRules(repoCfg) { repoCfg.agents ??= {}; + repoCfg.policies ??= {}; repoCfg.team_mode = normalizeTeamMode(repoCfg.team_mode); + repoCfg.policies.extract_defaults = normalizePolicyExtraction(repoCfg.policies.extract_defaults); for (const id of MANDATORY_AGENTS) { if (repoCfg.agents[id]?.enabled === false) { @@ -297,13 +390,37 @@ function getOperatingTeamMode(repoCfg) { } function readResolvedFile(relativePath, worktree) { - const repoPath = path.join(worktree, relativePath); - const bundlePath = path.join(PKG_ROOT, relativePath); - const filePath = fs.existsSync(repoPath) ? repoPath : bundlePath; - if (!fs.existsSync(filePath)) return ""; + const filePath = resolveIncludeFile(`plugin:${relativePath}`, worktree, PKG_ROOT); + if (!filePath || !fs.existsSync(filePath)) return ""; return resolveIncludes(fs.readFileSync(filePath, "utf8"), worktree, PKG_ROOT).trim(); } +function syncGeneratedPolicies(worktree, repoCfg) { + if (repoCfg.policies?.extract_defaults !== "all") return; + if (!fs.existsSync(BUNDLE_POLICIES_DIR)) return; + + const generatedDir = generatedPoliciesDir(worktree); + if (!fs.existsSync(generatedDir)) fs.mkdirSync(generatedDir, { recursive: true }); + + const policyFiles = fs.readdirSync(BUNDLE_POLICIES_DIR).filter(file => file.endsWith(".md") && file !== "README.md"); + + for (const file of policyFiles) { + const sourcePath = path.join(BUNDLE_POLICIES_DIR, file); + const source = fs.readFileSync(sourcePath, "utf8").trimEnd(); + const generated = [ + "", + "", + source, + "" + ].join("\n"); + fs.writeFileSync(path.join(generatedDir, file), generated, "utf8"); + } +} + function getModePromptFragment(agentId, operatingTeamMode, worktree) { const fragmentMap = { product_manager: { @@ -323,8 +440,8 @@ function getModePromptFragment(agentId, operatingTeamMode, worktree) { export default async function NomadWorksPlugin(input) { const worktree = path.resolve(input.worktree || process.cwd()); - const debugDir = path.join(worktree, ".nomadworks", "agents"); - const configPath = path.join(worktree, ".codenomad", "nomadworks.yaml"); + const debugDir = generatedAgentsDir(worktree); + const configPath = resolveConfigPath(worktree); const discussionRegistry = loadDiscussionRegistry(worktree); // Load project-specific configuration @@ -337,6 +454,7 @@ export default async function NomadWorksPlugin(input) { } } repoCfg = applyTeamConfigRules(repoCfg); + syncGeneratedPolicies(worktree, repoCfg); const operatingTeamMode = getOperatingTeamMode(repoCfg); const startAndMonitorWorkflow = async (sessionId, pmaSessionId, initialText, taskPath = null) => { @@ -407,8 +525,10 @@ export default async function NomadWorksPlugin(input) { return "Error: team_mode must be either 'mini' or 'full'."; } - const cfgDir = path.join(context.worktree, ".codenomad"); + const cfgDir = nomadworksDir(context.worktree); + const policiesDir = repoPoliciesDir(context.worktree); if (!fs.existsSync(cfgDir)) fs.mkdirSync(cfgDir, { recursive: true }); + if (!fs.existsSync(policiesDir)) fs.mkdirSync(policiesDir, { recursive: true }); // Discover all agent IDs to enable them explicitly const agentIds = fs.existsSync(BUNDLE_AGENTS_DIR) @@ -417,8 +537,9 @@ export default async function NomadWorksPlugin(input) { const nomadworksTmplPath = path.join(TEMPLATES_DIR, "nomadworks.yaml.template"); const codemapTmplPath = path.join(TEMPLATES_DIR, "codemap.yml.template"); + const policiesReadmePath = path.join(BUNDLE_POLICIES_DIR, "README.md"); - if (!fs.existsSync(nomadworksTmplPath) || !fs.existsSync(codemapTmplPath)) { + if (!fs.existsSync(nomadworksTmplPath) || !fs.existsSync(codemapTmplPath) || !fs.existsSync(policiesReadmePath)) { return "Error: Initialization templates not found in plugin."; } @@ -438,6 +559,7 @@ export default async function NomadWorksPlugin(input) { const cfgFilePath = path.join(cfgDir, "nomadworks.yaml"); const rootCodemapPath = path.join(context.worktree, "codemap.yml"); + const policiesReadmeTargetPath = path.join(policiesDir, "README.md"); if (!fs.existsSync(cfgFilePath)) { fs.writeFileSync(cfgFilePath, nomadworksConfig, "utf8"); @@ -447,6 +569,10 @@ export default async function NomadWorksPlugin(input) { fs.writeFileSync(rootCodemapPath, codemapConfig, "utf8"); } + if (!fs.existsSync(policiesReadmeTargetPath)) { + fs.writeFileSync(policiesReadmeTargetPath, fs.readFileSync(policiesReadmePath, "utf8"), "utf8"); + } + // Scaffold Task Registries const tasksDir = path.join(context.worktree, "tasks"); const scrsDir = path.join(context.worktree, "docs", "scrs"); @@ -471,7 +597,7 @@ export default async function NomadWorksPlugin(input) { fs.writeFileSync(scrsDonePath, "# Implemented Spec Change Requests\n\n| Date | SCR ID | Title | Related Feature | Task ID |\n| :--- | :--- | :--- | :--- | :--- |\n", "utf8"); } - return `NomadWorks initialized in '${requestedTeamMode}' team mode: .codenomad/nomadworks.yaml, registries, and codemap.yml created.`; + return `NomadWorks initialized in '${requestedTeamMode}' team mode: .nomadworks/nomadworks.yaml, policy README, registries, and codemap.yml created.`; } }), nomadworks_validate: tool({ @@ -793,10 +919,12 @@ export default async function NomadWorksPlugin(input) { const nomadworksActive = repoCfg && repoCfg.enabled === true; // 1. Identify and compile all NomadWorks agents - const repoAgentsDir = path.join(worktree, ".codenomad", "nomadworks", "agents"); + const repoAgentsPrimaryDir = repoAgentsDir(worktree); + const legacyAgentsDir = legacyRepoAgentsDir(worktree); const agentSources = []; if (fs.existsSync(BUNDLE_AGENTS_DIR)) agentSources.push(BUNDLE_AGENTS_DIR); - if (fs.existsSync(repoAgentsDir)) agentSources.push(repoAgentsDir); + if (fs.existsSync(repoAgentsPrimaryDir)) agentSources.push(repoAgentsPrimaryDir); + if (fs.existsSync(legacyAgentsDir)) agentSources.push(legacyAgentsDir); const ourAgents = {}; diff --git a/templates/nomadworks.yaml.template b/templates/nomadworks.yaml.template index eabd3a3..e4f27d1 100644 --- a/templates/nomadworks.yaml.template +++ b/templates/nomadworks.yaml.template @@ -9,8 +9,11 @@ defaults: # permissions: allow features: - debug_dumps: true # Dumps final agent configs to .nomadworks/agents/ for verification + debug_dumps: true # Dumps final agent configs to .nomadworks/generated/agents/ for verification # debug_logs: false # Enable detailed console logging for the plugin codemap_verification: true +policies: + extract_defaults: none # Set to 'all' to write bundled policy defaults to .nomadworks/generated/policies/ + agents: From 15d961fac76195e87518712f965828ad4181c71c Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Thu, 16 Apr 2026 15:49:01 +0100 Subject: [PATCH 06/16] feat: add additive repo agent instructions Treat .nomadworks/agents as additive prompt fragments, introduce .nomadworks/agent-overrides for explicit full replacements, and update the docs to explain the new repository customization model. --- README.md | 14 ++- docs/guides/AGENTS.md | 8 ++ docs/guides/TOOLS.md | 7 ++ docs/product/DOMAIN_MAP.md | 2 +- docs/setup/CONFIGURATION.md | 11 +- docs/setup/INSTALLATION.md | 2 +- src/index.js | 195 ++++++++++++++++++++---------------- 7 files changed, 149 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 7ef3a40..75c739c 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,22 @@ PMA will guide the repository setup flow and, when needed, initialize NomadWorks ## Configure -During setup, PMA can initialize the repository and create `.nomadworks/nomadworks.yaml`. NomadWorks reads this file for repository-local defaults, feature flags, policy extraction settings, and per-agent overrides. +During setup, PMA can initialize the repository and create `.nomadworks/nomadworks.yaml`. NomadWorks reads this file for repository-local defaults, feature flags, policy extraction settings, and per-agent config overrides. Repository-local policy overrides live in `.nomadworks/policies/`. If a policy file is not present there, NomadWorks falls back to the bundled plugin default automatically. +Repository-specific agent additions can live in `.nomadworks/agents/`. For rare advanced cases, explicit full prompt replacements can live in `.nomadworks/agent-overrides/`. + +## Repository Customization + +- `.nomadworks/policies/*.md`: shared repository policy overrides used by multiple agents +- `.nomadworks/agents/.md`: additive repository-specific instructions appended to one bundled agent prompt +- `.nomadworks/agent-overrides/.md`: explicit full prompt replacement for advanced cases +- `.nomadworks/generated/agents/`: generated final prompt dumps for inspection when `features.debug_dumps` is enabled +- `.nomadworks/generated/policies/`: generated reference copies of bundled default policies when `policies.extract_defaults` is set to `all` + +Runtime prompt resolution prefers repository-local policies and agent additions when present, while keeping the plugin-owned workflow and role model intact by default. + NomadWorks supports two team presets: - `mini`: PMA + BA + Tech Lead for simple repositories and `tiny` / `standard` tasks diff --git a/docs/guides/AGENTS.md b/docs/guides/AGENTS.md index 86fcd2d..adc8718 100644 --- a/docs/guides/AGENTS.md +++ b/docs/guides/AGENTS.md @@ -34,6 +34,14 @@ These agents can talk directly with the user and turn meaningful discussions int `mode: all` does not make an agent an orchestrator by default. PMA remains the sole workflow orchestrator. Discussion-capable agents may speak directly with the user, but workflow-relevant work must still be handed back through task files and PMA-owned orchestration. +## Repository Customization + +- `.nomadworks/agents/.md`: appends repository-specific instructions to the bundled agent prompt. +- `.nomadworks/agent-overrides/.md`: explicitly replaces the bundled base prompt for advanced cases. +- `.nomadworks/policies/*.md`: overrides shared repository policy files used by multiple agents. + +Use additive agent files and shared policies by default. Prefer explicit full prompt replacement only when a repository truly needs to take over an agent's base prompt. + ## Typical usage by task complexity ### Tiny diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index a340e23..0b3412f 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -20,6 +20,13 @@ Initializes NomadWorks in the current repository. - `docs/scrs/current.md` - `docs/scrs/done.md` +### Notes + +- Repository-specific agent additions are optional and can be created later under `.nomadworks/agents/`. +- Explicit full prompt replacements are optional and can be created later under `.nomadworks/agent-overrides/`. +- Generated prompt dumps go to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. +- Generated reference policy files go to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. + ## `nomadworks_validate` Validates NomadWorks workflow artifacts and CodeMap integrity. diff --git a/docs/product/DOMAIN_MAP.md b/docs/product/DOMAIN_MAP.md index 207d86d..f995887 100644 --- a/docs/product/DOMAIN_MAP.md +++ b/docs/product/DOMAIN_MAP.md @@ -37,5 +37,5 @@ This document maps the major product domains and the features that belong to the ### Plugin Setup And Configuration - **Purpose:** Defines how NomadWorks is installed, configured, and enabled in an OpenCode environment. -- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, agent overrides, policy overrides. +- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, agent additions, explicit agent overrides, policy overrides. - **Primary Docs:** `docs/setup/INSTALLATION.md`, `docs/setup/CONFIGURATION.md` diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index f6e787d..ed4ecbe 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -33,7 +33,7 @@ agents: - `defaults`: Shared defaults for providers, models, permissions, and other agent config fields. - `features`: Plugin feature flags such as debug dumps and validation behavior. - `policies`: Policy extraction controls for generated reference policy files. -- `agents`: Per-agent enablement and overrides. +- `agents`: Per-agent enablement and config overrides from `nomadworks.yaml`. ## Supported team modes @@ -92,10 +92,17 @@ policies: This writes the bundled default policy files to `.nomadworks/generated/policies/` for reference. Those generated files are not used directly at runtime. To customize one, copy it into `.nomadworks/policies/` and edit the copy. +### Add repository-specific agent instructions + +Create `.nomadworks/agents/.md` to append repository-specific instructions to one bundled agent prompt. + +Use `.nomadworks/agent-overrides/.md` only for rare advanced cases where you need to replace the bundled base prompt explicitly. + ## Operational notes - The `product_manager` agent becomes the default primary agent when NomadWorks is enabled. -- Repository-local agent markdown overrides can live in `.nomadworks/agents/`. +- Repository-local agent additions can live in `.nomadworks/agents/`. +- Explicit full prompt replacements can live in `.nomadworks/agent-overrides/`. - Repository-local policy overrides can live in `.nomadworks/policies/`. - Generated reference policy files are written to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. - Final agent prompts are dumped to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. diff --git a/docs/setup/INSTALLATION.md b/docs/setup/INSTALLATION.md index 02944ce..2d7aae0 100644 --- a/docs/setup/INSTALLATION.md +++ b/docs/setup/INSTALLATION.md @@ -52,7 +52,7 @@ When PMA initializes the repository, NomadWorks creates: ## 5. Configure NomadWorks -Edit `.nomadworks/nomadworks.yaml` to set defaults, features, policy extraction behavior, and per-agent overrides. +Edit `.nomadworks/nomadworks.yaml` to set defaults, features, policy extraction behavior, and per-agent config overrides. Use `.nomadworks/agents/` for additive repo-specific agent instructions and `.nomadworks/agent-overrides/` only for explicit full prompt replacements. See: diff --git a/src/index.js b/src/index.js index 6aaece1..ad28a70 100644 --- a/src/index.js +++ b/src/index.js @@ -47,10 +47,14 @@ function generatedAgentsDir(worktree) { return path.join(nomadworksDir(worktree), "generated", "agents"); } -function repoAgentsDir(worktree) { +function repoAgentAdditionsDir(worktree) { return path.join(nomadworksDir(worktree), "agents"); } +function repoAgentOverridesDir(worktree) { + return path.join(nomadworksDir(worktree), "agent-overrides"); +} + function legacyRepoAgentsDir(worktree) { return path.join(legacyNomadworksDir(worktree), "nomadworks", "agents"); } @@ -395,6 +399,33 @@ function readResolvedFile(relativePath, worktree) { return resolveIncludes(fs.readFileSync(filePath, "utf8"), worktree, PKG_ROOT).trim(); } +function loadMarkdownFragment(filePath, worktree) { + if (!fs.existsSync(filePath)) return ""; + + try { + const raw = fs.readFileSync(filePath, "utf8"); + const { body } = parseFrontmatter(raw); + return resolveIncludes(body.trim(), worktree, PKG_ROOT); + } catch (e) { + console.error(`[NomadWorks] Failed to read markdown fragment ${filePath}:`, e); + return ""; + } +} + +function loadAgentDefinition(filePath, worktree) { + if (!fs.existsSync(filePath)) return null; + + try { + const rawContent = fs.readFileSync(filePath, "utf8"); + const { data, body } = parseFrontmatter(rawContent); + const prompt = resolveIncludes(body.trim(), worktree, PKG_ROOT); + return { data, prompt }; + } catch (e) { + console.error(`[NomadWorks] Failed to read agent definition ${filePath}:`, e); + return null; + } +} + function syncGeneratedPolicies(worktree, repoCfg) { if (repoCfg.policies?.extract_defaults !== "all") return; if (!fs.existsSync(BUNDLE_POLICIES_DIR)) return; @@ -918,109 +949,103 @@ export default async function NomadWorksPlugin(input) { const nomadworksActive = repoCfg && repoCfg.enabled === true; - // 1. Identify and compile all NomadWorks agents - const repoAgentsPrimaryDir = repoAgentsDir(worktree); + // 1. Identify and compile all NomadWorks agents from bundled bases, + // optional explicit overrides, and additive repo-local fragments. + const repoAgentAdditions = repoAgentAdditionsDir(worktree); + const repoAgentOverrides = repoAgentOverridesDir(worktree); const legacyAgentsDir = legacyRepoAgentsDir(worktree); - const agentSources = []; - if (fs.existsSync(BUNDLE_AGENTS_DIR)) agentSources.push(BUNDLE_AGENTS_DIR); - if (fs.existsSync(repoAgentsPrimaryDir)) agentSources.push(repoAgentsPrimaryDir); - if (fs.existsSync(legacyAgentsDir)) agentSources.push(legacyAgentsDir); + const bundledAgentFiles = fs.existsSync(BUNDLE_AGENTS_DIR) + ? fs.readdirSync(BUNDLE_AGENTS_DIR).filter(f => f.endsWith(".md")) + : []; const ourAgents = {}; - for (const agentsDir of agentSources) { - if (!fs.existsSync(agentsDir)) continue; - - let files = []; - try { - files = fs.readdirSync(agentsDir).filter(f => f.endsWith(".md")); - } catch (e) { - console.error(`[NomadWorks] Failed to read agents from ${agentsDir}:`, e); + for (const file of bundledAgentFiles) { + const id = file.replace(".md", ""); + + if (!nomadworksActive && id !== "product_manager") { continue; } - for (const file of files) { - const id = file.replace(".md", ""); - - if (!nomadworksActive && id !== "product_manager") { - continue; - } + const agentOverride = repoCfg.agents?.[id] || {}; + if (nomadworksActive && !isAgentEffectivelyEnabled(id, repoCfg)) continue; - const agentOverride = repoCfg.agents?.[id] || {}; - if (nomadworksActive && !isAgentEffectivelyEnabled(id, repoCfg)) continue; + const bundledDefinition = loadAgentDefinition(path.join(BUNDLE_AGENTS_DIR, file), worktree); + if (!bundledDefinition) continue; - const filePath = path.join(agentsDir, file); - let rawContent; - try { - rawContent = fs.readFileSync(filePath, "utf8"); - } catch (e) { - console.error(`[NomadWorks] Failed to read agent file ${filePath}:`, e); - continue; - } + const explicitOverride = loadAgentDefinition(path.join(repoAgentOverrides, file), worktree) + || loadAgentDefinition(path.join(legacyAgentsDir, file), worktree); - const { data, body } = parseFrontmatter(rawContent); - let finalPrompt = resolveIncludes(body.trim(), worktree, PKG_ROOT); - const modePromptFragment = getModePromptFragment(id, operatingTeamMode, worktree); - if (modePromptFragment) { - finalPrompt = `${finalPrompt}\n\n${modePromptFragment}`; - } - const provider = agentOverride.provider || data.provider || repoCfg.defaults?.provider; - const model = agentOverride.model || data.model || repoCfg.defaults?.model; - - const agentConfig = { - description: data.description, - mode: agentOverride.mode || data.mode || "subagent", - prompt: finalPrompt, - tools: { ...(data.tools || {}), ...(agentOverride.tools || {}) }, - permission: agentOverride.permission || data.permission || data.permissions || repoCfg.defaults?.permissions, - model: toModelString(provider, model), - temperature: agentOverride.temperature ?? data.temperature ?? repoCfg.defaults?.temperature, - disable: false - }; + const activeDefinition = explicitOverride || bundledDefinition; + const { data } = activeDefinition; - const specialKeys = ['description', 'mode', 'model', 'provider', 'temperature', 'permission', 'permissions', 'tools', 'tools_add', 'tools_remove', 'enabled', 'prompt', 'disable']; - - const defaults = repoCfg.defaults || {}; - for (const k of Object.keys(defaults)) { - if (!specialKeys.includes(k)) agentConfig[k] = defaults[k]; - } - for (const k of Object.keys(data)) { - if (!specialKeys.includes(k)) agentConfig[k] = data[k]; - } - for (const k of Object.keys(agentOverride)) { - if (!specialKeys.includes(k)) agentConfig[k] = agentOverride[k]; - } + let finalPrompt = activeDefinition.prompt; + const modePromptFragment = getModePromptFragment(id, operatingTeamMode, worktree); + if (modePromptFragment) { + finalPrompt = `${finalPrompt}\n\n${modePromptFragment}`; + } - if (Array.isArray(agentOverride.tools_add)) { - agentConfig.tools ??= {}; - for (const t of agentOverride.tools_add) agentConfig.tools[t] = true; - } - if (Array.isArray(agentOverride.tools_remove)) { - if (agentConfig.tools) { - for (const t of agentOverride.tools_remove) delete agentConfig.tools[t]; - } + const additionFragment = loadMarkdownFragment(path.join(repoAgentAdditions, file), worktree); + if (additionFragment) { + finalPrompt = `${finalPrompt}\n\n# Repository-Specific ${id} Additions\n\n${additionFragment}`; + } + + const provider = agentOverride.provider || data.provider || repoCfg.defaults?.provider; + const model = agentOverride.model || data.model || repoCfg.defaults?.model; + + const agentConfig = { + description: data.description, + mode: agentOverride.mode || data.mode || "subagent", + prompt: finalPrompt, + tools: { ...(data.tools || {}), ...(agentOverride.tools || {}) }, + permission: agentOverride.permission || data.permission || data.permissions || repoCfg.defaults?.permissions, + model: toModelString(provider, model), + temperature: agentOverride.temperature ?? data.temperature ?? repoCfg.defaults?.temperature, + disable: false + }; + + const specialKeys = ['description', 'mode', 'model', 'provider', 'temperature', 'permission', 'permissions', 'tools', 'tools_add', 'tools_remove', 'enabled', 'prompt', 'disable']; + + const defaults = repoCfg.defaults || {}; + for (const k of Object.keys(defaults)) { + if (!specialKeys.includes(k)) agentConfig[k] = defaults[k]; + } + for (const k of Object.keys(data)) { + if (!specialKeys.includes(k)) agentConfig[k] = data[k]; + } + for (const k of Object.keys(agentOverride)) { + if (!specialKeys.includes(k)) agentConfig[k] = agentOverride[k]; + } + + if (Array.isArray(agentOverride.tools_add)) { + agentConfig.tools ??= {}; + for (const t of agentOverride.tools_add) agentConfig.tools[t] = true; + } + if (Array.isArray(agentOverride.tools_remove)) { + if (agentConfig.tools) { + for (const t of agentOverride.tools_remove) delete agentConfig.tools[t]; } + } - if (id === "product_manager" && (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full")) { - if (agentConfig.tools) { - delete agentConfig.tools.nomadflow_run_workflow; - delete agentConfig.tools.nomadflow_prompt_workflow; - } + if (id === "product_manager" && (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full")) { + if (agentConfig.tools) { + delete agentConfig.tools.nomadflow_run_workflow; + delete agentConfig.tools.nomadflow_prompt_workflow; } + } - ourAgents[id] = agentConfig; + ourAgents[id] = agentConfig; - if (repoCfg.features?.debug_dumps !== false) { - const debugPath = path.join(debugDir, `${id}.md`); - const { prompt, ...dumpConfig } = agentConfig; - const debugHeader = `--- + if (repoCfg.features?.debug_dumps !== false) { + const debugPath = path.join(debugDir, `${id}.md`); + const { prompt, ...dumpConfig } = agentConfig; + const debugHeader = `--- ${YAML.stringify(dumpConfig).trim()} ---`; - try { - if (!fs.existsSync(debugDir)) fs.mkdirSync(debugDir, { recursive: true }); - fs.writeFileSync(debugPath, `${debugHeader}\n\n${prompt}`, "utf8"); - } catch (e) { /* ignore debug errors */ } - } + try { + if (!fs.existsSync(debugDir)) fs.mkdirSync(debugDir, { recursive: true }); + fs.writeFileSync(debugPath, `${debugHeader}\n\n${prompt}`, "utf8"); + } catch (e) { /* ignore debug errors */ } } } From 8cfd489d2382bbe19a5fda08c8f0cb5d427eb94f Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Fri, 17 Apr 2026 15:18:38 +0100 Subject: [PATCH 07/16] feat: support repo-defined custom agents Treat .nomadworks/agents as full repo-local agent definitions, use .nomadworks/agent-additions for additive fragments, scaffold README placeholders for the NomadWorks folders, and document the reusable plugin and policy includes for custom agents. --- README.md | 14 ++- docs/guides/AGENTS.md | 6 +- docs/guides/TOOLS.md | 9 +- docs/product/DOMAIN_MAP.md | 2 +- docs/setup/CONFIGURATION.md | 13 ++- docs/setup/INSTALLATION.md | 6 +- src/index.js | 178 +++++++++++++++++++++++++++++++----- 7 files changed, 188 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 75c739c..e880583 100644 --- a/README.md +++ b/README.md @@ -27,17 +27,23 @@ During setup, PMA can initialize the repository and create `.nomadworks/nomadwor Repository-local policy overrides live in `.nomadworks/policies/`. If a policy file is not present there, NomadWorks falls back to the bundled plugin default automatically. -Repository-specific agent additions can live in `.nomadworks/agents/`. For rare advanced cases, explicit full prompt replacements can live in `.nomadworks/agent-overrides/`. +Repository-local full agent definitions can live in `.nomadworks/agents/`. Use this folder to override a bundled agent's base prompt or define a brand new custom repository agent. + +Repository-specific additive agent instructions can live in `.nomadworks/agent-additions/`. ## Repository Customization - `.nomadworks/policies/*.md`: shared repository policy overrides used by multiple agents -- `.nomadworks/agents/.md`: additive repository-specific instructions appended to one bundled agent prompt -- `.nomadworks/agent-overrides/.md`: explicit full prompt replacement for advanced cases +- `.nomadworks/agents/.md`: full repository-local agent definition that overrides a bundled agent or defines a new custom agent +- `.nomadworks/agent-additions/.md`: additive repository-specific instructions appended to a bundled or custom agent prompt - `.nomadworks/generated/agents/`: generated final prompt dumps for inspection when `features.debug_dumps` is enabled - `.nomadworks/generated/policies/`: generated reference copies of bundled default policies when `policies.extract_defaults` is set to `all` -Runtime prompt resolution prefers repository-local policies and agent additions when present, while keeping the plugin-owned workflow and role model intact by default. +`nomadworks_init` also creates README placeholders in these folders so repositories can discover what each folder is for without those README files being treated as agents. + +The scaffolded README files in `.nomadworks/agents/` and `.nomadworks/agent-additions/` also list the common available `plugin:` and `policy:` includes that custom agents can reuse. + +Runtime prompt resolution prefers repository-local policies, agent definitions, and agent additions when present, while keeping the plugin-owned workflow and role model intact by default. NomadWorks supports two team presets: diff --git a/docs/guides/AGENTS.md b/docs/guides/AGENTS.md index adc8718..4bebc30 100644 --- a/docs/guides/AGENTS.md +++ b/docs/guides/AGENTS.md @@ -36,11 +36,11 @@ These agents can talk directly with the user and turn meaningful discussions int ## Repository Customization -- `.nomadworks/agents/.md`: appends repository-specific instructions to the bundled agent prompt. -- `.nomadworks/agent-overrides/.md`: explicitly replaces the bundled base prompt for advanced cases. +- `.nomadworks/agents/.md`: full repository-local agent definition. Use this to override a bundled agent's base prompt or define a brand new custom repository agent. +- `.nomadworks/agent-additions/.md`: appends repository-specific instructions to a bundled or custom agent prompt. - `.nomadworks/policies/*.md`: overrides shared repository policy files used by multiple agents. -Use additive agent files and shared policies by default. Prefer explicit full prompt replacement only when a repository truly needs to take over an agent's base prompt. +Use shared policies and additive agent files by default. Use full agent definitions in `.nomadworks/agents/` when a repository needs a custom agent or needs to take over an agent's base prompt. ## Typical usage by task complexity diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index 0b3412f..57ef148 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -14,6 +14,10 @@ Initializes NomadWorks in the current repository. - `.nomadworks/nomadworks.yaml` - `.nomadworks/policies/README.md` +- `.nomadworks/agents/README.md` +- `.nomadworks/agent-additions/README.md` +- `.nomadworks/generated/agents/README.md` +- `.nomadworks/generated/policies/README.md` - `codemap.yml` - `tasks/current.md` - `tasks/done.md` @@ -22,10 +26,11 @@ Initializes NomadWorks in the current repository. ### Notes -- Repository-specific agent additions are optional and can be created later under `.nomadworks/agents/`. -- Explicit full prompt replacements are optional and can be created later under `.nomadworks/agent-overrides/`. +- Full repository-local agent definitions or custom agents are optional and can be created later under `.nomadworks/agents/`. +- Repository-specific additive agent instructions are optional and can be created later under `.nomadworks/agent-additions/`. - Generated prompt dumps go to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. - Generated reference policy files go to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. +- The scaffolded README files in `.nomadworks/agents/` and `.nomadworks/agent-additions/` list common `plugin:` and `policy:` includes that custom agents can reuse. ## `nomadworks_validate` diff --git a/docs/product/DOMAIN_MAP.md b/docs/product/DOMAIN_MAP.md index f995887..7277820 100644 --- a/docs/product/DOMAIN_MAP.md +++ b/docs/product/DOMAIN_MAP.md @@ -37,5 +37,5 @@ This document maps the major product domains and the features that belong to the ### Plugin Setup And Configuration - **Purpose:** Defines how NomadWorks is installed, configured, and enabled in an OpenCode environment. -- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, agent additions, explicit agent overrides, policy overrides. +- **Owned Features:** plugin installation, OpenCode config wiring, `nomadworks.yaml`, repo-local agent definitions, agent additions, policy overrides. - **Primary Docs:** `docs/setup/INSTALLATION.md`, `docs/setup/CONFIGURATION.md` diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index ed4ecbe..c9f78c8 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -94,15 +94,20 @@ This writes the bundled default policy files to `.nomadworks/generated/policies/ ### Add repository-specific agent instructions -Create `.nomadworks/agents/.md` to append repository-specific instructions to one bundled agent prompt. +Create `.nomadworks/agent-additions/.md` to append repository-specific instructions to a bundled or custom agent prompt. -Use `.nomadworks/agent-overrides/.md` only for rare advanced cases where you need to replace the bundled base prompt explicitly. +### Add repository-local agents or override a bundled base prompt + +Create `.nomadworks/agents/.md` to: + +- replace the bundled base prompt for an existing agent, or +- define a brand new custom repository agent ## Operational notes - The `product_manager` agent becomes the default primary agent when NomadWorks is enabled. -- Repository-local agent additions can live in `.nomadworks/agents/`. -- Explicit full prompt replacements can live in `.nomadworks/agent-overrides/`. +- Repository-local full agent definitions can live in `.nomadworks/agents/`. +- Repository-local additive agent instructions can live in `.nomadworks/agent-additions/`. - Repository-local policy overrides can live in `.nomadworks/policies/`. - Generated reference policy files are written to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. - Final agent prompts are dumped to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. diff --git a/docs/setup/INSTALLATION.md b/docs/setup/INSTALLATION.md index 2d7aae0..4206870 100644 --- a/docs/setup/INSTALLATION.md +++ b/docs/setup/INSTALLATION.md @@ -44,6 +44,10 @@ When PMA initializes the repository, NomadWorks creates: - `.nomadworks/nomadworks.yaml` - `.nomadworks/policies/README.md` +- `.nomadworks/agents/README.md` +- `.nomadworks/agent-additions/README.md` +- `.nomadworks/generated/agents/README.md` +- `.nomadworks/generated/policies/README.md` - `codemap.yml` - `tasks/current.md` - `tasks/done.md` @@ -52,7 +56,7 @@ When PMA initializes the repository, NomadWorks creates: ## 5. Configure NomadWorks -Edit `.nomadworks/nomadworks.yaml` to set defaults, features, policy extraction behavior, and per-agent config overrides. Use `.nomadworks/agents/` for additive repo-specific agent instructions and `.nomadworks/agent-overrides/` only for explicit full prompt replacements. +Edit `.nomadworks/nomadworks.yaml` to set defaults, features, policy extraction behavior, and per-agent config overrides. Use `.nomadworks/agents/` for full repository-local agent definitions or custom agents, and `.nomadworks/agent-additions/` for additive repo-specific agent instructions. See: diff --git a/src/index.js b/src/index.js index ad28a70..6453a02 100644 --- a/src/index.js +++ b/src/index.js @@ -47,12 +47,12 @@ function generatedAgentsDir(worktree) { return path.join(nomadworksDir(worktree), "generated", "agents"); } -function repoAgentAdditionsDir(worktree) { +function repoAgentsDir(worktree) { return path.join(nomadworksDir(worktree), "agents"); } -function repoAgentOverridesDir(worktree) { - return path.join(nomadworksDir(worktree), "agent-overrides"); +function repoAgentAdditionsDir(worktree) { + return path.join(nomadworksDir(worktree), "agent-additions"); } function legacyRepoAgentsDir(worktree) { @@ -77,6 +77,18 @@ function resolveConfigPath(worktree) { return repoPath; } +function listMarkdownFiles(dirPath) { + if (!fs.existsSync(dirPath)) return []; + + try { + return fs.readdirSync(dirPath) + .filter(file => file.endsWith(".md") && file.toLowerCase() !== "readme.md"); + } catch (e) { + console.error(`[NomadWorks] Failed to read markdown files from ${dirPath}:`, e); + return []; + } +} + function normalizePolicyExtraction(value) { if (typeof value !== "string") return "none"; return value.trim().toLowerCase() === "all" ? "all" : "none"; @@ -452,6 +464,117 @@ function syncGeneratedPolicies(worktree, repoCfg) { } } +function ensureReadmeFile(dirPath, content) { + if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath, { recursive: true }); + const readmePath = path.join(dirPath, "README.md"); + if (!fs.existsSync(readmePath)) { + fs.writeFileSync(readmePath, content, "utf8"); + } +} + +function scaffoldNomadworksReadmes(worktree) { + ensureReadmeFile(repoPoliciesDir(worktree), fs.readFileSync(path.join(BUNDLE_POLICIES_DIR, "README.md"), "utf8")); + ensureReadmeFile(repoAgentsDir(worktree), [ + "# Repository Agents", + "", + "Place full repository-local agent definitions here.", + "", + "- Use `.nomadworks/agents/.md` to override a bundled agent's full base definition.", + "- Use `.nomadworks/agents/.md` to define a brand new custom repository agent.", + "- Files in this folder are treated as full agent definitions.", + "- `README.md` is ignored by agent discovery.", + "", + "## Include Types Available In Custom Agents", + "", + "Custom agents can use the same include resolution as bundled agents:", + "", + "- `` for plugin-owned shared guidance", + "- `` for repository-overridable policy files with bundled defaults", + "- `` for explicit files under `.nomadworks/`", + "", + "## Common Plugin Includes", + "", + "- `plugin:Agents_Common.md`", + "- `plugin:docs/core/agent_orchestration.md`", + "- `plugin:docs/core/communication_guidelines.md`", + "- `plugin:docs/core/discussion_agent_guidelines.md`", + "- `plugin:docs/core/role_contracts.md`", + "- `plugin:docs/core/task_model.md`", + "- `plugin:docs/core/codemap_conventions.md`", + "- `plugin:docs/core/pma_mode_full.md`", + "- `plugin:docs/core/pma_mode_mini.md`", + "- `plugin:docs/core/tech_lead_mode_full.md`", + "- `plugin:docs/core/tech_lead_mode_mini.md`", + "", + "## Available Policy Includes", + "", + "- `policy:development-guidelines.md`", + "- `policy:testing-guidelines.md`", + "- `policy:documentation-guidelines.md`", + "- `policy:git-commit-messaging.md`", + "- `policy:product-guidelines.md`", + "- `policy:ui-ux-guidelines.md`", + "" + ].join("\n")); + ensureReadmeFile(repoAgentAdditionsDir(worktree), [ + "# Repository Agent Additions", + "", + "Place additive prompt fragments here to append repository-specific instructions to an existing agent.", + "", + "- Use `.nomadworks/agent-additions/.md` to add instructions to a bundled or custom repo agent.", + "- The matching base agent must exist in the plugin bundle or `.nomadworks/agents/`.", + "- `README.md` is ignored by agent discovery.", + "", + "## Include Types Available In Additions", + "", + "Agent additions can use the same include resolution as bundled agents and custom agents:", + "", + "- `` for plugin-owned shared guidance", + "- `` for repository-overridable policy files with bundled defaults", + "- `` for explicit files under `.nomadworks/`", + "", + "## Common Plugin Includes", + "", + "- `plugin:Agents_Common.md`", + "- `plugin:docs/core/agent_orchestration.md`", + "- `plugin:docs/core/communication_guidelines.md`", + "- `plugin:docs/core/discussion_agent_guidelines.md`", + "- `plugin:docs/core/role_contracts.md`", + "- `plugin:docs/core/task_model.md`", + "- `plugin:docs/core/codemap_conventions.md`", + "", + "## Available Policy Includes", + "", + "- `policy:development-guidelines.md`", + "- `policy:testing-guidelines.md`", + "- `policy:documentation-guidelines.md`", + "- `policy:git-commit-messaging.md`", + "- `policy:product-guidelines.md`", + "- `policy:ui-ux-guidelines.md`", + "" + ].join("\n")); + ensureReadmeFile(generatedAgentsDir(worktree), [ + "# Generated Agent Prompts", + "", + "This folder contains generated final prompt dumps for inspection.", + "", + "- Files here are generated by NomadWorks and may be overwritten.", + "- Do not edit files here to customize agent behavior.", + "- Use `.nomadworks/agents/` for full agent definitions and `.nomadworks/agent-additions/` for additive instructions.", + "" + ].join("\n")); + ensureReadmeFile(generatedPoliciesDir(worktree), [ + "# Generated Policy References", + "", + "This folder contains generated reference copies of bundled default policy files.", + "", + "- Files here are generated by NomadWorks and may be overwritten.", + "- Runtime does not read policies from this folder directly.", + "- Copy a file into `.nomadworks/policies/` if you want to customize it.", + "" + ].join("\n")); +} + function getModePromptFragment(agentId, operatingTeamMode, worktree) { const fragmentMap = { product_manager: { @@ -485,6 +608,7 @@ export default async function NomadWorksPlugin(input) { } } repoCfg = applyTeamConfigRules(repoCfg); + scaffoldNomadworksReadmes(worktree); syncGeneratedPolicies(worktree, repoCfg); const operatingTeamMode = getOperatingTeamMode(repoCfg); @@ -557,9 +681,7 @@ export default async function NomadWorksPlugin(input) { } const cfgDir = nomadworksDir(context.worktree); - const policiesDir = repoPoliciesDir(context.worktree); if (!fs.existsSync(cfgDir)) fs.mkdirSync(cfgDir, { recursive: true }); - if (!fs.existsSync(policiesDir)) fs.mkdirSync(policiesDir, { recursive: true }); // Discover all agent IDs to enable them explicitly const agentIds = fs.existsSync(BUNDLE_AGENTS_DIR) @@ -568,9 +690,7 @@ export default async function NomadWorksPlugin(input) { const nomadworksTmplPath = path.join(TEMPLATES_DIR, "nomadworks.yaml.template"); const codemapTmplPath = path.join(TEMPLATES_DIR, "codemap.yml.template"); - const policiesReadmePath = path.join(BUNDLE_POLICIES_DIR, "README.md"); - - if (!fs.existsSync(nomadworksTmplPath) || !fs.existsSync(codemapTmplPath) || !fs.existsSync(policiesReadmePath)) { + if (!fs.existsSync(nomadworksTmplPath) || !fs.existsSync(codemapTmplPath)) { return "Error: Initialization templates not found in plugin."; } @@ -590,7 +710,6 @@ export default async function NomadWorksPlugin(input) { const cfgFilePath = path.join(cfgDir, "nomadworks.yaml"); const rootCodemapPath = path.join(context.worktree, "codemap.yml"); - const policiesReadmeTargetPath = path.join(policiesDir, "README.md"); if (!fs.existsSync(cfgFilePath)) { fs.writeFileSync(cfgFilePath, nomadworksConfig, "utf8"); @@ -600,9 +719,7 @@ export default async function NomadWorksPlugin(input) { fs.writeFileSync(rootCodemapPath, codemapConfig, "utf8"); } - if (!fs.existsSync(policiesReadmeTargetPath)) { - fs.writeFileSync(policiesReadmeTargetPath, fs.readFileSync(policiesReadmePath, "utf8"), "utf8"); - } + scaffoldNomadworksReadmes(context.worktree); // Scaffold Task Registries const tasksDir = path.join(context.worktree, "tasks"); @@ -628,7 +745,7 @@ export default async function NomadWorksPlugin(input) { fs.writeFileSync(scrsDonePath, "# Implemented Spec Change Requests\n\n| Date | SCR ID | Title | Related Feature | Task ID |\n| :--- | :--- | :--- | :--- | :--- |\n", "utf8"); } - return `NomadWorks initialized in '${requestedTeamMode}' team mode: .nomadworks/nomadworks.yaml, policy README, registries, and codemap.yml created.`; + return `NomadWorks initialized in '${requestedTeamMode}' team mode: .nomadworks/nomadworks.yaml, repo policy/agent folders, registries, and codemap.yml created.`; } }), nomadworks_validate: tool({ @@ -950,33 +1067,44 @@ export default async function NomadWorksPlugin(input) { const nomadworksActive = repoCfg && repoCfg.enabled === true; // 1. Identify and compile all NomadWorks agents from bundled bases, - // optional explicit overrides, and additive repo-local fragments. + // repo-local full definitions, and additive repo-local fragments. + const repoAgentDefinitions = repoAgentsDir(worktree); const repoAgentAdditions = repoAgentAdditionsDir(worktree); - const repoAgentOverrides = repoAgentOverridesDir(worktree); const legacyAgentsDir = legacyRepoAgentsDir(worktree); - const bundledAgentFiles = fs.existsSync(BUNDLE_AGENTS_DIR) - ? fs.readdirSync(BUNDLE_AGENTS_DIR).filter(f => f.endsWith(".md")) - : []; + const bundledAgentFiles = listMarkdownFiles(BUNDLE_AGENTS_DIR); + const repoAgentFiles = listMarkdownFiles(repoAgentDefinitions); + const legacyAgentFiles = listMarkdownFiles(legacyAgentsDir); + const agentIds = new Set([ + ...bundledAgentFiles.map(file => file.replace(".md", "")), + ...repoAgentFiles.map(file => file.replace(".md", "")), + ...legacyAgentFiles.map(file => file.replace(".md", "")) + ]); const ourAgents = {}; - for (const file of bundledAgentFiles) { - const id = file.replace(".md", ""); + for (const id of agentIds) { + const file = `${id}.md`; if (!nomadworksActive && id !== "product_manager") { continue; } const agentOverride = repoCfg.agents?.[id] || {}; - if (nomadworksActive && !isAgentEffectivelyEnabled(id, repoCfg)) continue; + const hasRepoDefinedAgent = repoAgentFiles.includes(file) || legacyAgentFiles.includes(file); + if (nomadworksActive) { + const enabledByConfig = typeof agentOverride.enabled === "boolean" ? agentOverride.enabled : null; + const enabled = enabledByConfig !== null + ? enabledByConfig || MANDATORY_AGENTS.has(id) + : (hasRepoDefinedAgent ? true : isAgentEffectivelyEnabled(id, repoCfg)); + if (!enabled) continue; + } const bundledDefinition = loadAgentDefinition(path.join(BUNDLE_AGENTS_DIR, file), worktree); - if (!bundledDefinition) continue; - - const explicitOverride = loadAgentDefinition(path.join(repoAgentOverrides, file), worktree) + const repoDefinition = loadAgentDefinition(path.join(repoAgentDefinitions, file), worktree) || loadAgentDefinition(path.join(legacyAgentsDir, file), worktree); - const activeDefinition = explicitOverride || bundledDefinition; + const activeDefinition = repoDefinition || bundledDefinition; + if (!activeDefinition) continue; const { data } = activeDefinition; let finalPrompt = activeDefinition.prompt; From bf62fb4836d732e698ed3046f474bae803ca8fbb Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Sat, 18 Apr 2026 00:42:28 +0100 Subject: [PATCH 08/16] feat: summarize discussions on stop Move discussion summarization into the nomadworks_stop_discussion tool flow, store raw transcripts in runtime until closure, archive them after BA writes the final summary artifact, and document the new synchronous stop behavior. --- docs/core/discussion_agent_guidelines.md | 6 + docs/guides/TOOLS.md | 11 +- src/index.js | 261 ++++++++++++++++++++--- 3 files changed, 246 insertions(+), 32 deletions(-) diff --git a/docs/core/discussion_agent_guidelines.md b/docs/core/discussion_agent_guidelines.md index 68499bb..a283dcf 100644 --- a/docs/core/discussion_agent_guidelines.md +++ b/docs/core/discussion_agent_guidelines.md @@ -13,6 +13,12 @@ Discussion transcript tools: - `nomadworks_start_discussion(title, previous_message_count)` - `nomadworks_stop_discussion()` +Discussion lifecycle: + +- While a discussion is active, NomadWorks captures the raw transcript in `.nomadworks/runtime/discussions/`. +- When `nomadworks_stop_discussion()` is requested, the tool itself invokes `business_analyst` with a blocking prompt to rewrite the runtime transcript into a structured summary in `tasks/discussions/`. +- The archived workflow-facing summary is the artifact later agents should read. The raw transcript is archived in runtime after summarization. + ## Direct User Discussion - You may speak directly with the user in your area of responsibility. diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index 57ef148..e035540 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -64,7 +64,8 @@ Also provide: - Use `0` if the discussion starts now. - Use `existing_discussion_id` plus `previous_message_count` to reopen an older discussion and include a small amount of newer conversation that happened before the reopen call. - Only one active discussion is allowed per session. -- Discussion transcripts are stored in `tasks/discussions/`. +- While active, raw discussion transcripts are stored in `.nomadworks/runtime/discussions/`. +- The durable workflow artifact is written to `tasks/discussions/` when the discussion is stopped and summarized. - Active discussion state is persisted in `.nomadworks/runtime/discussions.json`. - Only discussion-capable agents should use these discussion tools. @@ -72,7 +73,13 @@ Also provide: Stops the automatic discussion transcript for the current session. -The discussion is first marked `closing`, the current assistant reply is captured, and then the file is marked `closed`. +This tool performs the full close flow synchronously: + +- marks the runtime transcript as summarizing +- invokes `business_analyst` with a blocking prompt to write the structured summary to `tasks/discussions/` +- verifies the summary file was written successfully +- archives the raw runtime transcript +- returns the final closed result from the tool call itself ## `nomadflow_run_workflow` diff --git a/src/index.js b/src/index.js index 6453a02..bbd330c 100644 --- a/src/index.js +++ b/src/index.js @@ -251,35 +251,65 @@ function saveDiscussionRegistry(worktree, registry) { fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2), "utf8"); } +function runtimeDiscussionsDir(worktree) { + return path.join(nomadworksDir(worktree), "runtime", "discussions"); +} + +function archivedRuntimeDiscussionsDir(worktree) { + return path.join(runtimeDiscussionsDir(worktree), "archive"); +} + +function finalDiscussionsDir(worktree) { + return path.join(worktree, "tasks", "discussions"); +} + function nextDiscussionIdentity(worktree, title) { - const discussionsDir = path.join(worktree, "tasks", "discussions"); + const discussionsDir = finalDiscussionsDir(worktree); + const runtimeDir = runtimeDiscussionsDir(worktree); if (!fs.existsSync(discussionsDir)) fs.mkdirSync(discussionsDir, { recursive: true }); + if (!fs.existsSync(runtimeDir)) fs.mkdirSync(runtimeDir, { recursive: true }); let sequence = 1; while (true) { const id = `DISCUSSION-${String(sequence).padStart(3, "0")}`; const filename = `${id}-${slugifyTitle(title)}.md`; - const relativePath = path.join("tasks", "discussions", filename); - const absolutePath = path.join(worktree, relativePath); - if (!fs.existsSync(absolutePath)) { - return { id, filename, relativePath, absolutePath }; + const summaryRelativePath = path.join("tasks", "discussions", filename); + const summaryAbsolutePath = path.join(worktree, summaryRelativePath); + const transcriptFilename = `${id}-transcript.md`; + const transcriptRelativePath = path.join(".nomadworks", "runtime", "discussions", transcriptFilename); + const transcriptAbsolutePath = path.join(worktree, transcriptRelativePath); + if (!fs.existsSync(summaryAbsolutePath) && !fs.existsSync(transcriptAbsolutePath)) { + return { + id, + filename, + summaryRelativePath, + summaryAbsolutePath, + transcriptFilename, + transcriptRelativePath, + transcriptAbsolutePath + }; } sequence += 1; } } function findDiscussionById(worktree, discussionID) { - const discussionsDir = path.join(worktree, "tasks", "discussions"); + const discussionsDir = finalDiscussionsDir(worktree); if (!fs.existsSync(discussionsDir)) return null; const entries = fs.readdirSync(discussionsDir).filter(name => name.startsWith(`${discussionID}-`) && name.endsWith(".md")); if (entries.length === 0) return null; const filename = entries.sort()[0]; + const transcriptFilename = `${discussionID}-transcript.md`; return { + id: discussionID, filename, - relativePath: path.join("tasks", "discussions", filename), - absolutePath: path.join(discussionsDir, filename) + summaryRelativePath: path.join("tasks", "discussions", filename), + summaryAbsolutePath: path.join(discussionsDir, filename), + transcriptFilename, + transcriptRelativePath: path.join(".nomadworks", "runtime", "discussions", transcriptFilename), + transcriptAbsolutePath: path.join(runtimeDiscussionsDir(worktree), transcriptFilename) }; } @@ -356,12 +386,167 @@ async function appendMessageIfNeeded(client, worktree, registry, sessionID, mess const text = extractTextParts(response.data.parts || []); if (!text) return; - appendDiscussionMessage(path.join(worktree, discussion.filePath), speaker, text, messageID); + appendDiscussionMessage(path.join(worktree, discussion.transcriptPath), speaker, text, messageID); discussion.appendedMessageIDs ??= []; discussion.appendedMessageIDs.push(messageID); saveDiscussionRegistry(worktree, registry); } +async function summarizeDiscussionWithBA(client, worktree, discussion) { + const transcriptPath = path.join(worktree, discussion.transcriptPath); + const summaryPath = path.join(worktree, discussion.summaryPath); + const summaryDir = path.dirname(summaryPath); + if (!fs.existsSync(summaryDir)) fs.mkdirSync(summaryDir, { recursive: true }); + + const hasExistingSummary = fs.existsSync(summaryPath); + const priorMtimeMs = hasExistingSummary ? fs.statSync(summaryPath).mtimeMs : null; + const summarizerSession = await client.session.create({ + body: { title: `Discussion Summary: ${discussion.id}` } + }); + + const promptText = [ + "[Agent Message] From: product_manager To: business_analyst", + "", + "Read the full runtime discussion transcript and convert it into a workflow-ready discussion summary.", + "", + `Discussion ID: ${discussion.id}`, + `Discussion Title: ${discussion.title}`, + `Source transcript: ${discussion.transcriptPath}`, + hasExistingSummary ? `Existing summary to update: ${discussion.summaryPath}` : "Existing summary to update: (none)", + `Write the final summary to this exact file path: ${discussion.summaryPath}`, + "", + "Do not return the full summary in chat. Write it into the target file and then return only a short confirmation that includes:", + "- the target file path", + "- whether the write succeeded", + "", + "Requirements:", + "1. Preserve all workflow-relevant detail.", + "2. Remove greetings, filler, repetition, and conversational back-and-forth that does not affect execution.", + "3. Do not omit facts, requests, constraints, non-goals, decisions, assumptions, open questions, risks, or referenced repository areas.", + "4. If something is unresolved, record it under Open Questions rather than guessing.", + "5. Convert implied but clearly supported details into explicit bullets when helpful.", + "6. Optimize the result for PMA and later subagents to act on it efficiently.", + "7. Do not include transcript-style dialogue formatting in the final artifact.", + "8. If an existing summary file is present, read it and carry forward its still-valid details while integrating the new transcript content.", + "", + "Write the file in this exact structure:", + "", + "---", + `id: ${discussion.id}`, + `title: ${JSON.stringify(discussion.title)}`, + "status: closed", + "summarized_by: business_analyst", + "source: runtime-transcript", + "---", + "", + "# Discussion Summary", + "", + "## Topic", + "", + "", + "## Purpose", + "", + "", + "## Repository Truth Relevant To This Discussion", + "- ...", + "", + "## Facts Established", + "- ...", + "", + "## Requirements Captured", + "- ...", + "", + "## Constraints", + "- ...", + "", + "## Non-Goals", + "- ...", + "", + "## Decisions Made", + "- ...", + "", + "## Assumptions", + "- ...", + "", + "## Open Questions", + "- ...", + "", + "## Risks Or Concerns", + "- ...", + "", + "## Referenced Files Or Areas", + "- ...", + "", + "## Recommended Workflow Next Step", + "- assigned_to: ", + "- why: ", + "", + "Quality bar:", + "- concise but complete", + "- no fluff", + "- no invented details", + "- no lost workflow-relevant detail", + "", + "If a later agent could make a wrong decision because a detail was omitted, that omission is a failure." + ].join("\n"); + + const response = await client.session.prompt({ + path: { id: summarizerSession.data.id }, + body: { + agent: "business_analyst", + parts: [{ type: "text", text: promptText }] + } + }); + + const confirmation = extractTextParts(response.data.parts || []); + return { confirmation, summaryPath, transcriptPath, hasExistingSummary, priorMtimeMs }; +} + +function archiveDiscussionTranscript(worktree, transcriptRelativePath) { + const sourcePath = path.join(worktree, transcriptRelativePath); + if (!fs.existsSync(sourcePath)) return null; + + const archiveDir = archivedRuntimeDiscussionsDir(worktree); + if (!fs.existsSync(archiveDir)) fs.mkdirSync(archiveDir, { recursive: true }); + + const targetPath = path.join(archiveDir, path.basename(sourcePath)); + fs.renameSync(sourcePath, targetPath); + return targetPath; +} + +async function finalizeClosingDiscussion(client, worktree, registry, sessionID, discussion) { + const { confirmation, summaryPath, hasExistingSummary, priorMtimeMs } = await summarizeDiscussionWithBA(client, worktree, discussion); + if (!fs.existsSync(summaryPath)) { + throw new Error(`Discussion summary was not written to ${discussion.summaryPath}`); + } + + if (hasExistingSummary) { + const currentMtimeMs = fs.statSync(summaryPath).mtimeMs; + if (currentMtimeMs <= priorMtimeMs) { + throw new Error(`Discussion summary file was not updated at ${discussion.summaryPath}`); + } + } + + const summaryContent = fs.readFileSync(summaryPath, "utf8").trim(); + if (!summaryContent) { + throw new Error(`Discussion summary file is empty at ${discussion.summaryPath}`); + } + + const transcriptPath = path.join(worktree, discussion.transcriptPath); + setDiscussionStatus(transcriptPath, "closed"); + const archivedTranscriptPath = archiveDiscussionTranscript(worktree, discussion.transcriptPath); + delete registry.active[sessionID]; + saveDiscussionRegistry(worktree, registry); + + return { + confirmation, + summaryPath: discussion.summaryPath, + archivedTranscriptPath: archivedTranscriptPath + ? path.relative(worktree, archivedTranscriptPath) + : path.join(".nomadworks", "runtime", "discussions", "archive", path.basename(discussion.transcriptPath)) + }; +} + function normalizeTeamMode(value) { if (typeof value !== "string") return "full"; const normalized = value.trim().toLowerCase(); @@ -807,22 +992,34 @@ export default async function NomadWorksPlugin(input) { } } - const existingFile = parseDiscussionFile(identity.absolutePath); + const existingFile = parseDiscussionFile(identity.summaryAbsolutePath); discussionTitle = existingFile.data.title || existingDiscussionID; - writeDiscussionFile(identity.absolutePath, { - ...existingFile.data, + const frontmatter = { + id: existingDiscussionID, + title: discussionTitle, status: "active", agent, - session_id: sessionID - }, existingFile.body); + session_id: sessionID, + appended_message_ids: [] + }; + const body = [ + `# Discussion: ${discussionTitle}`, + "", + "## Prior Summary Reference", + `Source summary file: ${identity.summaryRelativePath}`, + "", + "## Messages" + ].join("\n"); + writeDiscussionFile(identity.transcriptAbsolutePath, frontmatter, body); entry = { id: existingDiscussionID, title: discussionTitle, - filePath: identity.relativePath, + transcriptPath: identity.transcriptRelativePath, + summaryPath: identity.summaryRelativePath, status: "active", agent, - appendedMessageIDs: Array.isArray(existingFile.data.appended_message_ids) ? [...existingFile.data.appended_message_ids] : [] + appendedMessageIDs: [] }; } else { discussionTitle = title; @@ -835,12 +1032,13 @@ export default async function NomadWorksPlugin(input) { session_id: sessionID, appended_message_ids: [] }; - writeDiscussionFile(identity.absolutePath, frontmatter, `# Discussion: ${discussionTitle}\n\n## Messages`); + writeDiscussionFile(identity.transcriptAbsolutePath, frontmatter, `# Discussion: ${discussionTitle}\n\n## Messages`); entry = { id: identity.id, title: discussionTitle, - filePath: identity.relativePath, + transcriptPath: identity.transcriptRelativePath, + summaryPath: identity.summaryRelativePath, status: "active", agent, appendedMessageIDs: [] @@ -861,14 +1059,14 @@ export default async function NomadWorksPlugin(input) { if (message.info.role === "user") { const text = extractTextParts(message.parts || []); if (text) { - appendDiscussionMessage(identity.absolutePath, "User", text, message.info.id); + appendDiscussionMessage(identity.transcriptAbsolutePath, "User", text, message.info.id); if (!entry.appendedMessageIDs.includes(message.info.id)) entry.appendedMessageIDs.push(message.info.id); backfilled += 1; } } else if (message.info.role === "assistant") { const text = extractTextParts(message.parts || []); if (text) { - appendDiscussionMessage(identity.absolutePath, agent, text, message.info.id); + appendDiscussionMessage(identity.transcriptAbsolutePath, agent, text, message.info.id); if (!entry.appendedMessageIDs.includes(message.info.id)) entry.appendedMessageIDs.push(message.info.id); backfilled += 1; } @@ -881,7 +1079,7 @@ export default async function NomadWorksPlugin(input) { } const action = existingDiscussionID ? "reopened" : "started"; - return `SUCCESS: Discussion ${action}.\nID: ${entry.id}\nTitle: ${discussionTitle}\nFile: ${identity.relativePath}\nStatus: active\nBackfilled messages: ${backfilled}`; + return `SUCCESS: Discussion ${action}.\nID: ${entry.id}\nTitle: ${discussionTitle}\nTranscript: ${entry.transcriptPath}\nFinal Summary Target: ${entry.summaryPath}\nStatus: active\nBackfilled messages: ${backfilled}`; } }), nomadworks_stop_discussion: tool({ @@ -896,12 +1094,20 @@ export default async function NomadWorksPlugin(input) { return "FAIL: No active discussion exists for this session."; } - const discussionPath = path.join(context.worktree, existing.filePath); - setDiscussionStatus(discussionPath, "closing"); - existing.status = "closing"; + const discussionPath = path.join(context.worktree, existing.transcriptPath); + setDiscussionStatus(discussionPath, "summarizing"); + existing.status = "summarizing"; saveDiscussionRegistry(context.worktree, discussionRegistry); - return `SUCCESS: Discussion stop requested.\nID: ${existing.id}\nTitle: ${existing.title}\nFile: ${existing.filePath}\nStatus: closing`; + try { + const result = await finalizeClosingDiscussion(input.client, context.worktree, discussionRegistry, sessionID, existing); + return `SUCCESS: Discussion stopped and summarized.\nID: ${existing.id}\nTitle: ${existing.title}\nFinal Summary: ${result.summaryPath}\nStatus: closed`; + } catch (err) { + setDiscussionStatus(discussionPath, "active"); + existing.status = "active"; + saveDiscussionRegistry(context.worktree, discussionRegistry); + return `FAIL: Discussion summarization failed.\nID: ${existing.id}\nTitle: ${existing.title}\nTranscript: ${existing.transcriptPath}\nFinal Summary Target: ${existing.summaryPath}\nReason: ${err.message}`; + } } }), nomadflow_run_workflow: tool({ @@ -1050,11 +1256,6 @@ export default async function NomadWorksPlugin(input) { if (info.role === "assistant" && info.time?.completed) { const discussion = discussionRegistry.active[info.sessionID]; await appendMessageIfNeeded(client, worktree, discussionRegistry, info.sessionID, info.id, discussion.agent || "Assistant"); - if (discussion?.status === "closing") { - setDiscussionStatus(path.join(worktree, discussion.filePath), "closed"); - delete discussionRegistry.active[info.sessionID]; - saveDiscussionRegistry(worktree, discussionRegistry); - } } } catch (err) { if (debug) console.error("[NomadWorks] Failed to append discussion transcript:", err); From 36477b8779f881ef4ef3d4c288c8abdca41418ae Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Mon, 20 Apr 2026 14:25:37 +0100 Subject: [PATCH 09/16] feat: add definition of ready and done policies Add bundled Definition of Ready and Definition of Done policy files, include them in the shared agent prompt, and reflect them in task and subtask templates with lightweight readiness, completion, and per-AC verification mapping checklists. --- Agents_Common.md | 3 +++ docs/domains/task-lifecycle/OVERVIEW.md | 3 +++ policies/README.md | 8 ++++++ policies/definition-of-done.md | 26 +++++++++++++++++++ policies/definition-of-ready.md | 27 ++++++++++++++++++++ tasks/subtask-template.md | 19 ++++++++++++++ tasks/task-template.md | 34 +++++++++++++++++++++++++ 7 files changed, 120 insertions(+) create mode 100644 policies/definition-of-done.md create mode 100644 policies/definition-of-ready.md diff --git a/Agents_Common.md b/Agents_Common.md index bef612b..d91c0de 100644 --- a/Agents_Common.md +++ b/Agents_Common.md @@ -55,6 +55,7 @@ That document defines: * **Documentation Reading:** Whenever reading any file under `docs/` or `tasks/`, the file MUST be read fully to ensure complete understanding of the context and requirements. * **Role-Specific Guidelines:** Every agent is responsible for reading the core guidance and any applicable repository policy includes that are part of their prompt. +* **Definition Of Ready / Done:** All execution should follow the repository's active Definition of Ready and Definition of Done policies. * **Signed Agent Messages:** Agent-to-agent interactions must begin with a signed first message that clearly identifies the sending and receiving agents. Use this exact format on the first line: `[Agent Message] From: To: `. Example: `[Agent Message] From: product_manager To: tech_lead`. If a message does not begin with an agent signature, agents should assume they are speaking directly with the user. * **Pre-task Clarification:** Before starting any task, thoroughly review requirements. If anything is missing, ambiguous, or insufficient, immediately stop and clearly state what is needed, requesting clarification from the manager agent. Do not proceed until all requirements are clear. * **CodeMap-First Navigation:** Before broad repository search, agents should consult the most relevant `codemap.yml` chain for the area they are trying to understand. Use local, parent, root, or explicitly targeted module CodeMaps as the first navigation pass. If no suitable CodeMap exists or it is insufficient, agents may then expand into direct search and source inspection. @@ -95,5 +96,7 @@ All documentation updates must follow the repository's documentation policy for: - documentation ownership, naming, and layout conventions + + diff --git a/docs/domains/task-lifecycle/OVERVIEW.md b/docs/domains/task-lifecycle/OVERVIEW.md index 83d8965..defe310 100644 --- a/docs/domains/task-lifecycle/OVERVIEW.md +++ b/docs/domains/task-lifecycle/OVERVIEW.md @@ -13,6 +13,7 @@ This domain includes: - task classification by `tiny`, `standard`, and `complex` - task routing by `implementation`, `investigation`, and `spec` - slice-based task planning using `foundation`, `core`, `logic`, `ui`, `polish`, `qa`, and `docs` +- definition-of-ready and definition-of-done expectations for task execution - pre-sync quorum rules - task execution flow and handoff expectations - verification and archiving expectations @@ -61,6 +62,8 @@ This domain does not include: - `docs/core/task_model.md` - `docs/core/agent_orchestration.md` +- `.nomadworks/policies/definition-of-ready.md` +- `.nomadworks/policies/definition-of-done.md` - `tasks/task-template.md` - `tasks/subtask-template.md` - `docs/core/documentation_structure.md` diff --git a/policies/README.md b/policies/README.md index 1d8aecd..9adc62c 100644 --- a/policies/README.md +++ b/policies/README.md @@ -25,6 +25,14 @@ Files under `.nomadworks/generated/policies/` are reference copies only. They ar - Documentation layout, naming, ownership, and update expectations. - Used by all agents through the shared prompt. +- `definition-of-ready.md` + - Canonical readiness criteria before execution begins. + - Used by all agents through the shared prompt and reflected in task templates. + +- `definition-of-done.md` + - Canonical completion criteria before closure. + - Used by all agents through the shared prompt and reflected in task templates. + - `git-commit-messaging.md` - Commit subject and body rules. - Used by: `tech_lead`, `workflow_runner` diff --git a/policies/definition-of-done.md b/policies/definition-of-done.md new file mode 100644 index 0000000..efd033b --- /dev/null +++ b/policies/definition-of-done.md @@ -0,0 +1,26 @@ +# Definition Of Done + +A task is done only when the implementation, verification, documentation, and workflow closure requirements are all complete. + +## Completion Criteria + +- All in-scope acceptance criteria are satisfied or explicitly marked blocked with documented reason. +- Required tests, builds, and other verification commands pass according to the repository testing policy. +- Required evidence and verification artifacts are recorded. +- Product and technical documentation impact is resolved according to the repository documentation policy. +- Relevant CodeMap updates are completed when the changed code affects entrypoints, wiring, or maintained source structure. +- Task files, discussion references, and workflow registries are updated as needed. +- The authorized review and closure roles have completed their required checks. +- The final committed state includes all required code, documentation, and registry updates for closure. + +## Not Done Conditions + +- Any required test or build fails. +- Evidence is missing for claimed verification. +- Documentation or CodeMap impact remains unresolved. +- Acceptance criteria are incomplete, unclear, or unverified. +- Required finalization or archiving steps are missing. + +## Operational Rule + +A task must not be marked complete while any Definition of Done item remains open. diff --git a/policies/definition-of-ready.md b/policies/definition-of-ready.md new file mode 100644 index 0000000..fe0d324 --- /dev/null +++ b/policies/definition-of-ready.md @@ -0,0 +1,27 @@ +# Definition Of Ready + +A task is ready to begin only when the repository has enough information to execute safely and efficiently without inventing scope. + +## Readiness Criteria + +- Scope is clear, bounded, and appropriate for the task's declared complexity. +- The task objective is specific enough that the next responsible agent can act without guessing intent. +- Acceptance criteria are present, testable, and aligned with the stated scope. +- Complexity, track, and slice are set correctly for the work being requested. +- Required dependencies, assumptions, blockers, and open questions are either resolved or explicitly recorded. +- Required pre-sync specialists have reviewed the task definition according to the active task model. +- An approved SCR exists whenever the workflow requires one. +- The relevant repository areas are identified well enough to begin safe investigation, design, or implementation. + +## Not Ready Conditions + +- Requirements are ambiguous or contradictory. +- Acceptance criteria are missing or too vague to verify. +- The task is larger or riskier than its current routing metadata suggests. +- Required specialist review has not happened yet. +- A required SCR is missing or not approved. +- Critical blockers or dependencies are unknown or unrecorded. + +## Operational Rule + +If the task fails the Definition of Ready, execution should pause until the missing information is resolved or explicitly recorded for follow-up. diff --git a/tasks/subtask-template.md b/tasks/subtask-template.md index 348bede..559a640 100644 --- a/tasks/subtask-template.md +++ b/tasks/subtask-template.md @@ -15,12 +15,31 @@ parent: TASK-[PARENT] ### Task * [ ] [Assigned Agent]: [Action] +### Definition Of Ready Check +- [ ] Parent task, assigned slice, and local scope are clear. +- [ ] Local acceptance criteria or expected outcome is clear. +- [ ] Dependencies, blockers, and assumptions are known or recorded. + ### Acceptance Criteria * [Criterion 1] +### Acceptance Criteria Verification Map +- [ ] AC-1 + - **Method:** `[unit test | integration test | e2e | manual check | doc review]` + - **Owner:** `[agent_name]` + - **Evidence:** `[optional path or note]` + +Use this section to record the verification method for each local acceptance criterion. Evidence links are optional and should be added only when they materially improve traceability. + ### Assigned To: [Primary Agent] ### Status: [todo / in_progress / review / done / blocked] +### Definition Of Done Check +- [ ] Assigned outcome is complete. +- [ ] Relevant verification for this subtask is complete. +- [ ] Evidence or notes are recorded in the parent task when required. +- [ ] Parent task is updated with the subtask outcome. + # Reviews ## [Reviewing Agent]: - [Comments] diff --git a/tasks/task-template.md b/tasks/task-template.md index e5b553e..8a601a4 100644 --- a/tasks/task-template.md +++ b/tasks/task-template.md @@ -27,6 +27,14 @@ reopened_count: 0 - **Assigned To:** `[product_manager | business_analyst | tech_lead | technical_architect | developer | qa_engineer | ui_ux_designer | workflow_runner]` - **Handoff From:** `[agent_name or null]` +## Definition Of Ready Check +- [ ] Scope is clear, bounded, and appropriate for the task's declared complexity. +- [ ] Acceptance criteria are present, testable, and aligned with the objective. +- [ ] Complexity, track, and slice are set correctly. +- [ ] Required dependencies, assumptions, blockers, and open questions are resolved or explicitly recorded. +- [ ] Required pre-sync specialist review is complete. +- [ ] Required SCR exists and is approved when the workflow requires it. + ## Acceptance Criteria - [ ] AC-1: [Primary behavioral or task outcome] - [ ] AC-2: [Secondary outcome, validation, or edge-case requirement] @@ -34,6 +42,22 @@ reopened_count: 0 - [ ] AC-4: Product documentation reflects the latest state of the application for this change, or this task explicitly records that no product-truth update was required. - [ ] AC-5: Technical documentation reflects any architectural or implementation-significant change, or this task explicitly records that no technical-truth update was required. +## Acceptance Criteria Verification Map +- [ ] AC-1 + - **Method:** `[unit test | integration test | e2e | manual check | doc review]` + - **Owner:** `[agent_name]` + - **Evidence:** `[optional path or note]` +- [ ] AC-2 + - **Method:** `[unit test | integration test | e2e | manual check | doc review]` + - **Owner:** `[agent_name]` + - **Evidence:** `[optional path or note]` +- [ ] AC-3 + - **Method:** `[unit test | integration test | e2e | manual check | doc review]` + - **Owner:** `[agent_name]` + - **Evidence:** `[optional path or note]` + +Use this section to record how each acceptance criterion will be verified. Evidence links are optional and should be added when they materially improve traceability. Shared evidence may cover multiple acceptance criteria. + ### Source Authority (MANDATORY) * **Spec Reference:** [Commit Hash or SCR ID from documentation update] * **Documentation:** [Link to updated SPECIFICATION.md or FEATURES_LIST.md] @@ -100,6 +124,16 @@ Use this section when a task that was thought to be done must be resumed using t * [ ] Product Manager: Acceptance Criteria and Evidence Coverage Verification * [ ] User: Final Approval +## Definition Of Done Check +- [ ] All in-scope acceptance criteria are satisfied or explicitly marked blocked with reason. +- [ ] Required tests, builds, and verification commands pass. +- [ ] Required evidence and verification artifacts are recorded. +- [ ] Documentation impact is resolved according to repository policy. +- [ ] Relevant CodeMap updates are complete when needed. +- [ ] Task files and workflow registries are updated. +- [ ] Authorized review and closure checks are complete. +- [ ] Final committed state contains all required code, documentation, and registry updates. + ### Finalization * [ ] [Assigned Agent]: CodeMap Update (Update `codemap.yml` if entrypoints/wiring changed) * [ ] [Assigned Agent]: Documentation Update (Update relevant docs in `docs/`) From 26a28af1b728c3e5dee5842d234ca0e8cfa0544c Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 21 Apr 2026 15:43:16 +0100 Subject: [PATCH 10/16] fix: avoid crash when warnings missing Guard nomadworks_validate output formatting so missing warnings/errors fields don't throw in older builds or forks. --- src/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index bbd330c..ec5484c 100644 --- a/src/index.js +++ b/src/index.js @@ -938,11 +938,16 @@ export default async function NomadWorksPlugin(input) { args: {}, async execute(args, context) { const res = await nomadworks_validate_logic(context.worktree); - if (res.ok) { - return `PASS: All source directories indexed. Hierarchy validated.\nWarnings: ${res.warnings.length}\n${res.warnings.map(w => "- " + w).join("\n")}`; - } else { - return `FAIL: Validation errors found:\n${res.errors.map(e => "- " + e).join("\n")}\nWarnings: ${res.warnings.length}\n${res.warnings.map(w => "- " + w).join("\n")}`; + + // Defensive: older plugin builds or custom forks may not return `warnings`. + const warnings = Array.isArray(res?.warnings) ? res.warnings : []; + const errors = Array.isArray(res?.errors) ? res.errors : []; + + if (res?.ok) { + return `PASS: All source directories indexed. Hierarchy validated.\nWarnings: ${warnings.length}\n${warnings.map(w => "- " + w).join("\n")}`; } + + return `FAIL: Validation errors found:\n${errors.map(e => "- " + e).join("\n")}\nWarnings: ${warnings.length}\n${warnings.map(w => "- " + w).join("\n")}`; } }), nomadworks_start_discussion: tool({ From 8982006ee38ba9a80e021a5bdf52dc8261ab27a7 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 21 Apr 2026 15:46:38 +0100 Subject: [PATCH 11/16] feat: dispose instance after init Call the OpenCode /instance/dispose API after nomadworks_init succeeds so newly generated repo config and agents can be reloaded without a manual restart. --- docs/guides/TOOLS.md | 1 + src/index.js | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index e035540..dc01c9a 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -31,6 +31,7 @@ Initializes NomadWorks in the current repository. - Generated prompt dumps go to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. - Generated reference policy files go to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. - The scaffolded README files in `.nomadworks/agents/` and `.nomadworks/agent-additions/` list common `plugin:` and `policy:` includes that custom agents can reuse. +- After a successful init, NomadWorks will request the OpenCode instance be disposed so the new config/agents can be reloaded. ## `nomadworks_validate` diff --git a/src/index.js b/src/index.js index ec5484c..b58f3c8 100644 --- a/src/index.js +++ b/src/index.js @@ -930,7 +930,24 @@ export default async function NomadWorksPlugin(input) { fs.writeFileSync(scrsDonePath, "# Implemented Spec Change Requests\n\n| Date | SCR ID | Title | Related Feature | Task ID |\n| :--- | :--- | :--- | :--- | :--- |\n", "utf8"); } - return `NomadWorks initialized in '${requestedTeamMode}' team mode: .nomadworks/nomadworks.yaml, repo policy/agent folders, registries, and codemap.yml created.`; + const initSummary = `NomadWorks initialized in '${requestedTeamMode}' team mode: .nomadworks/nomadworks.yaml, repo policy/agent folders, registries, and codemap.yml created.`; + + // Ensure OpenCode reloads config/agents after scaffolding changes. + // Not all environments expose this API, so treat it as best-effort. + const client = input.client; + if (client?.instance?.dispose) { + try { + const disposeRes = await client.instance.dispose({ query: { directory: context.worktree } }); + if (disposeRes?.data === true) { + return `${initSummary}\n\nOpenCode instance disposed so the new config can be loaded.`; + } + return `${initSummary}\n\nWarning: instance.dispose did not report success. You may need to restart OpenCode to load the new config.`; + } catch (e) { + return `${initSummary}\n\nWarning: Failed to dispose OpenCode instance (${e?.message || "unknown error"}). You may need to restart OpenCode to load the new config.`; + } + } + + return `${initSummary}\n\nNote: OpenCode instance dispose API unavailable in this environment. Restart OpenCode to load the new config.`; } }), nomadworks_validate: tool({ From eeda685191516e6ed02e646a791d28ff3213a7dd Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 21 Apr 2026 20:29:13 +0100 Subject: [PATCH 12/16] feat: keep built-in agents enabled Add features.keep_builtin_agents to prevent disabling OpenCode built-in agents when NomadWorks is enabled. --- docs/setup/CONFIGURATION.md | 4 ++++ src/index.js | 5 +++++ templates/nomadworks.yaml.template | 1 + 3 files changed, 10 insertions(+) diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index c9f78c8..5e0bfd4 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -111,3 +111,7 @@ Create `.nomadworks/agents/.md` to: - Repository-local policy overrides can live in `.nomadworks/policies/`. - Generated reference policy files are written to `.nomadworks/generated/policies/` when `policies.extract_defaults` is set to `all`. - Final agent prompts are dumped to `.nomadworks/generated/agents/` when `features.debug_dumps` is enabled. + +## Feature flags + +- `features.keep_builtin_agents`: when `true`, NomadWorks will not disable OpenCode built-in agents (`build`, `plan`, `general`, `explore`). NomadWorks will still set `product_manager` as the default agent. diff --git a/src/index.js b/src/index.js index b58f3c8..a12f4d0 100644 --- a/src/index.js +++ b/src/index.js @@ -1402,6 +1402,11 @@ ${YAML.stringify(dumpConfig).trim()} const builtInAgents = ["build", "plan", "general", "explore"]; const allToDisable = new Set([...builtInAgents, ...Object.keys(cfg.agent)]); + + // Some users want to keep OpenCode built-in agents available alongside NomadWorks. + if (repoCfg.features?.keep_builtin_agents === true) { + for (const id of builtInAgents) allToDisable.delete(id); + } for (const id of allToDisable) { if (!ourAgents[id]) { diff --git a/templates/nomadworks.yaml.template b/templates/nomadworks.yaml.template index e4f27d1..df4d02a 100644 --- a/templates/nomadworks.yaml.template +++ b/templates/nomadworks.yaml.template @@ -11,6 +11,7 @@ defaults: features: debug_dumps: true # Dumps final agent configs to .nomadworks/generated/agents/ for verification # debug_logs: false # Enable detailed console logging for the plugin + # keep_builtin_agents: false # If true, do not disable OpenCode built-in agents (build/plan/general/explore) codemap_verification: true policies: From 22990d4a1431f9410fc13d4b82c421897caa1629 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Thu, 23 Apr 2026 16:20:56 +0100 Subject: [PATCH 13/16] feat: make workflow runner an orchestrator Clarify workflow_runner behavior to delegate implementation/verification to specialists by default and report hard blockers via a final 'HARD BLOCKER:' summary relayed back to PMA. --- agents/workflow_runner.md | 43 ++++++++++++++++++++++++++------------- docs/guides/TOOLS.md | 2 ++ src/index.js | 2 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/agents/workflow_runner.md b/agents/workflow_runner.md index 4445475..0e8e01c 100644 --- a/agents/workflow_runner.md +++ b/agents/workflow_runner.md @@ -1,30 +1,45 @@ --- -description: Delegated workflow executor for PMA-started task lifecycles, including implementation, verification, and delegated finalization. +description: Delegated workflow orchestrator for PMA-started task lifecycles. Delegates implementation and verification work to specialists and drives the task to delivery or a hard blocker. mode: subagent tools: nomadworks_validate: true --- -You are the NomadWorks Workflow Runner. Your sole responsibility is to execute the delegated lifecycle of a specific task assigned to you by the Product Manager. You never self-initiate work; you only execute within a PMA-started task lifecycle. +You are the NomadWorks Workflow Runner. Your sole responsibility is to run the delegated lifecycle of a specific task assigned to you by the Product Manager. + +You do not self-initiate work. You operate only within a PMA-started task lifecycle. + +Your default stance is orchestration: you delegate implementation and verification work to the appropriate specialists, integrate results, and drive the task to either delivery (with required evidence) or a clearly documented hard blocker that is returned to PMA. **Your Mandates:** -1. **Delegated Lifecycle Execution:** You are responsible for executing the delegated lifecycle defined by the task file. For `implementation` tasks this is Pre-Task Sync -> Implementation -> Post-Task Sync -> delegated finalization. For `investigation` and `spec` tasks, complete the requested research or documentation cycle and return the required artifacts to the Product Manager. +1. **Delegated Lifecycle Orchestration:** You are responsible for executing the delegated lifecycle defined by the task file. + - For `implementation` tasks: Pre-Task Sync -> delegate Implementation -> delegate QA/verification -> Post-Task Sync -> delegated finalization. + - For `investigation` and `spec` tasks: delegate the required research or documentation work as needed and return the required artifacts to PMA. 2. **Workflow Adherence:** You MUST follow the NomadWorks orchestrated workflow exactly. 3. **Task File as Law:** Read the assigned task file (`tasks/todo/...`) immediately. -4. **Collective Syncing:** Use the `Task` tool to orchestrate specialists (BA, Tech Lead, UI/UX, QA) during syncs. -5. **Evidence:** Generate and verify the verification artifacts required by the repository testing/evidence policy. -6. **Delegated Finalization Authority:** For `implementation` tasks in the full-team workflow-runner path, you are the delegated finalization executor. Once 100% approved in Post-Task Sync: - * Update the SCR status to `Implemented` in the SCR file and `docs/scrs/current.md`. - * Update all registries (`tasks/current.md` and `tasks/done.md`). - * Move the task folder to `tasks/done/`. - * **Perform the final Git commit** including all code changes, documentation updates, and registry updates in a single atomic commit. -7. **Communication:** At the end of your session, provide a concise summary of the execution outcome for the Product Manager, who remains the final workflow-closure authority. +4. **Specialist Delegation Is The Default:** + - Implementation is owned by `developer` (and `technical_architect` when architectural decisions are required). + - Verification is owned by `qa_engineer` and `tech_lead`. + - You orchestrate and integrate; you do not implement code directly unless PMA explicitly instructs you to do so. +5. **Collective Syncing:** Use the `Task` tool to orchestrate specialists (BA, Tech Lead, UI/UX, QA, Architect, Dev) during syncs and execution. +6. **Evidence:** Ensure required evidence exists and is correctly traced to acceptance criteria before asking for Post-Task Sync. +7. **Delegated Finalization Authority:** For `implementation` tasks in the full-team workflow-runner path, you are the delegated finalization executor. Once 100% approved in Post-Task Sync: + * Update the SCR status to `Implemented` in the SCR file and `docs/scrs/current.md`. + * Update all registries (`tasks/current.md` and `tasks/done.md`). + * Move the task folder to `tasks/done/`. + * **Perform the final Git commit** including all code changes, documentation updates, and registry updates in a single atomic commit. +8. **Hard Blockers (Escalation Mechanism):** If you hit a blocker that cannot be resolved with reasonable attempts: + - Stop further execution. + - End your current run by returning a final summary that starts with `HARD BLOCKER:` and includes what is needed to proceed. + - Do not keep prompting or attempting additional work after declaring a hard blocker. + - Do not attempt to message PMA directly; the plugin will relay your final output back to the PMA session. +9. **Communication:** At the end of your session, provide a concise summary of the execution outcome for the Product Manager, who remains the final workflow-closure authority. **Operational Cycle:** 1. **Initialize:** Read the task file and the `Agents_Common.md`. 2. **Pre-Task Sync:** Orchestrate a synchronous sync-up with specialists to confirm readiness. Reuse your current `task_id` for these calls. -3. **Execution Phase:** Execute the task according to its `track` and `slice`. -4. **Self-Verification:** Run the relevant tests and `nomadworks_validate` when repository changes are involved. -5. **Evidence Collection:** Populate the expected evidence or findings artifacts for the task. +3. **Execution Phase:** Delegate work according to the task's `track` and `slice`, then integrate results. +4. **Verification:** Ensure relevant tests and `nomadworks_validate` are run when repository changes are involved. +5. **Evidence Collection:** Ensure the expected evidence or findings artifacts for the task exist and are complete. 6. **Post-Task Sync:** Orchestrate a synchronous verification session with specialists when required. 7. **Finalize:** For `implementation` tasks, complete delegated finalization and archiving. For `investigation` and `spec` tasks, return a concise final report and any produced artifacts to the PMA. 8. **Resume Awareness:** If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so the prior execution context remains available. diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index dc01c9a..495c906 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -96,6 +96,8 @@ Starts a `workflow_runner` session for a complex task. - Only available in `full` team mode. - Used for `complex` implementation tasks. - The runner executes in a separate session and reports completion back to PMA. +- The runner is expected to orchestrate the lifecycle by delegating implementation and verification work to specialists, driving the task to delivery or a hard blocker. +- When a hard blocker is reached, the runner should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the PMA session. ## `nomadflow_prompt_workflow` diff --git a/src/index.js b/src/index.js index a12f4d0..c9172de 100644 --- a/src/index.js +++ b/src/index.js @@ -1173,7 +1173,7 @@ export default async function NomadWorksPlugin(input) { ].filter(Boolean).join("\n"); const lifecycleInstruction = workflowTrack === "implementation" - ? "Please execute the full lifecycle (Sync -> Implementation -> Commit -> Archive) and provide a final summary." + ? "Please execute the full lifecycle (Sync -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). Delegate implementation/QA to specialists by default. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to PMA. Provide a final summary." : workflowTrack === "spec" ? "Please execute the full spec lifecycle for this task, update the required documentation artifacts, and provide a final summary." : "Please execute the investigation lifecycle for this task, capture findings clearly, and provide a final summary."; From d5dcca9e814ea4bf918b2d03d5c13b31d096b6f0 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Fri, 24 Apr 2026 09:37:13 +0100 Subject: [PATCH 14/16] feat: require workflow execution plans Make workflow_runner delegation deterministic by requiring an execution plan, fixed ownership matrix, and no direct implementation unless PMA explicitly authorizes it. --- agents/workflow_runner.md | 62 +++++++++++++++++++++++++++++++++++---- docs/guides/TOOLS.md | 2 ++ src/index.js | 2 +- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/agents/workflow_runner.md b/agents/workflow_runner.md index 0e8e01c..63a18b9 100644 --- a/agents/workflow_runner.md +++ b/agents/workflow_runner.md @@ -34,15 +34,65 @@ Your default stance is orchestration: you delegate implementation and verificati - Do not attempt to message PMA directly; the plugin will relay your final output back to the PMA session. 9. **Communication:** At the end of your session, provide a concise summary of the execution outcome for the Product Manager, who remains the final workflow-closure authority. +## Deterministic Agent Responsibility Matrix + +Use this ownership matrix for every Workflow Runner lifecycle. Do not improvise ownership unless the task file or PMA explicitly overrides it. + +| Phase | Owner | Required Output | +| :--- | :--- | :--- | +| Requirements and AC validation | `business_analyst` | Readiness notes, requirements gaps, AC coverage risks | +| Architecture and impact mapping | `technical_architect` | Technical approach, affected areas, interface/data impacts | +| Implementation | `developer` | Code changes, tests, implementation notes, changed-file summary | +| UI/UX review when relevant | `ui_ux_designer` | UI/UX findings or signoff | +| QA verification | `qa_engineer` | Verification evidence, test results, regression notes | +| Technical signoff | `tech_lead` | Behavioral verification, code quality signoff, bounce-back decision | +| Lifecycle orchestration and finalization | `workflow_runner` | Handoffs, evidence tracking, registry/SCR/archive updates, final report | +| Final closure | `product_manager` | Accepts or rejects runner outcome after plugin relay | + +## Implementation Boundary + +You are not the implementation agent. + +For implementation tasks, after Pre-Task Sync you MUST create or append a Workflow Execution Plan in the task file and then delegate implementation to `developer` using the Task tool. + +You MUST NOT directly edit product source code, tests, application configuration, or implementation files unless PMA explicitly authorizes that exception in the workflow instructions. + +You MAY edit workflow artifacts required to coordinate and close the task, including: + +- task files +- evidence notes +- SCR status +- task registries +- finalization/archive metadata + +If implementation is needed, assign it to `developer`. +If technical design is needed, assign it to `technical_architect`. +If verification is needed, assign it to `qa_engineer` and `tech_lead`. +If UI/UX evaluation is needed, assign it to `ui_ux_designer`. + +## Workflow Execution Plan + +Before implementation begins, write or append this plan to the task file and update statuses as each step completes: + +| Step | Assigned Agent | Purpose | Expected Output | Status | +| :--- | :--- | :--- | :--- | :--- | +| 1 | `business_analyst` | Validate requirements and acceptance criteria | Readiness notes | pending | +| 2 | `technical_architect` | Confirm technical approach and impact surface | Impact and design notes | pending | +| 3 | `developer` | Implement code and tests | Changed files and test notes | pending | +| 4 | `qa_engineer` | Verify behavior and regression coverage | Evidence and test results | pending | +| 5 | `tech_lead` | Final technical signoff | Approval or bounce-back | pending | +| 6 | `workflow_runner` | Finalize lifecycle | Registries, SCR/archive updates, commit, final report | pending | + **Operational Cycle:** 1. **Initialize:** Read the task file and the `Agents_Common.md`. 2. **Pre-Task Sync:** Orchestrate a synchronous sync-up with specialists to confirm readiness. Reuse your current `task_id` for these calls. -3. **Execution Phase:** Delegate work according to the task's `track` and `slice`, then integrate results. -4. **Verification:** Ensure relevant tests and `nomadworks_validate` are run when repository changes are involved. -5. **Evidence Collection:** Ensure the expected evidence or findings artifacts for the task exist and are complete. -6. **Post-Task Sync:** Orchestrate a synchronous verification session with specialists when required. -7. **Finalize:** For `implementation` tasks, complete delegated finalization and archiving. For `investigation` and `spec` tasks, return a concise final report and any produced artifacts to the PMA. -8. **Resume Awareness:** If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so the prior execution context remains available. +3. **Plan:** Create or update the Workflow Execution Plan in the task file before implementation starts. +4. **Execution Phase:** Delegate work according to the responsibility matrix and the task's `track` and `slice`, then integrate results. +5. **Verification:** Ensure relevant tests and `nomadworks_validate` are run when repository changes are involved. +6. **Evidence Collection:** Ensure the expected evidence or findings artifacts for the task exist and are complete. +7. **Post-Task Sync:** Orchestrate a synchronous verification session with specialists when required. +8. **Finalize:** For `implementation` tasks, complete delegated finalization and archiving. For `investigation` and `spec` tasks, return a concise final report and any produced artifacts to the PMA. +9. **Resume Awareness:** If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so the prior execution context remains available. diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index 495c906..d8a9d5e 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -97,6 +97,8 @@ Starts a `workflow_runner` session for a complex task. - Used for `complex` implementation tasks. - The runner executes in a separate session and reports completion back to PMA. - The runner is expected to orchestrate the lifecycle by delegating implementation and verification work to specialists, driving the task to delivery or a hard blocker. +- For implementation tasks, the runner must create or append a Workflow Execution Plan in the task file after Pre-Task Sync and before implementation starts. +- The runner must not directly edit product source code, tests, application configuration, or implementation files unless PMA explicitly authorizes that exception in the workflow instructions. - When a hard blocker is reached, the runner should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the PMA session. ## `nomadflow_prompt_workflow` diff --git a/src/index.js b/src/index.js index c9172de..e11d7d5 100644 --- a/src/index.js +++ b/src/index.js @@ -1173,7 +1173,7 @@ export default async function NomadWorksPlugin(input) { ].filter(Boolean).join("\n"); const lifecycleInstruction = workflowTrack === "implementation" - ? "Please execute the full lifecycle (Sync -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). Delegate implementation/QA to specialists by default. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to PMA. Provide a final summary." + ? "Please execute the full lifecycle (Sync -> Workflow Execution Plan -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). After Pre-Task Sync, create or append a Workflow Execution Plan in the task file and assign each step to the responsible specialist. Do not implement code directly unless PMA explicitly authorized that exception in these instructions. If implementation is required, delegate it to developer. If verification is required, delegate it to qa_engineer and tech_lead. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to PMA. Provide a final summary." : workflowTrack === "spec" ? "Please execute the full spec lifecycle for this task, update the required documentation artifacts, and provide a final summary." : "Please execute the investigation lifecycle for this task, capture findings clearly, and provide a final summary."; From 6c381d733b0fb5a3dc42ec8ef43644412167a368 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Sun, 26 Apr 2026 11:57:02 +0100 Subject: [PATCH 15/16] refactor: use delegated PMA workflows Replace the workflow_runner agent with delegated product_manager workflow sessions and update documentation/prompts accordingly. Also preserve already-registered OpenCode agents when keep_builtin_agents is enabled. --- Agents_Common.md | 6 +- README.md | 7 +- agents/business_analyst.md | 2 +- agents/developer.md | 2 +- agents/product_manager.md | 4 +- agents/tech_lead.md | 2 +- agents/technical_architect.md | 2 +- agents/ui_ux_designer.md | 2 +- agents/workflow_runner.md | 101 ----------------------------- docs/core/agent_orchestration.md | 6 +- docs/core/pma_mode_full.md | 6 +- docs/core/pma_mode_mini.md | 4 +- docs/core/role_contracts.md | 6 +- docs/core/task_model.md | 4 +- docs/core/tech_lead_mode_full.md | 2 +- docs/core/tech_lead_mode_mini.md | 2 +- docs/guides/AGENTS.md | 5 +- docs/guides/TEAM_MODE_FULL.md | 7 +- docs/guides/TEAM_MODE_MINI.md | 4 +- docs/guides/TOOLS.md | 20 +++--- docs/guides/WORKFLOW.md | 6 +- docs/product/DOMAIN_MAP.md | 4 +- docs/product/FEATURES_LIST.md | 2 +- docs/setup/CONFIGURATION.md | 8 +-- policies/README.md | 6 +- src/index.js | 55 ++++++++-------- tasks/task-template.md | 6 +- templates/nomadworks.yaml.template | 2 +- 28 files changed, 89 insertions(+), 194 deletions(-) delete mode 100644 agents/workflow_runner.md diff --git a/Agents_Common.md b/Agents_Common.md index d91c0de..2c6407b 100644 --- a/Agents_Common.md +++ b/Agents_Common.md @@ -38,7 +38,7 @@ Refer to `docs/core/agent_orchestration.md` for the full strategy. Key highlight * **Delegated Execution Phase:** Once an SCR is triggered for implementation, the NomadWorks Collective executes the entire cycle (Task -> Dev -> QA -> Review -> Commit) within PMA-delegated task lifecycles. * **Source of Truth:** SCR files track the *proposals*, Documentation tracks the *state*, and Tasks track the *work*. * **Verification:** 100% test pass rate and internal sign-offs are required before delegated workflow closure. -* **Complexity Routing:** Use `tiny` for low-risk, single-slice work; `standard` for bounded delivery tasks; and `complex` for multi-step work that requires decomposition and the Workflow Runner. +* **Complexity Routing:** Use `tiny` for low-risk, single-slice work; `standard` for bounded delivery tasks; and `complex` for multi-step work that requires decomposition and delegated PMA workflow orchestration. * **Limited Parallelism:** Until dedicated git worktree support lands, at most one shared-worktree implementation task may be active at a time. Investigation and spec work may proceed in parallel when they do not interfere with the active implementation task. ## 4.1 Task Model @@ -78,9 +78,9 @@ That document defines: * **Task Lifecycle:** PMA reviews -> Updates task file -> Assigns next agent. * **Discussion Tasks:** When a discussion between PMA, BA, and Tech Lead becomes workflow-relevant, it should be captured in a normal task file, assigned to the next responsible agent, and tracked under `Active Discussions` in `tasks/current.md` until it resolves into execution, SCR work, clarification, or closure. * **Task Reopening:** If a task that was thought to be complete later needs unresolved discrepancies fixed or minor same-scope changes after implementation, reuse the same task file, move it back into `Active`, and record the reason in the task's `Reopen History` rather than creating a brand new task. -* **Resume Continuity:** When resuming a reopened task, keep the same task file ID. Reuse the same Task tool `task_id` for delegated task work when possible, and for workflow-runner execution reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible, so prior context remains available. +* **Resume Continuity:** When resuming a reopened task, keep the same task file ID. Reuse the same Task tool `task_id` for delegated task work when possible, and for delegated PMA workflow execution reuse both the same Task tool `task_id` and the same workflow `session_id` when possible, so prior context remains available. * **Documentation Closure Ownership:** The Product Manager Agent is the final owner of confirming whether product and technical documentation updates were completed or explicitly marked unnecessary before task closure. -* **Git Strategy:** PMA remains the final workflow-closure authority. Tech Lead is the default commit authority for direct execution paths, and Workflow Runner may perform the delegated final commit only in explicit full-team complex workflows. +* **Git Strategy:** PMA remains the final workflow-closure authority. Tech Lead is the default commit authority for direct execution paths, and a delegated PMA workflow session may perform the delegated final commit only in explicit full-team complex workflows. * **Authority Matrix:** Follow the canonical authority and output rules in `docs/core/role_contracts.md` for ownership, verification, commit authority, and closure decisions. * **Commit Message Policy:** Every commit message must follow the repository's active commit messaging policy. * **Implementation Evidence Collection:** Every `implementation` task must produce the verification artifacts required by the repository's testing and evidence policy. diff --git a/README.md b/README.md index e880583..7730ac4 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Runtime prompt resolution prefers repository-local policies, agent definitions, NomadWorks supports two team presets: - `mini`: PMA + BA + Tech Lead for simple repositories and `tiny` / `standard` tasks -- `full`: the complete collective, including advanced specialists and `workflow_runner` +- `full`: the complete collective, including advanced specialists for architecture, development, QA, and UI/UX If `team_mode` is not set in an existing repository, NomadWorks treats it as `full` by default. @@ -79,14 +79,13 @@ For the full release setup, required secrets, and branch-based versioning behavi | Team Mode | Available Agents | Supported Task Complexity | Flow Guide | | :--- | :--- | :--- | :--- | | `mini` | `product_manager`, `business_analyst`, `tech_lead` | `tiny`, `standard` | [Mini Team Mode](docs/guides/TEAM_MODE_MINI.md) | -| `full` | Full NomadWorks Collective, including `workflow_runner`, `technical_architect`, `developer`, `qa_engineer`, and `ui_ux_designer` | `tiny`, `standard`, `complex` | [Full Team Mode](docs/guides/TEAM_MODE_FULL.md) | +| `full` | Full NomadWorks Collective, including `technical_architect`, `developer`, `qa_engineer`, and `ui_ux_designer` | `tiny`, `standard`, `complex` | [Full Team Mode](docs/guides/TEAM_MODE_FULL.md) | ## Workflow Agents The NomadWorks Collective operates like a role-based software development team: - `product_manager` (Product Manager Agent, PMA): Default orchestrator and routing agent. -- `workflow_runner` (Workflow Runner): Delegated executor for complex implementation tasks. - `business_analyst` (Business Analyst, BA): Requirements and product-truth steward. - `technical_architect` (Technical Architect): Architecture, interfaces, and impact mapping. - `tech_lead` (Tech Lead): Behavioral verification and technical sign-off. @@ -115,7 +114,7 @@ For arguments, behavior, and team-mode availability, see [Plugin Tools](docs/gui - **Track:** `implementation`, `investigation`, `spec` - **Slice:** `foundation`, `core`, `logic`, `ui`, `polish`, `qa`, `docs` -Use `complex` for work that needs an approved SCR, slice-based decomposition, and `workflow_runner`. Keep `tiny` and `standard` tasks direct and bounded. +Use `complex` for work that needs an approved SCR, slice-based decomposition, and delegated PMA workflow orchestration. Keep `tiny` and `standard` tasks direct and bounded. ## Discussion Handoffs diff --git a/agents/business_analyst.md b/agents/business_analyst.md index bc00557..b8854c2 100644 --- a/agents/business_analyst.md +++ b/agents/business_analyst.md @@ -15,7 +15,7 @@ Before starting any analysis or documentation, thoroughly review the product vis 4. **Document Stewardship:** Maintain the "Single Source of Truth." Ensure all documentation is consistent, correctly cross-linked, and accurate across the `docs/` directory. 5. **SCR Lifecycle Management:** Manage the initial lifecycle of Spec Change Requests. Move SCRs from **Proposed** to **Review** and finally to **Approved** in `docs/scrs/current.md` once the Product Owner gives explicit approval. 6. **Documentation Maintenance:** Update the `PRODUCT_OVERVIEW.md`, `FEATURES_LIST.md`, and the **SCR Registries** as needed. -7. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +7. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Analytical:** Break down complex problems into manageable components. * **Detail-Oriented:** Be meticulous in documenting specifications, ensuring accuracy and completeness. diff --git a/agents/developer.md b/agents/developer.md index 63804b3..98b5da5 100644 --- a/agents/developer.md +++ b/agents/developer.md @@ -13,7 +13,7 @@ Before starting any development, thoroughly review the requirements. **If any in 3. **Implementation:** Write the minimum amount of code necessary to implement the feature and satisfy all requirements. Adhere to idiomatic patterns and the architect's design. 4. **Refactor & Document:** Improve code design, readability, and efficiency. Proactively update relevant `docs/` files (API specs, technical notes) and the local `codemap.yml` as part of the implementation. 5. **Internal Verification:** Write and run comprehensive unit and integration tests. **Run `nomadworks_validate` to ensure your CodeMap updates are accurate and exhaustive.** Ensure all tests and validations are green before handing back to the PMA. -6. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +6. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While developing, always keep the following in mind:** * **UI/UX Adherence:** If applicable, ensure pixel-perfect implementation and adherence to design guidelines. diff --git a/agents/product_manager.md b/agents/product_manager.md index a2107fb..e135fd2 100644 --- a/agents/product_manager.md +++ b/agents/product_manager.md @@ -42,8 +42,8 @@ You are the Product Manager Agent (PMA). You are the central orchestrator for al * **Delegated Batch Execution:** When the PO triggers a batch of implementation SCRs, execute them sequentially within the shared worktree. Investigation and spec tasks may still run in parallel when they are isolated from the active implementation task. * **Post-Task Sync & Evidence:** You are the gatekeeper of implementation evidence. Ensure the Developer/QA has provided the verification artifacts required by the repository testing/evidence policy before calling the specialists for the Post-Task Sync. Instruct each specialist to **introduce themselves and their role** when providing verification feedback. * **Bounce Back Protocol:** If an implementation is rejected during the Post-Task Sync, reuse the original Task tool `task_id` when sending it back to the agent. This ensures they have the full execution history of the rejection. -* **Formal Reopen Protocol:** If a task was marked done but later needs discrepancies fixed or minor same-scope changes after implementation, move that same task back into `Active`, append a `Reopen History` entry, and continue using the same task file ID. Reuse the same Task tool `task_id` when resuming delegated task work, and when resuming Workflow Runner execution, reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible. -* **Commit Authority:** You own final closure in all modes. Tech Lead is the default commit authority for direct execution paths, while Workflow Runner may perform the final commit only when you explicitly delegated a full-team complex workflow to it. +* **Formal Reopen Protocol:** If a task was marked done but later needs discrepancies fixed or minor same-scope changes after implementation, move that same task back into `Active`, append a `Reopen History` entry, and continue using the same task file ID. Reuse the same Task tool `task_id` when resuming delegated task work, and when resuming delegated PMA workflow execution, reuse both the same Task tool `task_id` and the same workflow `session_id` when possible. +* **Commit Authority:** You own final closure in all modes. Tech Lead is the default commit authority for direct execution paths, while delegated PMA workflow sessions may perform the final commit only when you explicitly delegated a full-team complex workflow to them. **Your Essential Skills and Personality:** diff --git a/agents/tech_lead.md b/agents/tech_lead.md index 14e2d72..0f75bc6 100644 --- a/agents/tech_lead.md +++ b/agents/tech_lead.md @@ -17,7 +17,7 @@ Before taking technical action, thoroughly review the task file, acceptance crit 5. **Documentation Verification:** Ensure all technical and feature documentation has been updated to reflect the changes before any final commit. 6. **Commit Authority:** When you are the active direct-path technical owner, you are the default commit authority. Use the required commit-message format and include a brief explanatory body. 7. **Mentorship & Escalation:** Act as the first point of escalation for Developers. Provide technical guidance and resolve complex challenges before escalating further. -8. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +8. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Architectural Adherence:** Ensure development matches the established patterns and state management. * **Performance Optimization:** Identify and resolve performance bottlenecks. diff --git a/agents/technical_architect.md b/agents/technical_architect.md index b1936a1..da5d31d 100644 --- a/agents/technical_architect.md +++ b/agents/technical_architect.md @@ -15,7 +15,7 @@ Before starting any architectural design, thoroughly review the requirements. ** 3. **Establish Architectural Patterns:** Propose and document appropriate patterns (data flow, error handling, state management, security architecture). 4. **Ensure Consistency:** Review existing documentation and proposed designs to ensure strict adherence to established architecture and coding standards. **Run `nomadworks_validate` to verify that all CodeMaps follow the Hierarchical Scoping rules.** 5. **Document Decisions:** Clearly and concisely document all decisions and rationales in the relevant specification files (e.g., `docs/architecture/`). -6. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +6. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Scalability:** Design for future growth and data volume. diff --git a/agents/ui_ux_designer.md b/agents/ui_ux_designer.md index 71795d3..ba6c6c1 100644 --- a/agents/ui_ux_designer.md +++ b/agents/ui_ux_designer.md @@ -24,7 +24,7 @@ After implementation, you will thoroughly analyze visual evidence **without read * **Aesthetic Review:** Assess if the UI looks exceptionally beautiful, clean, and premium enough to be considered award-winning. * **Consistency Check:** Ensure UI elements are consistent with the overall design system across all screenshots. * **Feedback:** Provide detailed feedback categorized as 'Good', 'Needs Fix Now', or 'Future Enhancement'. -* **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +* **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **When in Sync-up Mode:** Critically evaluate the provided task definition for design clarity. Identify missing details or potential usability issues before work starts. diff --git a/agents/workflow_runner.md b/agents/workflow_runner.md deleted file mode 100644 index 63a18b9..0000000 --- a/agents/workflow_runner.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -description: Delegated workflow orchestrator for PMA-started task lifecycles. Delegates implementation and verification work to specialists and drives the task to delivery or a hard blocker. -mode: subagent -tools: - nomadworks_validate: true ---- -You are the NomadWorks Workflow Runner. Your sole responsibility is to run the delegated lifecycle of a specific task assigned to you by the Product Manager. - -You do not self-initiate work. You operate only within a PMA-started task lifecycle. - -Your default stance is orchestration: you delegate implementation and verification work to the appropriate specialists, integrate results, and drive the task to either delivery (with required evidence) or a clearly documented hard blocker that is returned to PMA. - -**Your Mandates:** -1. **Delegated Lifecycle Orchestration:** You are responsible for executing the delegated lifecycle defined by the task file. - - For `implementation` tasks: Pre-Task Sync -> delegate Implementation -> delegate QA/verification -> Post-Task Sync -> delegated finalization. - - For `investigation` and `spec` tasks: delegate the required research or documentation work as needed and return the required artifacts to PMA. -2. **Workflow Adherence:** You MUST follow the NomadWorks orchestrated workflow exactly. -3. **Task File as Law:** Read the assigned task file (`tasks/todo/...`) immediately. -4. **Specialist Delegation Is The Default:** - - Implementation is owned by `developer` (and `technical_architect` when architectural decisions are required). - - Verification is owned by `qa_engineer` and `tech_lead`. - - You orchestrate and integrate; you do not implement code directly unless PMA explicitly instructs you to do so. -5. **Collective Syncing:** Use the `Task` tool to orchestrate specialists (BA, Tech Lead, UI/UX, QA, Architect, Dev) during syncs and execution. -6. **Evidence:** Ensure required evidence exists and is correctly traced to acceptance criteria before asking for Post-Task Sync. -7. **Delegated Finalization Authority:** For `implementation` tasks in the full-team workflow-runner path, you are the delegated finalization executor. Once 100% approved in Post-Task Sync: - * Update the SCR status to `Implemented` in the SCR file and `docs/scrs/current.md`. - * Update all registries (`tasks/current.md` and `tasks/done.md`). - * Move the task folder to `tasks/done/`. - * **Perform the final Git commit** including all code changes, documentation updates, and registry updates in a single atomic commit. -8. **Hard Blockers (Escalation Mechanism):** If you hit a blocker that cannot be resolved with reasonable attempts: - - Stop further execution. - - End your current run by returning a final summary that starts with `HARD BLOCKER:` and includes what is needed to proceed. - - Do not keep prompting or attempting additional work after declaring a hard blocker. - - Do not attempt to message PMA directly; the plugin will relay your final output back to the PMA session. -9. **Communication:** At the end of your session, provide a concise summary of the execution outcome for the Product Manager, who remains the final workflow-closure authority. - -## Deterministic Agent Responsibility Matrix - -Use this ownership matrix for every Workflow Runner lifecycle. Do not improvise ownership unless the task file or PMA explicitly overrides it. - -| Phase | Owner | Required Output | -| :--- | :--- | :--- | -| Requirements and AC validation | `business_analyst` | Readiness notes, requirements gaps, AC coverage risks | -| Architecture and impact mapping | `technical_architect` | Technical approach, affected areas, interface/data impacts | -| Implementation | `developer` | Code changes, tests, implementation notes, changed-file summary | -| UI/UX review when relevant | `ui_ux_designer` | UI/UX findings or signoff | -| QA verification | `qa_engineer` | Verification evidence, test results, regression notes | -| Technical signoff | `tech_lead` | Behavioral verification, code quality signoff, bounce-back decision | -| Lifecycle orchestration and finalization | `workflow_runner` | Handoffs, evidence tracking, registry/SCR/archive updates, final report | -| Final closure | `product_manager` | Accepts or rejects runner outcome after plugin relay | - -## Implementation Boundary - -You are not the implementation agent. - -For implementation tasks, after Pre-Task Sync you MUST create or append a Workflow Execution Plan in the task file and then delegate implementation to `developer` using the Task tool. - -You MUST NOT directly edit product source code, tests, application configuration, or implementation files unless PMA explicitly authorizes that exception in the workflow instructions. - -You MAY edit workflow artifacts required to coordinate and close the task, including: - -- task files -- evidence notes -- SCR status -- task registries -- finalization/archive metadata - -If implementation is needed, assign it to `developer`. -If technical design is needed, assign it to `technical_architect`. -If verification is needed, assign it to `qa_engineer` and `tech_lead`. -If UI/UX evaluation is needed, assign it to `ui_ux_designer`. - -## Workflow Execution Plan - -Before implementation begins, write or append this plan to the task file and update statuses as each step completes: - -| Step | Assigned Agent | Purpose | Expected Output | Status | -| :--- | :--- | :--- | :--- | :--- | -| 1 | `business_analyst` | Validate requirements and acceptance criteria | Readiness notes | pending | -| 2 | `technical_architect` | Confirm technical approach and impact surface | Impact and design notes | pending | -| 3 | `developer` | Implement code and tests | Changed files and test notes | pending | -| 4 | `qa_engineer` | Verify behavior and regression coverage | Evidence and test results | pending | -| 5 | `tech_lead` | Final technical signoff | Approval or bounce-back | pending | -| 6 | `workflow_runner` | Finalize lifecycle | Registries, SCR/archive updates, commit, final report | pending | - -**Operational Cycle:** -1. **Initialize:** Read the task file and the `Agents_Common.md`. -2. **Pre-Task Sync:** Orchestrate a synchronous sync-up with specialists to confirm readiness. Reuse your current `task_id` for these calls. -3. **Plan:** Create or update the Workflow Execution Plan in the task file before implementation starts. -4. **Execution Phase:** Delegate work according to the responsibility matrix and the task's `track` and `slice`, then integrate results. -5. **Verification:** Ensure relevant tests and `nomadworks_validate` are run when repository changes are involved. -6. **Evidence Collection:** Ensure the expected evidence or findings artifacts for the task exist and are complete. -7. **Post-Task Sync:** Orchestrate a synchronous verification session with specialists when required. -8. **Finalize:** For `implementation` tasks, complete delegated finalization and archiving. For `investigation` and `spec` tasks, return a concise final report and any produced artifacts to the PMA. -9. **Resume Awareness:** If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so the prior execution context remains available. - - - - - - diff --git a/docs/core/agent_orchestration.md b/docs/core/agent_orchestration.md index e6dad57..37bd224 100644 --- a/docs/core/agent_orchestration.md +++ b/docs/core/agent_orchestration.md @@ -18,7 +18,7 @@ The **Product Manager Agent (PMA)** is the sole orchestrator. Subagents (Archite - The canonical task-routing definitions live in `docs/core/task_model.md`. - `tiny` work stays lightweight and direct. - `standard` work stays bounded and uses the normal delivery path. -- `complex` implementation work uses slice-based decomposition and `workflow_runner`. +- `complex` implementation work uses slice-based decomposition and delegated PMA workflow sessions. - PMA always facilitates pre-sync, while the required specialist quorum follows the defaults in `docs/core/task_model.md`. ### 3. Operational Flow (Two-Phase Execution) @@ -47,7 +47,7 @@ The workflow is divided into a **Negotiation Phase** (Human-involved) and a **De - If a task that was believed to be done later needs discrepancies fixed or minor same-scope changes, PMA should move that same task back into `Active` instead of creating a brand new task. - The task keeps the same task file ID and records the discrepancy in `Reopen History`. - When PMA resumes delegated task work, it should reuse the same Task tool `task_id` when possible. -- If the task previously ran through `workflow_runner`, PMA should reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible so the prior context is preserved. +- If the task previously ran through a delegated PMA workflow session, PMA should reuse both the same Task tool `task_id` and the same workflow `session_id` when possible so the prior context is preserved. - Create a new task only when the new work is truly follow-up scope rather than unfinished original scope. ### 3.1 Limited Parallelism (Shared Worktree) @@ -59,7 +59,7 @@ The workflow is divided into a **Negotiation Phase** (Human-involved) and a **De - **Clarification/Questions:** Any need for clarification or questions from an agent is directed to the PMA. The PMA then facilitates the inquiry and relays the response. - **Dependency Management:** The PMA actively tracks and manages all task dependencies. - **Review & Feedback:** The PMA assigns review and verification work to the appropriate technical specialists, with Tech Lead remaining the default technical review authority. -- **Commit Authority:** Tech Lead is the default commit authority for direct execution paths. Workflow Runner may perform the final commit only in delegated full-team complex workflows, while PMA remains the final closure authority. +- **Commit Authority:** Tech Lead is the default commit authority for direct execution paths. A delegated PMA workflow session may perform the final commit only in delegated full-team complex workflows, while the originating PMA remains the final closure authority. - **Escalation:** Any persistent blockers or disagreements are escalated directly to the PMA. - **Orchestrated Discussion Workflow:** The PMA may create a new `Task`, reuse the resulting `session_id`, gather specialist input, and synthesize the final decision. - **Documentation as the Single Source of Truth:** All agents refer to project documentation in `docs/` as the primary authority, and the PMA ensures it stays current. diff --git a/docs/core/pma_mode_full.md b/docs/core/pma_mode_full.md index 1ec72a5..f14e7b3 100644 --- a/docs/core/pma_mode_full.md +++ b/docs/core/pma_mode_full.md @@ -8,7 +8,7 @@ You are operating in **full team mode**. ## Full Team Task Paths - `tiny` and many `standard` tasks may still use direct PMA orchestration. -- `complex` implementation tasks should use `workflow_runner` when appropriate. +- `complex` implementation tasks should use delegated PMA workflow sessions when appropriate. - Use `technical_architect` for impact mapping and slice-based decomposition when the task has structural or cross-slice complexity. ## Full Team Specialist Use @@ -21,5 +21,5 @@ You are operating in **full team mode**. ## Full Team Complex Workflow -- When using `workflow_runner`, treat it as a separate execution session that owns pre-sync, execution, post-task sync, and final reporting. -- PMA remains the orchestrator of the overall program of work and reviews the runner's final output before closure. +- When using `nomadflow_run_workflow`, treat the delegated PMA as a separate execution session that owns pre-sync, execution, post-task sync, and final reporting. +- The originating PMA remains the orchestrator of the overall program of work and reviews the delegated PMA's final output before closure. diff --git a/docs/core/pma_mode_mini.md b/docs/core/pma_mode_mini.md index e1089ee..ce3be40 100644 --- a/docs/core/pma_mode_mini.md +++ b/docs/core/pma_mode_mini.md @@ -5,7 +5,7 @@ You are operating in **mini team mode**. - The supported core team is `product_manager`, `business_analyst`, and `tech_lead`. - Only `tiny` and `standard` tasks are supported in this mode. - You MUST refuse `complex` work and ask the user to switch to `full` team mode or rescope the task. -- Do NOT attempt to use `workflow_runner` in mini mode. +- Do NOT attempt to use delegated PMA workflow sessions in mini mode. - Do NOT assume `technical_architect`, `developer`, `qa_engineer`, `reviewer`, or `ui_ux_designer` are available unless the runtime explicitly provides them. ## Mini Team Task Paths @@ -29,5 +29,5 @@ You are operating in **mini team mode**. - the task is clearly `complex` - architecture design or structural decomposition is required -- the work needs Workflow Runner orchestration +- the work needs delegated PMA workflow orchestration - the work needs specialist coverage the mini team cannot provide safely diff --git a/docs/core/role_contracts.md b/docs/core/role_contracts.md index 3a68b28..78b26fc 100644 --- a/docs/core/role_contracts.md +++ b/docs/core/role_contracts.md @@ -13,19 +13,19 @@ This document defines the workflow verbs and handoff output contract used across - **Product Manager Agent (PMA):** Owns workflow closure in all modes. PMA decides whether evidence, documentation, and registry state are sufficient for final closure. - **Tech Lead:** Default commit authority for direct execution paths and mini-team work. -- **Workflow Runner:** Delegated commit authority only for full-team complex workflow-runner paths that PMA explicitly starts. +- **Delegated PMA workflow session:** Delegated commit authority only for full-team complex workflows that the originating PMA explicitly starts. - **Task Archiving:** Archive and registry updates are part of finalization and must be included in the final committed state. ## Documentation Responsibility Model - **Business Analyst:** Owns product truth and product-facing feature documentation. - **Technical Architect:** Owns architecture truth and technical design documentation. -- **Tech Lead / Developer / Workflow Runner:** May update code-adjacent documentation during execution. +- **Tech Lead / Developer / delegated PMA workflow session:** May update code-adjacent documentation during execution. - **PMA:** Verifies documentation closure and decides whether documentation impact has been fully resolved for the task. ## Specialist Output Contract -When handing work back to PMA or Workflow Runner, specialists should return these sections in a concise format: +When handing work back to PMA, specialists should return these sections in a concise format: - **Summary:** What was done or decided. - **Work Performed:** Files changed, reviewed, or key areas analyzed. diff --git a/docs/core/task_model.md b/docs/core/task_model.md index 4595603..cd152eb 100644 --- a/docs/core/task_model.md +++ b/docs/core/task_model.md @@ -6,7 +6,7 @@ NomadWorks classifies work across three orthogonal dimensions. - `tiny`: Very small, low-risk work such as copy edits, typos, trivial config fixes, or narrowly scoped non-behavioral changes. - `standard`: The default delivery path for bounded bug fixes, focused features, and moderate documentation or QA work. -- `complex`: Multi-step work that benefits from decomposition, multiple specialist handoffs, and full Workflow Runner orchestration. +- `complex`: Multi-step work that benefits from decomposition, multiple specialist handoffs, and delegated PMA workflow orchestration. ## 2. Track @@ -29,7 +29,7 @@ NomadWorks classifies work across three orthogonal dimensions. - `tiny` tasks should stay within one slice and usually one specialist handoff. - `standard` tasks should keep one primary slice even if they touch adjacent areas. - `complex` tasks should be decomposed into slice-based subtasks. -- `complex + implementation` is the default case for using `workflow_runner`. +- `complex + implementation` is the default case for using `nomadflow_run_workflow` to start a delegated PMA workflow session. - While one implementation task is active in the shared worktree, parallel work should be limited to `investigation` or `spec` tasks that avoid conflicting edits. ## Pre-Sync Specialist Defaults diff --git a/docs/core/tech_lead_mode_full.md b/docs/core/tech_lead_mode_full.md index 2f6dc75..8f616af 100644 --- a/docs/core/tech_lead_mode_full.md +++ b/docs/core/tech_lead_mode_full.md @@ -5,4 +5,4 @@ You are operating in **full team mode**. - Full team mode includes broader specialist coverage across architecture, QA, and workflow orchestration. - Focus on technical leadership, behavioral verification, and high-quality execution while using other specialists where appropriate. - Do not absorb all specialist responsibilities by default. Coordinate with Architect, Developer, QA, and UI/UX when those roles are relevant. -- For `complex` work, support PMA and Workflow Runner through technical review, behavioral verification, and escalation handling rather than acting as the sole technical path. +- For `complex` work, support PMA and delegated PMA workflow sessions through technical review, behavioral verification, and escalation handling rather than acting as the sole technical path. diff --git a/docs/core/tech_lead_mode_mini.md b/docs/core/tech_lead_mode_mini.md index aab0b49..36b963d 100644 --- a/docs/core/tech_lead_mode_mini.md +++ b/docs/core/tech_lead_mode_mini.md @@ -8,4 +8,4 @@ You are operating in **mini team mode**. - You are responsible for making technical progress without assuming that Architect, Developer, or QA are available as separate agents. - Treat product-truth updates as BA-owned, but flag PMA if technical changes require corresponding technical documentation updates. - If UI-facing work lacks dedicated UI/UX review, call out the reduced-review risk explicitly. -- If the task clearly requires deeper architecture support, Workflow Runner orchestration, or broader specialist coverage, tell PMA to switch the repository to `full` team mode or rescope the task. +- If the task clearly requires deeper architecture support, delegated PMA workflow orchestration, or broader specialist coverage, tell PMA to switch the repository to `full` team mode or rescope the task. diff --git a/docs/guides/AGENTS.md b/docs/guides/AGENTS.md index 4bebc30..eb4b06d 100644 --- a/docs/guides/AGENTS.md +++ b/docs/guides/AGENTS.md @@ -6,8 +6,7 @@ The collective is designed so each agent represents a professional function insi ## Primary orchestration agents -- `product_manager`: The default primary agent. Routes work by complexity, delegates specialists, and decides when to use the Workflow Runner. -- `workflow_runner`: Delegated executor for complex implementation tasks. Handles pre-task sync, implementation orchestration, post-task sync, and final reporting inside a PMA-started workflow. +- `product_manager`: The default primary agent. Routes work by complexity, delegates specialists, and may start delegated PMA workflow sessions for complex work. ## Specialist agents @@ -60,4 +59,4 @@ Use shared policies and additive agent files by default. Use full agent definiti - PMA links the task to an approved SCR. - Architect helps decompose the work into slice-based subtasks. -- `workflow_runner` executes the end-to-end delivery cycle. +- PMA may start a delegated PMA workflow session to execute the end-to-end delivery cycle while the originating PMA waits for completion notification. diff --git a/docs/guides/TEAM_MODE_FULL.md b/docs/guides/TEAM_MODE_FULL.md index e76dfa5..301967c 100644 --- a/docs/guides/TEAM_MODE_FULL.md +++ b/docs/guides/TEAM_MODE_FULL.md @@ -5,7 +5,6 @@ Full team mode enables the complete NomadWorks Collective. ## Available Agents - `product_manager` (PMA) -- `workflow_runner` - `business_analyst` (BA) - `technical_architect` - `tech_lead` @@ -26,10 +25,10 @@ User request -> PMA classifies task and track -> BA + Tech Lead refine or review specification -> For standard work, PMA orchestrates specialist handoffs directly - -> For complex work, PMA starts Workflow Runner in a separate session + -> For complex work, PMA starts a delegated PMA workflow session -> Architect decomposes structural work into slices when needed -> Developer / QA / UI-UX contribute by specialty - -> Workflow Runner or PMA returns evidence and completion state + -> Delegated PMA workflow or originating PMA returns evidence and completion state -> PMA checks documentation closure -> Commit and archive ``` @@ -37,7 +36,7 @@ User request ## Full Team Responsibilities - **PMA:** orchestration, routing, final closure -- **Workflow Runner:** separate-session execution for complex workflows +- **Delegated PMA workflow:** separate-session execution for complex workflows - **BA:** product truth and acceptance criteria - **Technical Architect:** architecture and decomposition - **Tech Lead:** technical leadership and behavioral verification diff --git a/docs/guides/TEAM_MODE_MINI.md b/docs/guides/TEAM_MODE_MINI.md index 066c7e6..4e78adc 100644 --- a/docs/guides/TEAM_MODE_MINI.md +++ b/docs/guides/TEAM_MODE_MINI.md @@ -16,7 +16,7 @@ Mini team mode is the lightest supported NomadWorks operating model. Not supported: - `complex` -- `workflow_runner` +- delegated PMA workflow sessions ## Mini Team Task Flow @@ -38,4 +38,4 @@ User request ## Escalation Rule -If the task clearly needs architecture decomposition, Workflow Runner orchestration, or broader specialist support, PMA should stop and ask to switch the repository to `full` team mode or rescope the work. +If the task clearly needs architecture decomposition, delegated PMA workflow orchestration, or broader specialist support, PMA should stop and ask to switch the repository to `full` team mode or rescope the work. diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index d8a9d5e..3adf2b4 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -84,33 +84,33 @@ This tool performs the full close flow synchronously: ## `nomadflow_run_workflow` -Starts a `workflow_runner` session for a complex task. +Starts a delegated `product_manager` workflow session for a complex task. ### Arguments - `task_path`: path to the task markdown file -- `instructions`: detailed instructions for the workflow runner +- `instructions`: detailed instructions for the delegated PMA workflow session ### Notes - Only available in `full` team mode. - Used for `complex` implementation tasks. -- The runner executes in a separate session and reports completion back to PMA. -- The runner is expected to orchestrate the lifecycle by delegating implementation and verification work to specialists, driving the task to delivery or a hard blocker. -- For implementation tasks, the runner must create or append a Workflow Execution Plan in the task file after Pre-Task Sync and before implementation starts. -- The runner must not directly edit product source code, tests, application configuration, or implementation files unless PMA explicitly authorizes that exception in the workflow instructions. -- When a hard blocker is reached, the runner should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the PMA session. +- The delegated PMA executes in a separate session and reports completion back to the originating PMA session. +- The delegated PMA is expected to orchestrate the lifecycle by delegating implementation and verification work to specialists, driving the task to delivery or a hard blocker. +- For implementation tasks, the delegated PMA must create or append a Workflow Execution Plan in the task file after Pre-Task Sync and before implementation starts. +- The delegated PMA must not directly edit product source code, tests, application configuration, or implementation files. +- When a hard blocker is reached, the delegated PMA should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the originating PMA session. ## `nomadflow_prompt_workflow` -Sends a follow-up prompt to an existing `workflow_runner` session. +Sends a follow-up prompt to an existing delegated PMA workflow session. ### Arguments -- `session_id`: workflow runner session ID +- `session_id`: delegated PMA workflow session ID - `text`: follow-up message for that session ### Notes - Only available in `full` team mode. -- Useful for bounce-backs, clarifications, and resumed runner work. +- Useful for bounce-backs, clarifications, and resumed delegated workflow work. diff --git a/docs/guides/WORKFLOW.md b/docs/guides/WORKFLOW.md index c6a15e2..778a650 100644 --- a/docs/guides/WORKFLOW.md +++ b/docs/guides/WORKFLOW.md @@ -6,7 +6,7 @@ NomadWorks uses three task complexity levels and three work tracks. - `tiny`: Minimal, low-risk work. - `standard`: Default bounded delivery work. -- `complex`: Multi-step work that uses decomposition and the Workflow Runner. +- `complex`: Multi-step work that uses decomposition and delegated PMA workflow orchestration. ## Track @@ -41,7 +41,7 @@ NomadWorks uses three task complexity levels and three work tracks. ## Team modes - `mini`: supports `tiny` and `standard` only, using `product_manager`, `business_analyst`, and `tech_lead` -- `full`: supports `tiny`, `standard`, and `complex`, including `workflow_runner` +- `full`: supports `tiny`, `standard`, and `complex`, including delegated PMA workflow sessions See also: @@ -85,7 +85,7 @@ Track these task files under `Active Discussions` in `tasks/current.md` until th - Move it back into `Active` in `tasks/current.md`. - Keep the same task file ID and record the reason in `Reopen History`. - Reuse the same Task tool `task_id` for delegated task work when possible. -- If the task used `workflow_runner`, reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible. +- If the task used a delegated PMA workflow session, reuse both the same Task tool `task_id` and the same workflow `session_id` when possible. ## Evidence By Track diff --git a/docs/product/DOMAIN_MAP.md b/docs/product/DOMAIN_MAP.md index 7277820..c60c340 100644 --- a/docs/product/DOMAIN_MAP.md +++ b/docs/product/DOMAIN_MAP.md @@ -12,8 +12,8 @@ This document maps the major product domains and the features that belong to the ### Agent Orchestration -- **Purpose:** Defines how PMA, Workflow Runner, and specialist agents collaborate. -- **Owned Features:** Product Manager routing, Workflow Runner handoff, specialist delegation, discussion protocols. +- **Purpose:** Defines how PMA and specialist agents collaborate. +- **Owned Features:** Product Manager routing, delegated PMA workflow sessions, specialist delegation, discussion protocols. - **Primary Docs:** `docs/guides/AGENTS.md`, `docs/core/agent_orchestration.md` ### Task Lifecycle diff --git a/docs/product/FEATURES_LIST.md b/docs/product/FEATURES_LIST.md index 2f44948..e044907 100644 --- a/docs/product/FEATURES_LIST.md +++ b/docs/product/FEATURES_LIST.md @@ -5,7 +5,7 @@ This document is the "Single Source of Truth" for all features implemented or pl ## 1. Core Features - **Plugin-Based Agent Installation:** [Status: Done] - **Product Manager Default Agent:** [Status: Done] -- **Workflow Runner Session Orchestration:** [Status: Done] +- **Delegated PMA Workflow Session Orchestration:** [Status: Done] - **CodeMap Validation:** [Status: Done] - **Complexity-Based Task Routing (`tiny`, `standard`, `complex`):** [Status: In Progress] - **Standard Slice Model (`foundation`, `core`, `logic`, `ui`, `polish`, `qa`, `docs`):** [Status: In Progress] diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index 5e0bfd4..1a434d1 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -41,12 +41,12 @@ agents: - Enabled by default: `product_manager`, `business_analyst`, `tech_lead` - Intended for: `tiny` and `standard` tasks in simple repositories -- Not supported: `complex` work and `workflow_runner` +- Not supported: `complex` delegated workflows ### `full` - Enables the full NomadWorks Collective by default -- Intended for: repositories that need the complete role set, including `workflow_runner` +- Intended for: repositories that need the complete specialist role set and delegated PMA workflows - Supports: `tiny`, `standard`, and `complex` ## Common uses @@ -78,7 +78,7 @@ Mandatory agents cannot be disabled: ```yaml agents: - workflow_runner: + developer: tools_add: - nomadworks_validate ``` @@ -114,4 +114,4 @@ Create `.nomadworks/agents/.md` to: ## Feature flags -- `features.keep_builtin_agents`: when `true`, NomadWorks will not disable OpenCode built-in agents (`build`, `plan`, `general`, `explore`). NomadWorks will still set `product_manager` as the default agent. +- `features.keep_builtin_agents`: when `true`, NomadWorks will not disable agents that OpenCode already registered, including built-in agents such as `build`, `plan`, `general`, and `explore`. NomadWorks will still set `product_manager` as the default agent. diff --git a/policies/README.md b/policies/README.md index 9adc62c..a56bdab 100644 --- a/policies/README.md +++ b/policies/README.md @@ -15,11 +15,11 @@ Files under `.nomadworks/generated/policies/` are reference copies only. They ar - `development-guidelines.md` - Repository-specific engineering rules, stack notes, and implementation conventions. - - Used by: `developer`, `technical_architect`, `tech_lead`, `workflow_runner` + - Used by: `developer`, `technical_architect`, `tech_lead`, delegated PMA workflows - `testing-guidelines.md` - Testing, evidence, regression, and verification conventions. - - Used by: `developer`, `qa_engineer`, `tech_lead`, `workflow_runner` + - Used by: `developer`, `qa_engineer`, `tech_lead`, delegated PMA workflows - `documentation-guidelines.md` - Documentation layout, naming, ownership, and update expectations. @@ -35,7 +35,7 @@ Files under `.nomadworks/generated/policies/` are reference copies only. They ar - `git-commit-messaging.md` - Commit subject and body rules. - - Used by: `tech_lead`, `workflow_runner` + - Used by: `tech_lead`, delegated PMA workflows - `product-guidelines.md` - User story, acceptance criteria, terminology, and product-truth conventions. diff --git a/src/index.js b/src/index.js index e11d7d5..2e5cb8f 100644 --- a/src/index.js +++ b/src/index.js @@ -585,9 +585,7 @@ function isAgentEffectivelyEnabled(agentId, repoCfg) { } function getOperatingTeamMode(repoCfg) { - const hasArchitect = isAgentEffectivelyEnabled("technical_architect", repoCfg); - const hasRunner = isAgentEffectivelyEnabled("workflow_runner", repoCfg); - return hasArchitect && hasRunner ? "full" : "mini"; + return repoCfg.team_mode; } function readResolvedFile(relativePath, worktree) { @@ -811,16 +809,16 @@ export default async function NomadWorksPlugin(input) { try { // Blocking prompt call in a background promise - if (debug) console.log(`[NomadFlow] Sending initial/resumed prompt to Workflow Runner session ${sessionId}...`); + if (debug) console.log(`[NomadFlow] Sending initial/resumed prompt to delegated PMA session ${sessionId}...`); const runResult = await client.session.prompt({ path: { id: sessionId }, body: { - agent: "workflow_runner", + agent: "product_manager", parts: [{ type: "text", text: initialText }] } }); - if (debug) console.log(`[NomadFlow] Workflow Runner session ${sessionId} returned control.`); + if (debug) console.log(`[NomadFlow] Delegated PMA session ${sessionId} returned control.`); // Capture final message and notify PMA const finalMessage = runResult.data.parts.map(p => p.text).join("\n"); @@ -831,7 +829,7 @@ export default async function NomadWorksPlugin(input) { body: { parts: [{ type: "text", - text: `[NomadFlow Notification] Workflow Runner has finished work for: ${identifier}.\n\nFINAL SUMMARY FROM RUNNER:\n${finalMessage}` + text: `[NomadFlow Notification] Delegated PMA workflow has finished work for: ${identifier}.\n\nFINAL SUMMARY FROM DELEGATED PMA:\n${finalMessage}` }] } }); @@ -843,7 +841,7 @@ export default async function NomadWorksPlugin(input) { await client.session.promptAsync({ path: { id: pmaSessionId }, body: { - parts: [{ type: "text", text: `[NomadFlow Error] Workflow Runner failed for ${identifier}: ${err.message}` }] + parts: [{ type: "text", text: `[NomadFlow Error] Delegated PMA workflow failed for ${identifier}: ${err.message}` }] } }); } catch (notifyErr) { @@ -1133,17 +1131,17 @@ export default async function NomadWorksPlugin(input) { } }), nomadflow_run_workflow: tool({ - description: "Start a workflow_runner session for a complex task", + description: "Start a delegated PMA workflow session for a complex task", args: { task_path: tool.schema.string().describe("Path to the task markdown file (e.g. tasks/todo/task_001.md)"), - instructions: tool.schema.string().describe("Detailed instructions for the workflow_runner") + instructions: tool.schema.string().describe("Detailed instructions for the delegated PMA workflow session") }, async execute(args, context) { const client = input.client; if (!client) return "Error: OpenCode client not available in plugin context."; - if (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full") { - return "FAIL: Workflow Runner is unavailable in the current team configuration. Switch to full team mode to run complex workflows."; + if (operatingTeamMode !== "full") { + return "FAIL: Delegated PMA workflows are unavailable in mini team mode. Switch to full team mode to run complex workflows."; } const pmaSessionId = context.sessionId || context.sessionID; @@ -1173,17 +1171,17 @@ export default async function NomadWorksPlugin(input) { ].filter(Boolean).join("\n"); const lifecycleInstruction = workflowTrack === "implementation" - ? "Please execute the full lifecycle (Sync -> Workflow Execution Plan -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). After Pre-Task Sync, create or append a Workflow Execution Plan in the task file and assign each step to the responsible specialist. Do not implement code directly unless PMA explicitly authorized that exception in these instructions. If implementation is required, delegate it to developer. If verification is required, delegate it to qa_engineer and tech_lead. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to PMA. Provide a final summary." + ? "You are a delegated PMA workflow session. Execute the full lifecycle (Sync -> Workflow Execution Plan -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). After Pre-Task Sync, create or append a Workflow Execution Plan in the task file and assign each step to the responsible specialist. Do not implement code directly. If implementation is required, delegate it to developer. If verification is required, delegate it to qa_engineer and tech_lead. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to the originating PMA session. Provide a final summary." : workflowTrack === "spec" - ? "Please execute the full spec lifecycle for this task, update the required documentation artifacts, and provide a final summary." - : "Please execute the investigation lifecycle for this task, capture findings clearly, and provide a final summary."; + ? "You are a delegated PMA workflow session. Execute the full spec lifecycle for this task, delegate specialist work as needed, update the required documentation artifacts, and provide a final summary." + : "You are a delegated PMA workflow session. Execute the investigation lifecycle for this task, delegate specialist work as needed, capture findings clearly, and provide a final summary."; const initialText = `Task File: ${args.task_path}\n${metadataSummary ? `\n${metadataSummary}` : ""}\n\nInstructions: ${args.instructions}\n\n${lifecycleInstruction}`; // Start monitoring in background (async) startAndMonitorWorkflow(sessionId, pmaSessionId, initialText, args.task_path); - return `SUCCESS: Workflow Runner session started. ID: ${sessionId}\nTrack: ${workflowTrack}\nInstructions sent for ${args.task_path}. You will be notified on completion in this session (${pmaSessionId}).`; + return `SUCCESS: Delegated PMA workflow session started. ID: ${sessionId}\nTrack: ${workflowTrack}\nInstructions sent for ${args.task_path}. You will be notified on completion in this session (${pmaSessionId}).`; } catch (e) { console.error("[NomadFlow] Failed to start workflow session:", e); return `FAIL: Failed to initiate session: ${e.message}`; @@ -1191,17 +1189,17 @@ export default async function NomadWorksPlugin(input) { } }), nomadflow_prompt_workflow: tool({ - description: "Send a message or follow-up prompt to an existing workflow_runner session", + description: "Send a message or follow-up prompt to an existing delegated PMA workflow session", args: { session_id: tool.schema.string().describe("The ID of the session started by nomadflow_run_workflow"), - text: tool.schema.string().describe("The message or instruction to send to the workflow_runner") + text: tool.schema.string().describe("The message or instruction to send to the delegated PMA workflow session") }, async execute(args, context) { const client = input.client; if (!client) return "Error: OpenCode client not available."; - if (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full") { - return "FAIL: Workflow Runner is unavailable in the current team configuration. Switch to full team mode to send workflow runner prompts."; + if (operatingTeamMode !== "full") { + return "FAIL: Delegated PMA workflows are unavailable in mini team mode. Switch to full team mode to send workflow prompts."; } const pmaSessionId = context.sessionId || context.sessionID; @@ -1219,7 +1217,7 @@ export default async function NomadWorksPlugin(input) { return `SUCCESS: Session '${args.session_id}' was not tracked. Sent prompt and resumed monitoring. You will be notified on completion in this session (${pmaSessionId}).`; } - // 2. If already tracking (runner is active), send asynchronously so PMA isn't blocked + // 2. If already tracking (delegated PMA is active), send asynchronously so PMA isn't blocked await client.session.promptAsync({ path: { id: args.session_id }, body: { parts: [{ type: "text", text: args.text }] } @@ -1255,7 +1253,7 @@ export default async function NomadWorksPlugin(input) { body: { parts: [{ type: "text", - text: `[NomadFlow Error Notification] Workflow Runner session ${sessionID} has ${event.type.split('.')[1]}. Please check the runner session logs.` + text: `[NomadFlow Error Notification] Delegated PMA workflow session ${sessionID} has ${event.type.split('.')[1]}. Please check the workflow session logs.` }] } }); @@ -1378,7 +1376,7 @@ export default async function NomadWorksPlugin(input) { } } - if (id === "product_manager" && (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full")) { + if (id === "product_manager" && operatingTeamMode !== "full") { if (agentConfig.tools) { delete agentConfig.tools.nomadflow_run_workflow; delete agentConfig.tools.nomadflow_prompt_workflow; @@ -1401,12 +1399,13 @@ ${YAML.stringify(dumpConfig).trim()} } const builtInAgents = ["build", "plan", "general", "explore"]; - const allToDisable = new Set([...builtInAgents, ...Object.keys(cfg.agent)]); + const preserveExistingAgents = repoCfg.features?.keep_builtin_agents === true; + const allToDisable = preserveExistingAgents + ? new Set() + : new Set([...builtInAgents, ...Object.keys(cfg.agent)]); - // Some users want to keep OpenCode built-in agents available alongside NomadWorks. - if (repoCfg.features?.keep_builtin_agents === true) { - for (const id of builtInAgents) allToDisable.delete(id); - } + // Some users want to keep OpenCode's existing agents available alongside NomadWorks. + // In that mode, avoid disabling anything that OpenCode already registered. for (const id of allToDisable) { if (!ourAgents[id]) { diff --git a/tasks/task-template.md b/tasks/task-template.md index 8a601a4..bdde578 100644 --- a/tasks/task-template.md +++ b/tasks/task-template.md @@ -24,7 +24,7 @@ reopened_count: 0 [Short description of the intended outcome and scope.] ## Ownership -- **Assigned To:** `[product_manager | business_analyst | tech_lead | technical_architect | developer | qa_engineer | ui_ux_designer | workflow_runner]` +- **Assigned To:** `[product_manager | business_analyst | tech_lead | technical_architect | developer | qa_engineer | ui_ux_designer]` - **Handoff From:** `[agent_name or null]` ## Definition Of Ready Check @@ -87,7 +87,7 @@ Use this section when a task that was thought to be done must be resumed using t - **Reason:** [What discrepancy, incomplete work, or minor same-scope change was found] - **Resume Path:** [How the task returns to Active and which agent owns the next step] - **Task Tool Resume:** [Reuse the same Task tool `task_id` if applicable, otherwise write `Not applicable`] -- **Workflow Session Resume:** [Reuse the same Workflow Runner `session_id` if applicable, otherwise write `Not applicable`] +- **Workflow Session Resume:** [Reuse the same delegated PMA workflow `session_id` if applicable, otherwise write `Not applicable`] ### Pre Sync * **PMA Facilitator:** The Product Manager always runs the sync and records the decision. @@ -148,7 +148,7 @@ Use this section when a task that was thought to be done must be resumed using t - If a completed task needs discrepancies fixed or minor same-scope changes after implementation, move the same task back into `Active` rather than creating a new task for the same unfinished scope. - Keep the same task file ID. - Reuse the same Task tool `task_id` when resuming delegated task work, when possible. -- Reuse the same Workflow Runner `session_id` when resuming a Workflow Runner task, when possible. +- Reuse the same delegated PMA workflow `session_id` when resuming a delegated workflow task, when possible. # Reviews ## Technical Architect: diff --git a/templates/nomadworks.yaml.template b/templates/nomadworks.yaml.template index df4d02a..c2f6a27 100644 --- a/templates/nomadworks.yaml.template +++ b/templates/nomadworks.yaml.template @@ -11,7 +11,7 @@ defaults: features: debug_dumps: true # Dumps final agent configs to .nomadworks/generated/agents/ for verification # debug_logs: false # Enable detailed console logging for the plugin - # keep_builtin_agents: false # If true, do not disable OpenCode built-in agents (build/plan/general/explore) + # keep_builtin_agents: false # If true, do not disable agents OpenCode already registered, including built-ins codemap_verification: true policies: From 9ee64bd0a38fad9f99056df53a846d21b995d059 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Mon, 27 Apr 2026 10:11:50 +0100 Subject: [PATCH 16/16] fix: restore workflow runner orchestration Bring back workflow_runner as the separate complex workflow agent, tighten its task-management and no-direct-implementation rules, and switch workflow tooling back from delegated PMA sessions. --- Agents_Common.md | 6 +-- README.md | 7 +-- agents/business_analyst.md | 2 +- agents/developer.md | 2 +- agents/product_manager.md | 4 +- agents/tech_lead.md | 2 +- agents/technical_architect.md | 2 +- agents/ui_ux_designer.md | 2 +- agents/workflow_runner.md | 93 ++++++++++++++++++++++++++++++++ docs/core/agent_orchestration.md | 6 +-- docs/core/pma_mode_full.md | 6 +-- docs/core/pma_mode_mini.md | 4 +- docs/core/role_contracts.md | 6 +-- docs/core/task_model.md | 4 +- docs/core/tech_lead_mode_full.md | 2 +- docs/core/tech_lead_mode_mini.md | 2 +- docs/guides/AGENTS.md | 5 +- docs/guides/TEAM_MODE_FULL.md | 7 +-- docs/guides/TEAM_MODE_MINI.md | 4 +- docs/guides/TOOLS.md | 20 +++---- docs/guides/WORKFLOW.md | 6 +-- docs/product/DOMAIN_MAP.md | 4 +- docs/product/FEATURES_LIST.md | 2 +- docs/setup/CONFIGURATION.md | 6 +-- policies/README.md | 6 +-- src/index.js | 40 +++++++------- tasks/task-template.md | 6 +-- 27 files changed, 176 insertions(+), 80 deletions(-) create mode 100644 agents/workflow_runner.md diff --git a/Agents_Common.md b/Agents_Common.md index 2c6407b..5a0657d 100644 --- a/Agents_Common.md +++ b/Agents_Common.md @@ -38,7 +38,7 @@ Refer to `docs/core/agent_orchestration.md` for the full strategy. Key highlight * **Delegated Execution Phase:** Once an SCR is triggered for implementation, the NomadWorks Collective executes the entire cycle (Task -> Dev -> QA -> Review -> Commit) within PMA-delegated task lifecycles. * **Source of Truth:** SCR files track the *proposals*, Documentation tracks the *state*, and Tasks track the *work*. * **Verification:** 100% test pass rate and internal sign-offs are required before delegated workflow closure. -* **Complexity Routing:** Use `tiny` for low-risk, single-slice work; `standard` for bounded delivery tasks; and `complex` for multi-step work that requires decomposition and delegated PMA workflow orchestration. +* **Complexity Routing:** Use `tiny` for low-risk, single-slice work; `standard` for bounded delivery tasks; and `complex` for multi-step work that requires decomposition and the Workflow Runner. * **Limited Parallelism:** Until dedicated git worktree support lands, at most one shared-worktree implementation task may be active at a time. Investigation and spec work may proceed in parallel when they do not interfere with the active implementation task. ## 4.1 Task Model @@ -78,9 +78,9 @@ That document defines: * **Task Lifecycle:** PMA reviews -> Updates task file -> Assigns next agent. * **Discussion Tasks:** When a discussion between PMA, BA, and Tech Lead becomes workflow-relevant, it should be captured in a normal task file, assigned to the next responsible agent, and tracked under `Active Discussions` in `tasks/current.md` until it resolves into execution, SCR work, clarification, or closure. * **Task Reopening:** If a task that was thought to be complete later needs unresolved discrepancies fixed or minor same-scope changes after implementation, reuse the same task file, move it back into `Active`, and record the reason in the task's `Reopen History` rather than creating a brand new task. -* **Resume Continuity:** When resuming a reopened task, keep the same task file ID. Reuse the same Task tool `task_id` for delegated task work when possible, and for delegated PMA workflow execution reuse both the same Task tool `task_id` and the same workflow `session_id` when possible, so prior context remains available. +* **Resume Continuity:** When resuming a reopened task, keep the same task file ID. Reuse the same Task tool `task_id` for delegated task work when possible, and for Workflow Runner execution reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible, so prior context remains available. * **Documentation Closure Ownership:** The Product Manager Agent is the final owner of confirming whether product and technical documentation updates were completed or explicitly marked unnecessary before task closure. -* **Git Strategy:** PMA remains the final workflow-closure authority. Tech Lead is the default commit authority for direct execution paths, and a delegated PMA workflow session may perform the delegated final commit only in explicit full-team complex workflows. +* **Git Strategy:** PMA remains the final workflow-closure authority. Tech Lead is the default commit authority for direct execution paths, and Workflow Runner may perform the delegated final commit only in explicit full-team complex workflows. * **Authority Matrix:** Follow the canonical authority and output rules in `docs/core/role_contracts.md` for ownership, verification, commit authority, and closure decisions. * **Commit Message Policy:** Every commit message must follow the repository's active commit messaging policy. * **Implementation Evidence Collection:** Every `implementation` task must produce the verification artifacts required by the repository's testing and evidence policy. diff --git a/README.md b/README.md index 7730ac4..671084b 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Runtime prompt resolution prefers repository-local policies, agent definitions, NomadWorks supports two team presets: - `mini`: PMA + BA + Tech Lead for simple repositories and `tiny` / `standard` tasks -- `full`: the complete collective, including advanced specialists for architecture, development, QA, and UI/UX +- `full`: the complete collective, including advanced specialists and `workflow_runner` If `team_mode` is not set in an existing repository, NomadWorks treats it as `full` by default. @@ -79,13 +79,14 @@ For the full release setup, required secrets, and branch-based versioning behavi | Team Mode | Available Agents | Supported Task Complexity | Flow Guide | | :--- | :--- | :--- | :--- | | `mini` | `product_manager`, `business_analyst`, `tech_lead` | `tiny`, `standard` | [Mini Team Mode](docs/guides/TEAM_MODE_MINI.md) | -| `full` | Full NomadWorks Collective, including `technical_architect`, `developer`, `qa_engineer`, and `ui_ux_designer` | `tiny`, `standard`, `complex` | [Full Team Mode](docs/guides/TEAM_MODE_FULL.md) | +| `full` | Full NomadWorks Collective, including `workflow_runner`, `technical_architect`, `developer`, `qa_engineer`, and `ui_ux_designer` | `tiny`, `standard`, `complex` | [Full Team Mode](docs/guides/TEAM_MODE_FULL.md) | ## Workflow Agents The NomadWorks Collective operates like a role-based software development team: - `product_manager` (Product Manager Agent, PMA): Default orchestrator and routing agent. +- `workflow_runner` (Workflow Runner): Delegated orchestrator for complex implementation tasks. - `business_analyst` (Business Analyst, BA): Requirements and product-truth steward. - `technical_architect` (Technical Architect): Architecture, interfaces, and impact mapping. - `tech_lead` (Tech Lead): Behavioral verification and technical sign-off. @@ -114,7 +115,7 @@ For arguments, behavior, and team-mode availability, see [Plugin Tools](docs/gui - **Track:** `implementation`, `investigation`, `spec` - **Slice:** `foundation`, `core`, `logic`, `ui`, `polish`, `qa`, `docs` -Use `complex` for work that needs an approved SCR, slice-based decomposition, and delegated PMA workflow orchestration. Keep `tiny` and `standard` tasks direct and bounded. +Use `complex` for work that needs an approved SCR, slice-based decomposition, and `workflow_runner`. Keep `tiny` and `standard` tasks direct and bounded. ## Discussion Handoffs diff --git a/agents/business_analyst.md b/agents/business_analyst.md index b8854c2..bc00557 100644 --- a/agents/business_analyst.md +++ b/agents/business_analyst.md @@ -15,7 +15,7 @@ Before starting any analysis or documentation, thoroughly review the product vis 4. **Document Stewardship:** Maintain the "Single Source of Truth." Ensure all documentation is consistent, correctly cross-linked, and accurate across the `docs/` directory. 5. **SCR Lifecycle Management:** Manage the initial lifecycle of Spec Change Requests. Move SCRs from **Proposed** to **Review** and finally to **Approved** in `docs/scrs/current.md` once the Product Owner gives explicit approval. 6. **Documentation Maintenance:** Update the `PRODUCT_OVERVIEW.md`, `FEATURES_LIST.md`, and the **SCR Registries** as needed. -7. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +7. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Analytical:** Break down complex problems into manageable components. * **Detail-Oriented:** Be meticulous in documenting specifications, ensuring accuracy and completeness. diff --git a/agents/developer.md b/agents/developer.md index 98b5da5..63804b3 100644 --- a/agents/developer.md +++ b/agents/developer.md @@ -13,7 +13,7 @@ Before starting any development, thoroughly review the requirements. **If any in 3. **Implementation:** Write the minimum amount of code necessary to implement the feature and satisfy all requirements. Adhere to idiomatic patterns and the architect's design. 4. **Refactor & Document:** Improve code design, readability, and efficiency. Proactively update relevant `docs/` files (API specs, technical notes) and the local `codemap.yml` as part of the implementation. 5. **Internal Verification:** Write and run comprehensive unit and integration tests. **Run `nomadworks_validate` to ensure your CodeMap updates are accurate and exhaustive.** Ensure all tests and validations are green before handing back to the PMA. -6. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +6. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While developing, always keep the following in mind:** * **UI/UX Adherence:** If applicable, ensure pixel-perfect implementation and adherence to design guidelines. diff --git a/agents/product_manager.md b/agents/product_manager.md index e135fd2..a2107fb 100644 --- a/agents/product_manager.md +++ b/agents/product_manager.md @@ -42,8 +42,8 @@ You are the Product Manager Agent (PMA). You are the central orchestrator for al * **Delegated Batch Execution:** When the PO triggers a batch of implementation SCRs, execute them sequentially within the shared worktree. Investigation and spec tasks may still run in parallel when they are isolated from the active implementation task. * **Post-Task Sync & Evidence:** You are the gatekeeper of implementation evidence. Ensure the Developer/QA has provided the verification artifacts required by the repository testing/evidence policy before calling the specialists for the Post-Task Sync. Instruct each specialist to **introduce themselves and their role** when providing verification feedback. * **Bounce Back Protocol:** If an implementation is rejected during the Post-Task Sync, reuse the original Task tool `task_id` when sending it back to the agent. This ensures they have the full execution history of the rejection. -* **Formal Reopen Protocol:** If a task was marked done but later needs discrepancies fixed or minor same-scope changes after implementation, move that same task back into `Active`, append a `Reopen History` entry, and continue using the same task file ID. Reuse the same Task tool `task_id` when resuming delegated task work, and when resuming delegated PMA workflow execution, reuse both the same Task tool `task_id` and the same workflow `session_id` when possible. -* **Commit Authority:** You own final closure in all modes. Tech Lead is the default commit authority for direct execution paths, while delegated PMA workflow sessions may perform the final commit only when you explicitly delegated a full-team complex workflow to them. +* **Formal Reopen Protocol:** If a task was marked done but later needs discrepancies fixed or minor same-scope changes after implementation, move that same task back into `Active`, append a `Reopen History` entry, and continue using the same task file ID. Reuse the same Task tool `task_id` when resuming delegated task work, and when resuming Workflow Runner execution, reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible. +* **Commit Authority:** You own final closure in all modes. Tech Lead is the default commit authority for direct execution paths, while Workflow Runner may perform the final commit only when you explicitly delegated a full-team complex workflow to it. **Your Essential Skills and Personality:** diff --git a/agents/tech_lead.md b/agents/tech_lead.md index 0f75bc6..14e2d72 100644 --- a/agents/tech_lead.md +++ b/agents/tech_lead.md @@ -17,7 +17,7 @@ Before taking technical action, thoroughly review the task file, acceptance crit 5. **Documentation Verification:** Ensure all technical and feature documentation has been updated to reflect the changes before any final commit. 6. **Commit Authority:** When you are the active direct-path technical owner, you are the default commit authority. Use the required commit-message format and include a brief explanatory body. 7. **Mentorship & Escalation:** Act as the first point of escalation for Developers. Provide technical guidance and resolve complex challenges before escalating further. -8. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +8. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Architectural Adherence:** Ensure development matches the established patterns and state management. * **Performance Optimization:** Identify and resolve performance bottlenecks. diff --git a/agents/technical_architect.md b/agents/technical_architect.md index da5d31d..b1936a1 100644 --- a/agents/technical_architect.md +++ b/agents/technical_architect.md @@ -15,7 +15,7 @@ Before starting any architectural design, thoroughly review the requirements. ** 3. **Establish Architectural Patterns:** Propose and document appropriate patterns (data flow, error handling, state management, security architecture). 4. **Ensure Consistency:** Review existing documentation and proposed designs to ensure strict adherence to established architecture and coding standards. **Run `nomadworks_validate` to verify that all CodeMaps follow the Hierarchical Scoping rules.** 5. **Document Decisions:** Clearly and concisely document all decisions and rationales in the relevant specification files (e.g., `docs/architecture/`). -6. **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +6. **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **While working, always keep the following in mind:** * **Scalability:** Design for future growth and data volume. diff --git a/agents/ui_ux_designer.md b/agents/ui_ux_designer.md index ba6c6c1..71795d3 100644 --- a/agents/ui_ux_designer.md +++ b/agents/ui_ux_designer.md @@ -24,7 +24,7 @@ After implementation, you will thoroughly analyze visual evidence **without read * **Aesthetic Review:** Assess if the UI looks exceptionally beautiful, clean, and premium enough to be considered award-winning. * **Consistency Check:** Ensure UI elements are consistent with the overall design system across all screenshots. * **Feedback:** Provide detailed feedback categorized as 'Good', 'Needs Fix Now', or 'Future Enhancement'. -* **Required Output:** When handing work back to PMA, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. +* **Required Output:** When handing work back to PMA or Workflow Runner, return the shared output contract: Summary, Work Performed, Acceptance Criteria Coverage, Documentation Impact, Open Risks, and Recommended Next Step. **When in Sync-up Mode:** Critically evaluate the provided task definition for design clarity. Identify missing details or potential usability issues before work starts. diff --git a/agents/workflow_runner.md b/agents/workflow_runner.md new file mode 100644 index 0000000..8872c02 --- /dev/null +++ b/agents/workflow_runner.md @@ -0,0 +1,93 @@ +--- +description: Delegated workflow orchestrator for PMA-started complex task lifecycles. Owns task-management execution, specialist handoffs, evidence tracking, finalization, and blocker reporting; does not implement product code directly. +mode: subagent +tools: + nomadworks_validate: true +--- +You are the NomadWorks Workflow Runner. You execute one PMA-started workflow lifecycle for one task file. + +You are not the Product Manager and you are not the implementation agent. PMA owns product/workflow closure and provides the task. You own disciplined task-management execution inside the delegated run. + +## Primary Boundary + +- You MUST NOT directly edit product source code, tests, application configuration, or implementation files. +- You MUST delegate implementation to `developer`. +- You MUST delegate verification to `qa_engineer` and `tech_lead`. +- You MAY edit workflow artifacts required to coordinate and close the task: task files, evidence notes, SCR status, task registries, archive/finalization metadata, and commit metadata. + +## Required PMA Inputs + +Before starting execution, verify the task file and PMA instructions include enough task-management context: + +- task path +- objective +- complexity, track, and slice +- assigned owner/current lifecycle phase +- acceptance criteria with AC IDs +- SCR link when required by the task model +- known constraints, dependencies, assumptions, and open questions +- expected evidence requirements +- documentation impact expectations +- commit/finalization expectations + +If required context is missing, stop immediately and return a final response beginning with `HARD BLOCKER:`. List the missing inputs and do not proceed to implementation or specialist delegation. + +## Deterministic Responsibility Matrix + +Use this ownership matrix for every delegated workflow. Do not improvise ownership unless the task file or PMA explicitly overrides it. + +| Phase | Owner | Required Output | +| :--- | :--- | :--- | +| Requirements and AC validation | `business_analyst` | Readiness notes, requirements gaps, AC coverage risks | +| Architecture and impact mapping | `technical_architect` | Technical approach, affected areas, interface/data impacts | +| Implementation | `developer` | Code changes, tests, implementation notes, changed-file summary | +| UI/UX review when relevant | `ui_ux_designer` | UI/UX findings or signoff | +| QA verification | `qa_engineer` | Verification evidence, test results, regression notes | +| Technical signoff | `tech_lead` | Behavioral verification, code quality signoff, bounce-back decision | +| Lifecycle orchestration and finalization | `workflow_runner` | Handoffs, evidence tracking, registry/SCR/archive updates, final report | +| Final closure | `product_manager` | Accepts or rejects runner outcome after plugin relay | + +## Workflow Execution Plan + +After the Task Readiness Check and Pre-Task Sync, write or append this plan to the task file before implementation begins. Update statuses as each step completes. + +| Step | Assigned Agent | Purpose | Expected Output | Status | +| :--- | :--- | :--- | :--- | :--- | +| 1 | `business_analyst` | Validate requirements and acceptance criteria | Readiness notes | pending | +| 2 | `technical_architect` | Confirm technical approach and impact surface | Impact and design notes | pending | +| 3 | `developer` | Implement code and tests | Changed files and test notes | pending | +| 4 | `qa_engineer` | Verify behavior and regression coverage | Evidence and test results | pending | +| 5 | `tech_lead` | Final technical signoff | Approval or bounce-back | pending | +| 6 | `workflow_runner` | Finalize lifecycle | Registries, SCR/archive updates, commit, final report | pending | + +## Operational Cycle + +1. **Task Readiness Check:** Read the full task file and verify Required PMA Inputs are present. +2. **Pre-Task Sync:** Use Task-tool specialist delegation to confirm readiness with the required specialist quorum. +3. **Plan:** Append/update the Workflow Execution Plan in the task file. +4. **Delegate Implementation:** Assign implementation to `developer` with the task file path, AC IDs, constraints, and expected evidence. +5. **Collect Evidence:** Ensure implementation output updates the task file and includes AC traceability. +6. **Delegate Verification:** Assign verification to `qa_engineer` and technical signoff to `tech_lead`; include the same task file path. +7. **Bounce Back If Needed:** If QA or Tech Lead rejects the work, send it back to the correct specialist using the same task context. Do not fix it yourself. +8. **Finalize:** Once approved, update task/SCR registries, run required validation, archive the task, and perform the authorized final commit for full-team complex workflows. +9. **Return Final Summary:** End with a concise PMA-facing report including Summary, Work Performed, AC Coverage, Evidence, Documentation Impact, Commit, Open Risks, and Closure Recommendation. + +## Hard Blocker Mechanism + +If you cannot proceed after reasonable orchestration attempts: + +- Stop further execution. +- End your current run by returning a final summary that starts with `HARD BLOCKER:`. +- Include the exact missing information, failed dependency, rejected evidence, or external issue PMA/user must resolve. +- Do not keep prompting or attempting additional work after declaring a hard blocker. +- Do not attempt to message PMA directly; the plugin relays your final output back to the PMA session. + +## Resume Awareness + +If PMA later reopens the same task because discrepancies or minor same-scope changes were found after implementation, resume work under the same task file ID, reuse the same Task tool `task_id` for specialist continuity, and reuse the same Workflow Runner `session_id` when possible so prior context remains available. + + + + + + diff --git a/docs/core/agent_orchestration.md b/docs/core/agent_orchestration.md index 37bd224..e6dad57 100644 --- a/docs/core/agent_orchestration.md +++ b/docs/core/agent_orchestration.md @@ -18,7 +18,7 @@ The **Product Manager Agent (PMA)** is the sole orchestrator. Subagents (Archite - The canonical task-routing definitions live in `docs/core/task_model.md`. - `tiny` work stays lightweight and direct. - `standard` work stays bounded and uses the normal delivery path. -- `complex` implementation work uses slice-based decomposition and delegated PMA workflow sessions. +- `complex` implementation work uses slice-based decomposition and `workflow_runner`. - PMA always facilitates pre-sync, while the required specialist quorum follows the defaults in `docs/core/task_model.md`. ### 3. Operational Flow (Two-Phase Execution) @@ -47,7 +47,7 @@ The workflow is divided into a **Negotiation Phase** (Human-involved) and a **De - If a task that was believed to be done later needs discrepancies fixed or minor same-scope changes, PMA should move that same task back into `Active` instead of creating a brand new task. - The task keeps the same task file ID and records the discrepancy in `Reopen History`. - When PMA resumes delegated task work, it should reuse the same Task tool `task_id` when possible. -- If the task previously ran through a delegated PMA workflow session, PMA should reuse both the same Task tool `task_id` and the same workflow `session_id` when possible so the prior context is preserved. +- If the task previously ran through `workflow_runner`, PMA should reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible so the prior context is preserved. - Create a new task only when the new work is truly follow-up scope rather than unfinished original scope. ### 3.1 Limited Parallelism (Shared Worktree) @@ -59,7 +59,7 @@ The workflow is divided into a **Negotiation Phase** (Human-involved) and a **De - **Clarification/Questions:** Any need for clarification or questions from an agent is directed to the PMA. The PMA then facilitates the inquiry and relays the response. - **Dependency Management:** The PMA actively tracks and manages all task dependencies. - **Review & Feedback:** The PMA assigns review and verification work to the appropriate technical specialists, with Tech Lead remaining the default technical review authority. -- **Commit Authority:** Tech Lead is the default commit authority for direct execution paths. A delegated PMA workflow session may perform the final commit only in delegated full-team complex workflows, while the originating PMA remains the final closure authority. +- **Commit Authority:** Tech Lead is the default commit authority for direct execution paths. Workflow Runner may perform the final commit only in delegated full-team complex workflows, while PMA remains the final closure authority. - **Escalation:** Any persistent blockers or disagreements are escalated directly to the PMA. - **Orchestrated Discussion Workflow:** The PMA may create a new `Task`, reuse the resulting `session_id`, gather specialist input, and synthesize the final decision. - **Documentation as the Single Source of Truth:** All agents refer to project documentation in `docs/` as the primary authority, and the PMA ensures it stays current. diff --git a/docs/core/pma_mode_full.md b/docs/core/pma_mode_full.md index f14e7b3..c17ecbb 100644 --- a/docs/core/pma_mode_full.md +++ b/docs/core/pma_mode_full.md @@ -8,7 +8,7 @@ You are operating in **full team mode**. ## Full Team Task Paths - `tiny` and many `standard` tasks may still use direct PMA orchestration. -- `complex` implementation tasks should use delegated PMA workflow sessions when appropriate. +- `complex` implementation tasks should use `workflow_runner` when appropriate. - Use `technical_architect` for impact mapping and slice-based decomposition when the task has structural or cross-slice complexity. ## Full Team Specialist Use @@ -21,5 +21,5 @@ You are operating in **full team mode**. ## Full Team Complex Workflow -- When using `nomadflow_run_workflow`, treat the delegated PMA as a separate execution session that owns pre-sync, execution, post-task sync, and final reporting. -- The originating PMA remains the orchestrator of the overall program of work and reviews the delegated PMA's final output before closure. +- When using `workflow_runner`, treat it as a separate execution session that owns task-readiness validation, pre-sync, specialist delegation, post-task sync, finalization, and final reporting. +- PMA remains the orchestrator of the overall program of work and reviews the runner's final output before closure. diff --git a/docs/core/pma_mode_mini.md b/docs/core/pma_mode_mini.md index ce3be40..e1089ee 100644 --- a/docs/core/pma_mode_mini.md +++ b/docs/core/pma_mode_mini.md @@ -5,7 +5,7 @@ You are operating in **mini team mode**. - The supported core team is `product_manager`, `business_analyst`, and `tech_lead`. - Only `tiny` and `standard` tasks are supported in this mode. - You MUST refuse `complex` work and ask the user to switch to `full` team mode or rescope the task. -- Do NOT attempt to use delegated PMA workflow sessions in mini mode. +- Do NOT attempt to use `workflow_runner` in mini mode. - Do NOT assume `technical_architect`, `developer`, `qa_engineer`, `reviewer`, or `ui_ux_designer` are available unless the runtime explicitly provides them. ## Mini Team Task Paths @@ -29,5 +29,5 @@ You are operating in **mini team mode**. - the task is clearly `complex` - architecture design or structural decomposition is required -- the work needs delegated PMA workflow orchestration +- the work needs Workflow Runner orchestration - the work needs specialist coverage the mini team cannot provide safely diff --git a/docs/core/role_contracts.md b/docs/core/role_contracts.md index 78b26fc..3a68b28 100644 --- a/docs/core/role_contracts.md +++ b/docs/core/role_contracts.md @@ -13,19 +13,19 @@ This document defines the workflow verbs and handoff output contract used across - **Product Manager Agent (PMA):** Owns workflow closure in all modes. PMA decides whether evidence, documentation, and registry state are sufficient for final closure. - **Tech Lead:** Default commit authority for direct execution paths and mini-team work. -- **Delegated PMA workflow session:** Delegated commit authority only for full-team complex workflows that the originating PMA explicitly starts. +- **Workflow Runner:** Delegated commit authority only for full-team complex workflow-runner paths that PMA explicitly starts. - **Task Archiving:** Archive and registry updates are part of finalization and must be included in the final committed state. ## Documentation Responsibility Model - **Business Analyst:** Owns product truth and product-facing feature documentation. - **Technical Architect:** Owns architecture truth and technical design documentation. -- **Tech Lead / Developer / delegated PMA workflow session:** May update code-adjacent documentation during execution. +- **Tech Lead / Developer / Workflow Runner:** May update code-adjacent documentation during execution. - **PMA:** Verifies documentation closure and decides whether documentation impact has been fully resolved for the task. ## Specialist Output Contract -When handing work back to PMA, specialists should return these sections in a concise format: +When handing work back to PMA or Workflow Runner, specialists should return these sections in a concise format: - **Summary:** What was done or decided. - **Work Performed:** Files changed, reviewed, or key areas analyzed. diff --git a/docs/core/task_model.md b/docs/core/task_model.md index cd152eb..4595603 100644 --- a/docs/core/task_model.md +++ b/docs/core/task_model.md @@ -6,7 +6,7 @@ NomadWorks classifies work across three orthogonal dimensions. - `tiny`: Very small, low-risk work such as copy edits, typos, trivial config fixes, or narrowly scoped non-behavioral changes. - `standard`: The default delivery path for bounded bug fixes, focused features, and moderate documentation or QA work. -- `complex`: Multi-step work that benefits from decomposition, multiple specialist handoffs, and delegated PMA workflow orchestration. +- `complex`: Multi-step work that benefits from decomposition, multiple specialist handoffs, and full Workflow Runner orchestration. ## 2. Track @@ -29,7 +29,7 @@ NomadWorks classifies work across three orthogonal dimensions. - `tiny` tasks should stay within one slice and usually one specialist handoff. - `standard` tasks should keep one primary slice even if they touch adjacent areas. - `complex` tasks should be decomposed into slice-based subtasks. -- `complex + implementation` is the default case for using `nomadflow_run_workflow` to start a delegated PMA workflow session. +- `complex + implementation` is the default case for using `workflow_runner`. - While one implementation task is active in the shared worktree, parallel work should be limited to `investigation` or `spec` tasks that avoid conflicting edits. ## Pre-Sync Specialist Defaults diff --git a/docs/core/tech_lead_mode_full.md b/docs/core/tech_lead_mode_full.md index 8f616af..2f6dc75 100644 --- a/docs/core/tech_lead_mode_full.md +++ b/docs/core/tech_lead_mode_full.md @@ -5,4 +5,4 @@ You are operating in **full team mode**. - Full team mode includes broader specialist coverage across architecture, QA, and workflow orchestration. - Focus on technical leadership, behavioral verification, and high-quality execution while using other specialists where appropriate. - Do not absorb all specialist responsibilities by default. Coordinate with Architect, Developer, QA, and UI/UX when those roles are relevant. -- For `complex` work, support PMA and delegated PMA workflow sessions through technical review, behavioral verification, and escalation handling rather than acting as the sole technical path. +- For `complex` work, support PMA and Workflow Runner through technical review, behavioral verification, and escalation handling rather than acting as the sole technical path. diff --git a/docs/core/tech_lead_mode_mini.md b/docs/core/tech_lead_mode_mini.md index 36b963d..aab0b49 100644 --- a/docs/core/tech_lead_mode_mini.md +++ b/docs/core/tech_lead_mode_mini.md @@ -8,4 +8,4 @@ You are operating in **mini team mode**. - You are responsible for making technical progress without assuming that Architect, Developer, or QA are available as separate agents. - Treat product-truth updates as BA-owned, but flag PMA if technical changes require corresponding technical documentation updates. - If UI-facing work lacks dedicated UI/UX review, call out the reduced-review risk explicitly. -- If the task clearly requires deeper architecture support, delegated PMA workflow orchestration, or broader specialist coverage, tell PMA to switch the repository to `full` team mode or rescope the task. +- If the task clearly requires deeper architecture support, Workflow Runner orchestration, or broader specialist coverage, tell PMA to switch the repository to `full` team mode or rescope the task. diff --git a/docs/guides/AGENTS.md b/docs/guides/AGENTS.md index eb4b06d..bbfbb3b 100644 --- a/docs/guides/AGENTS.md +++ b/docs/guides/AGENTS.md @@ -6,7 +6,8 @@ The collective is designed so each agent represents a professional function insi ## Primary orchestration agents -- `product_manager`: The default primary agent. Routes work by complexity, delegates specialists, and may start delegated PMA workflow sessions for complex work. +- `product_manager`: The default primary agent. Routes work by complexity, delegates specialists, and decides when to use the Workflow Runner. +- `workflow_runner`: Delegated orchestrator for complex implementation tasks. Handles task-readiness validation, pre-task sync, specialist delegation, post-task sync, finalization, and final reporting inside a PMA-started workflow. ## Specialist agents @@ -59,4 +60,4 @@ Use shared policies and additive agent files by default. Use full agent definiti - PMA links the task to an approved SCR. - Architect helps decompose the work into slice-based subtasks. -- PMA may start a delegated PMA workflow session to execute the end-to-end delivery cycle while the originating PMA waits for completion notification. +- `workflow_runner` executes the end-to-end delivery cycle through specialist delegation while PMA waits for completion notification. diff --git a/docs/guides/TEAM_MODE_FULL.md b/docs/guides/TEAM_MODE_FULL.md index 301967c..a89f0e5 100644 --- a/docs/guides/TEAM_MODE_FULL.md +++ b/docs/guides/TEAM_MODE_FULL.md @@ -5,6 +5,7 @@ Full team mode enables the complete NomadWorks Collective. ## Available Agents - `product_manager` (PMA) +- `workflow_runner` - `business_analyst` (BA) - `technical_architect` - `tech_lead` @@ -25,10 +26,10 @@ User request -> PMA classifies task and track -> BA + Tech Lead refine or review specification -> For standard work, PMA orchestrates specialist handoffs directly - -> For complex work, PMA starts a delegated PMA workflow session + -> For complex work, PMA starts Workflow Runner in a separate session -> Architect decomposes structural work into slices when needed -> Developer / QA / UI-UX contribute by specialty - -> Delegated PMA workflow or originating PMA returns evidence and completion state + -> Workflow Runner or PMA returns evidence and completion state -> PMA checks documentation closure -> Commit and archive ``` @@ -36,7 +37,7 @@ User request ## Full Team Responsibilities - **PMA:** orchestration, routing, final closure -- **Delegated PMA workflow:** separate-session execution for complex workflows +- **Workflow Runner:** separate-session orchestration for complex workflows - **BA:** product truth and acceptance criteria - **Technical Architect:** architecture and decomposition - **Tech Lead:** technical leadership and behavioral verification diff --git a/docs/guides/TEAM_MODE_MINI.md b/docs/guides/TEAM_MODE_MINI.md index 4e78adc..066c7e6 100644 --- a/docs/guides/TEAM_MODE_MINI.md +++ b/docs/guides/TEAM_MODE_MINI.md @@ -16,7 +16,7 @@ Mini team mode is the lightest supported NomadWorks operating model. Not supported: - `complex` -- delegated PMA workflow sessions +- `workflow_runner` ## Mini Team Task Flow @@ -38,4 +38,4 @@ User request ## Escalation Rule -If the task clearly needs architecture decomposition, delegated PMA workflow orchestration, or broader specialist support, PMA should stop and ask to switch the repository to `full` team mode or rescope the work. +If the task clearly needs architecture decomposition, Workflow Runner orchestration, or broader specialist support, PMA should stop and ask to switch the repository to `full` team mode or rescope the work. diff --git a/docs/guides/TOOLS.md b/docs/guides/TOOLS.md index 3adf2b4..092bfb6 100644 --- a/docs/guides/TOOLS.md +++ b/docs/guides/TOOLS.md @@ -84,33 +84,33 @@ This tool performs the full close flow synchronously: ## `nomadflow_run_workflow` -Starts a delegated `product_manager` workflow session for a complex task. +Starts a `workflow_runner` session for a complex task. ### Arguments - `task_path`: path to the task markdown file -- `instructions`: detailed instructions for the delegated PMA workflow session +- `instructions`: detailed instructions for the workflow runner ### Notes - Only available in `full` team mode. - Used for `complex` implementation tasks. -- The delegated PMA executes in a separate session and reports completion back to the originating PMA session. -- The delegated PMA is expected to orchestrate the lifecycle by delegating implementation and verification work to specialists, driving the task to delivery or a hard blocker. -- For implementation tasks, the delegated PMA must create or append a Workflow Execution Plan in the task file after Pre-Task Sync and before implementation starts. -- The delegated PMA must not directly edit product source code, tests, application configuration, or implementation files. -- When a hard blocker is reached, the delegated PMA should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the originating PMA session. +- The runner executes in a separate session and reports completion back to PMA. +- The runner is expected to orchestrate the lifecycle by validating task readiness, delegating implementation and verification work to specialists, and driving the task to delivery or a hard blocker. +- For implementation tasks, the runner must create or append a Workflow Execution Plan in the task file after Pre-Task Sync and before implementation starts. +- The runner must not directly edit product source code, tests, application configuration, or implementation files. +- When a hard blocker is reached, the runner should end its run and return a final summary starting with `HARD BLOCKER:` so the plugin relays it back to the PMA session. ## `nomadflow_prompt_workflow` -Sends a follow-up prompt to an existing delegated PMA workflow session. +Sends a follow-up prompt to an existing `workflow_runner` session. ### Arguments -- `session_id`: delegated PMA workflow session ID +- `session_id`: workflow runner session ID - `text`: follow-up message for that session ### Notes - Only available in `full` team mode. -- Useful for bounce-backs, clarifications, and resumed delegated workflow work. +- Useful for bounce-backs, clarifications, and resumed runner work. diff --git a/docs/guides/WORKFLOW.md b/docs/guides/WORKFLOW.md index 778a650..c6a15e2 100644 --- a/docs/guides/WORKFLOW.md +++ b/docs/guides/WORKFLOW.md @@ -6,7 +6,7 @@ NomadWorks uses three task complexity levels and three work tracks. - `tiny`: Minimal, low-risk work. - `standard`: Default bounded delivery work. -- `complex`: Multi-step work that uses decomposition and delegated PMA workflow orchestration. +- `complex`: Multi-step work that uses decomposition and the Workflow Runner. ## Track @@ -41,7 +41,7 @@ NomadWorks uses three task complexity levels and three work tracks. ## Team modes - `mini`: supports `tiny` and `standard` only, using `product_manager`, `business_analyst`, and `tech_lead` -- `full`: supports `tiny`, `standard`, and `complex`, including delegated PMA workflow sessions +- `full`: supports `tiny`, `standard`, and `complex`, including `workflow_runner` See also: @@ -85,7 +85,7 @@ Track these task files under `Active Discussions` in `tasks/current.md` until th - Move it back into `Active` in `tasks/current.md`. - Keep the same task file ID and record the reason in `Reopen History`. - Reuse the same Task tool `task_id` for delegated task work when possible. -- If the task used a delegated PMA workflow session, reuse both the same Task tool `task_id` and the same workflow `session_id` when possible. +- If the task used `workflow_runner`, reuse both the same Task tool `task_id` and the same Workflow Runner `session_id` when possible. ## Evidence By Track diff --git a/docs/product/DOMAIN_MAP.md b/docs/product/DOMAIN_MAP.md index c60c340..7277820 100644 --- a/docs/product/DOMAIN_MAP.md +++ b/docs/product/DOMAIN_MAP.md @@ -12,8 +12,8 @@ This document maps the major product domains and the features that belong to the ### Agent Orchestration -- **Purpose:** Defines how PMA and specialist agents collaborate. -- **Owned Features:** Product Manager routing, delegated PMA workflow sessions, specialist delegation, discussion protocols. +- **Purpose:** Defines how PMA, Workflow Runner, and specialist agents collaborate. +- **Owned Features:** Product Manager routing, Workflow Runner handoff, specialist delegation, discussion protocols. - **Primary Docs:** `docs/guides/AGENTS.md`, `docs/core/agent_orchestration.md` ### Task Lifecycle diff --git a/docs/product/FEATURES_LIST.md b/docs/product/FEATURES_LIST.md index e044907..2f44948 100644 --- a/docs/product/FEATURES_LIST.md +++ b/docs/product/FEATURES_LIST.md @@ -5,7 +5,7 @@ This document is the "Single Source of Truth" for all features implemented or pl ## 1. Core Features - **Plugin-Based Agent Installation:** [Status: Done] - **Product Manager Default Agent:** [Status: Done] -- **Delegated PMA Workflow Session Orchestration:** [Status: Done] +- **Workflow Runner Session Orchestration:** [Status: Done] - **CodeMap Validation:** [Status: Done] - **Complexity-Based Task Routing (`tiny`, `standard`, `complex`):** [Status: In Progress] - **Standard Slice Model (`foundation`, `core`, `logic`, `ui`, `polish`, `qa`, `docs`):** [Status: In Progress] diff --git a/docs/setup/CONFIGURATION.md b/docs/setup/CONFIGURATION.md index 1a434d1..88da84f 100644 --- a/docs/setup/CONFIGURATION.md +++ b/docs/setup/CONFIGURATION.md @@ -41,12 +41,12 @@ agents: - Enabled by default: `product_manager`, `business_analyst`, `tech_lead` - Intended for: `tiny` and `standard` tasks in simple repositories -- Not supported: `complex` delegated workflows +- Not supported: `complex` work and `workflow_runner` ### `full` - Enables the full NomadWorks Collective by default -- Intended for: repositories that need the complete specialist role set and delegated PMA workflows +- Intended for: repositories that need the complete role set, including `workflow_runner` - Supports: `tiny`, `standard`, and `complex` ## Common uses @@ -78,7 +78,7 @@ Mandatory agents cannot be disabled: ```yaml agents: - developer: + workflow_runner: tools_add: - nomadworks_validate ``` diff --git a/policies/README.md b/policies/README.md index a56bdab..9adc62c 100644 --- a/policies/README.md +++ b/policies/README.md @@ -15,11 +15,11 @@ Files under `.nomadworks/generated/policies/` are reference copies only. They ar - `development-guidelines.md` - Repository-specific engineering rules, stack notes, and implementation conventions. - - Used by: `developer`, `technical_architect`, `tech_lead`, delegated PMA workflows + - Used by: `developer`, `technical_architect`, `tech_lead`, `workflow_runner` - `testing-guidelines.md` - Testing, evidence, regression, and verification conventions. - - Used by: `developer`, `qa_engineer`, `tech_lead`, delegated PMA workflows + - Used by: `developer`, `qa_engineer`, `tech_lead`, `workflow_runner` - `documentation-guidelines.md` - Documentation layout, naming, ownership, and update expectations. @@ -35,7 +35,7 @@ Files under `.nomadworks/generated/policies/` are reference copies only. They ar - `git-commit-messaging.md` - Commit subject and body rules. - - Used by: `tech_lead`, delegated PMA workflows + - Used by: `tech_lead`, `workflow_runner` - `product-guidelines.md` - User story, acceptance criteria, terminology, and product-truth conventions. diff --git a/src/index.js b/src/index.js index 2e5cb8f..6b51122 100644 --- a/src/index.js +++ b/src/index.js @@ -809,16 +809,16 @@ export default async function NomadWorksPlugin(input) { try { // Blocking prompt call in a background promise - if (debug) console.log(`[NomadFlow] Sending initial/resumed prompt to delegated PMA session ${sessionId}...`); + if (debug) console.log(`[NomadFlow] Sending initial/resumed prompt to Workflow Runner session ${sessionId}...`); const runResult = await client.session.prompt({ path: { id: sessionId }, body: { - agent: "product_manager", + agent: "workflow_runner", parts: [{ type: "text", text: initialText }] } }); - if (debug) console.log(`[NomadFlow] Delegated PMA session ${sessionId} returned control.`); + if (debug) console.log(`[NomadFlow] Workflow Runner session ${sessionId} returned control.`); // Capture final message and notify PMA const finalMessage = runResult.data.parts.map(p => p.text).join("\n"); @@ -829,7 +829,7 @@ export default async function NomadWorksPlugin(input) { body: { parts: [{ type: "text", - text: `[NomadFlow Notification] Delegated PMA workflow has finished work for: ${identifier}.\n\nFINAL SUMMARY FROM DELEGATED PMA:\n${finalMessage}` + text: `[NomadFlow Notification] Workflow Runner has finished work for: ${identifier}.\n\nFINAL SUMMARY FROM RUNNER:\n${finalMessage}` }] } }); @@ -841,7 +841,7 @@ export default async function NomadWorksPlugin(input) { await client.session.promptAsync({ path: { id: pmaSessionId }, body: { - parts: [{ type: "text", text: `[NomadFlow Error] Delegated PMA workflow failed for ${identifier}: ${err.message}` }] + parts: [{ type: "text", text: `[NomadFlow Error] Workflow Runner failed for ${identifier}: ${err.message}` }] } }); } catch (notifyErr) { @@ -1131,17 +1131,17 @@ export default async function NomadWorksPlugin(input) { } }), nomadflow_run_workflow: tool({ - description: "Start a delegated PMA workflow session for a complex task", + description: "Start a workflow_runner session for a complex task", args: { task_path: tool.schema.string().describe("Path to the task markdown file (e.g. tasks/todo/task_001.md)"), - instructions: tool.schema.string().describe("Detailed instructions for the delegated PMA workflow session") + instructions: tool.schema.string().describe("Detailed instructions for the workflow_runner") }, async execute(args, context) { const client = input.client; if (!client) return "Error: OpenCode client not available in plugin context."; - if (operatingTeamMode !== "full") { - return "FAIL: Delegated PMA workflows are unavailable in mini team mode. Switch to full team mode to run complex workflows."; + if (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full") { + return "FAIL: Workflow Runner is unavailable in the current team configuration. Switch to full team mode to run complex workflows."; } const pmaSessionId = context.sessionId || context.sessionID; @@ -1171,17 +1171,17 @@ export default async function NomadWorksPlugin(input) { ].filter(Boolean).join("\n"); const lifecycleInstruction = workflowTrack === "implementation" - ? "You are a delegated PMA workflow session. Execute the full lifecycle (Sync -> Workflow Execution Plan -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). After Pre-Task Sync, create or append a Workflow Execution Plan in the task file and assign each step to the responsible specialist. Do not implement code directly. If implementation is required, delegate it to developer. If verification is required, delegate it to qa_engineer and tech_lead. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to the originating PMA session. Provide a final summary." + ? "You are the Workflow Runner. Execute the full lifecycle (Task Readiness Check -> Pre-Task Sync -> Workflow Execution Plan -> Delegate Implementation -> Delegate Verification -> Post-Task Sync -> Commit -> Archive). Read the task file first and verify it has sufficient PMA-provided task management context before doing anything else. Do not implement code directly. If implementation is required, delegate it to developer. If verification is required, delegate it to qa_engineer and tech_lead. If you hit a hard blocker, stop and END your run with a final summary that starts with 'HARD BLOCKER:' so the plugin can relay it back to PMA. Provide a final summary." : workflowTrack === "spec" - ? "You are a delegated PMA workflow session. Execute the full spec lifecycle for this task, delegate specialist work as needed, update the required documentation artifacts, and provide a final summary." - : "You are a delegated PMA workflow session. Execute the investigation lifecycle for this task, delegate specialist work as needed, capture findings clearly, and provide a final summary."; + ? "You are the Workflow Runner. Execute the full spec lifecycle for this task, delegate specialist work as needed, update the required documentation artifacts, and provide a final summary." + : "You are the Workflow Runner. Execute the investigation lifecycle for this task, delegate specialist work as needed, capture findings clearly, and provide a final summary."; const initialText = `Task File: ${args.task_path}\n${metadataSummary ? `\n${metadataSummary}` : ""}\n\nInstructions: ${args.instructions}\n\n${lifecycleInstruction}`; // Start monitoring in background (async) startAndMonitorWorkflow(sessionId, pmaSessionId, initialText, args.task_path); - return `SUCCESS: Delegated PMA workflow session started. ID: ${sessionId}\nTrack: ${workflowTrack}\nInstructions sent for ${args.task_path}. You will be notified on completion in this session (${pmaSessionId}).`; + return `SUCCESS: Workflow Runner session started. ID: ${sessionId}\nTrack: ${workflowTrack}\nInstructions sent for ${args.task_path}. You will be notified on completion in this session (${pmaSessionId}).`; } catch (e) { console.error("[NomadFlow] Failed to start workflow session:", e); return `FAIL: Failed to initiate session: ${e.message}`; @@ -1189,17 +1189,17 @@ export default async function NomadWorksPlugin(input) { } }), nomadflow_prompt_workflow: tool({ - description: "Send a message or follow-up prompt to an existing delegated PMA workflow session", + description: "Send a message or follow-up prompt to an existing workflow_runner session", args: { session_id: tool.schema.string().describe("The ID of the session started by nomadflow_run_workflow"), - text: tool.schema.string().describe("The message or instruction to send to the delegated PMA workflow session") + text: tool.schema.string().describe("The message or instruction to send to the workflow_runner") }, async execute(args, context) { const client = input.client; if (!client) return "Error: OpenCode client not available."; - if (operatingTeamMode !== "full") { - return "FAIL: Delegated PMA workflows are unavailable in mini team mode. Switch to full team mode to send workflow prompts."; + if (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full") { + return "FAIL: Workflow Runner is unavailable in the current team configuration. Switch to full team mode to send workflow runner prompts."; } const pmaSessionId = context.sessionId || context.sessionID; @@ -1217,7 +1217,7 @@ export default async function NomadWorksPlugin(input) { return `SUCCESS: Session '${args.session_id}' was not tracked. Sent prompt and resumed monitoring. You will be notified on completion in this session (${pmaSessionId}).`; } - // 2. If already tracking (delegated PMA is active), send asynchronously so PMA isn't blocked + // 2. If already tracking (runner is active), send asynchronously so PMA isn't blocked await client.session.promptAsync({ path: { id: args.session_id }, body: { parts: [{ type: "text", text: args.text }] } @@ -1253,7 +1253,7 @@ export default async function NomadWorksPlugin(input) { body: { parts: [{ type: "text", - text: `[NomadFlow Error Notification] Delegated PMA workflow session ${sessionID} has ${event.type.split('.')[1]}. Please check the workflow session logs.` + text: `[NomadFlow Error Notification] Workflow Runner session ${sessionID} has ${event.type.split('.')[1]}. Please check the runner session logs.` }] } }); @@ -1376,7 +1376,7 @@ export default async function NomadWorksPlugin(input) { } } - if (id === "product_manager" && operatingTeamMode !== "full") { + if (id === "product_manager" && (!isAgentEffectivelyEnabled("workflow_runner", repoCfg) || operatingTeamMode !== "full")) { if (agentConfig.tools) { delete agentConfig.tools.nomadflow_run_workflow; delete agentConfig.tools.nomadflow_prompt_workflow; diff --git a/tasks/task-template.md b/tasks/task-template.md index bdde578..8a601a4 100644 --- a/tasks/task-template.md +++ b/tasks/task-template.md @@ -24,7 +24,7 @@ reopened_count: 0 [Short description of the intended outcome and scope.] ## Ownership -- **Assigned To:** `[product_manager | business_analyst | tech_lead | technical_architect | developer | qa_engineer | ui_ux_designer]` +- **Assigned To:** `[product_manager | business_analyst | tech_lead | technical_architect | developer | qa_engineer | ui_ux_designer | workflow_runner]` - **Handoff From:** `[agent_name or null]` ## Definition Of Ready Check @@ -87,7 +87,7 @@ Use this section when a task that was thought to be done must be resumed using t - **Reason:** [What discrepancy, incomplete work, or minor same-scope change was found] - **Resume Path:** [How the task returns to Active and which agent owns the next step] - **Task Tool Resume:** [Reuse the same Task tool `task_id` if applicable, otherwise write `Not applicable`] -- **Workflow Session Resume:** [Reuse the same delegated PMA workflow `session_id` if applicable, otherwise write `Not applicable`] +- **Workflow Session Resume:** [Reuse the same Workflow Runner `session_id` if applicable, otherwise write `Not applicable`] ### Pre Sync * **PMA Facilitator:** The Product Manager always runs the sync and records the decision. @@ -148,7 +148,7 @@ Use this section when a task that was thought to be done must be resumed using t - If a completed task needs discrepancies fixed or minor same-scope changes after implementation, move the same task back into `Active` rather than creating a new task for the same unfinished scope. - Keep the same task file ID. - Reuse the same Task tool `task_id` when resuming delegated task work, when possible. -- Reuse the same delegated PMA workflow `session_id` when resuming a delegated workflow task, when possible. +- Reuse the same Workflow Runner `session_id` when resuming a Workflow Runner task, when possible. # Reviews ## Technical Architect: