bmad-module-ultracode-goal 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +3 -2
- package/docs/architecture.md +6 -4
- package/docs/comparison.md +25 -24
- package/docs/cross-session-recall.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/how-it-works.md +1 -1
- package/docs/index.md +1 -0
- package/docs/knowledge-graph-refresh.md +66 -0
- package/package.json +1 -1
- package/skills/ultracode-goal/customize.toml +1 -2
- package/skills/ultracode-goal/references/finalize.md +8 -4
- package/website/astro.config.mjs +1 -0
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"name": "bmad-module-ultracode-goal",
|
|
20
20
|
"source": "./",
|
|
21
21
|
"description": "Supercharges BMAD with Claude Code Goal Mode, Auto Mode, and Auto Memory: autonomous Epic execution to a machine-checked, TEA-gated Definition-of-Done. Execute Epics. Accumulate Knowledge. Deliver Outcomes.",
|
|
22
|
-
"version": "1.0.
|
|
22
|
+
"version": "1.0.1",
|
|
23
23
|
"author": {
|
|
24
24
|
"name": "Armel"
|
|
25
25
|
},
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://www.npmjs.com/package/bmad-module-ultracode-goal)
|
|
12
12
|
[](https://opensource.org/license/MIT)
|
|
13
13
|
[](https://github.com/bmad-code-org/BMAD-METHOD)
|
|
14
|
-
[](https://www.python.org)
|
|
15
15
|
[](https://docs.astral.sh/uv/)
|
|
16
16
|
[](https://armelhbobdad.github.io/bmad-module-ultracode-goal/)
|
|
17
17
|
[](https://github.com/armelhbobdad/bmad-module-ultracode-goal/stargazers)
|
|
@@ -61,7 +61,7 @@ The `gate_status` comes straight from TEA's artifact: `gate_eval.py` never re-de
|
|
|
61
61
|
|
|
62
62
|
## Install
|
|
63
63
|
|
|
64
|
-
Requires [Claude Code](https://claude.com/product/claude-code) (the runtime UCG conducts), [Node.js](https://nodejs.org/) >= 22, [Python](https://www.python.org/) >= 3.
|
|
64
|
+
Requires [Claude Code](https://claude.com/product/claude-code) (the runtime UCG conducts), [Node.js](https://nodejs.org/) >= 22, [Python](https://www.python.org/) >= 3.11, [uv](https://docs.astral.sh/uv/), plus `git` and `gh` on PATH.
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
67
|
npx bmad-module-ultracode-goal install
|
|
@@ -138,6 +138,7 @@ The docs are organized into three buckets: **Why** (start here), **Try** (do stu
|
|
|
138
138
|
- **[Gate Model](./docs/gate-model.md)**: how `gate_eval.py` maps `gate_status` to a verdict, and the production AND-signals.
|
|
139
139
|
- **[Health Check](./docs/health-check.md)**: the terminal self-improvement loop: what it sends, privacy, and how to disable it.
|
|
140
140
|
- **[Cross-Session Recall](./docs/cross-session-recall.md)**: the optional claude-mem integration: touchpoints, trust model, and how to enable it.
|
|
141
|
+
- **[Knowledge-Graph Refresh](./docs/knowledge-graph-refresh.md)**: the optional graphify integration: preconditions, what it sends where, and what it never touches.
|
|
141
142
|
- **[Troubleshooting](./docs/troubleshooting.md)**: real failure modes and their remediations.
|
|
142
143
|
|
|
143
144
|
Every run that reaches Finalize ends with a self-improvement check that can file a deduplicated GitHub issue with your approval, so **please let runs finish through Finalize**, or [open an issue](https://github.com/armelhbobdad/bmad-module-ultracode-goal/issues/new/choose) directly. If UCG shipped an epic while you slept, a ⭐ helps others find it.
|
package/docs/architecture.md
CHANGED
|
@@ -88,11 +88,13 @@ skills/ultracode-goal/
|
|
|
88
88
|
|
|
89
89
|
Configuration resolves in three layers, base → team → user, via `resolve_customization.py`:
|
|
90
90
|
|
|
91
|
-
1. **Base**: `customize.toml` in the skill root (the shipped `[workflow]` block).
|
|
92
|
-
2. **Team**: `{project-root}/_bmad/custom/ultracode-goal.toml
|
|
93
|
-
3. **User**: `{project-root}/_bmad/custom/ultracode-goal.user.toml`.
|
|
91
|
+
1. **Base**: `customize.toml` in the skill root (the shipped `[workflow]` block). In an installed project that file is `{project-root}/_bmad/ucg/ultracode-goal/customize.toml`, a verbatim copy of the shipped one; it is the layer to read (every knob is there with its comment), not the layer to edit.
|
|
92
|
+
2. **Team**: `{project-root}/_bmad/custom/ultracode-goal.toml`, committed.
|
|
93
|
+
3. **User**: `{project-root}/_bmad/custom/ultracode-goal.user.toml`, gitignored by the `*.user.toml` rule that ships in `_bmad/custom/.gitignore`.
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
Neither override file is created by any installer, and a missing one is not an error: the resolver loads it non-required and treats absence as an empty table, so a fresh project resolves the base layer alone. You create them when you first need to override something. Do not mistake them for the `config.toml` and `config.user.toml` already sitting in that directory: those are BMAD's own configuration, and a UCG knob written there resolves to nothing.
|
|
96
|
+
|
|
97
|
+
Merge semantics: **scalars override**, **tables deep-merge**, **arrays append**. At activation the skill runs `resolve_customization.py --skill {skill-root} --key workflow`; if that fails, it resolves the three files itself in the same order. The shipped base layer defines the run's knobs: the TEA/artifact paths (`tea_config_path`, `trace_output_dir`, `implementation_artifacts`, `deferred_work_path`), the git guardrails (`epic_branch_prefix`, `protected_branches`), the turn budget (`max_turns_per_story`; `story_token_budget` remains as a deprecated no-op key), the experimental `parallel_max_concurrency`, the `allowlist_commands`, the two lifecycle hooks (`on_epic_complete`, `on_escalation`), the [health check](./health-check.md) family (`health_check_repo`, `health_check_seen_cache`, `health_check_queue_path`, `health_check_autosubmit`), and the two optional third-party integrations, both off by default: [`cross_session_recall`](./cross-session-recall.md) and [`graphify_integration`](./knowledge-graph-refresh.md). Teams and users override without editing the shipped file. Remember that a budget or branch override only reaches the *enforcement* layer because preflight threads it into the hook env (see layer 2 above).
|
|
96
98
|
|
|
97
99
|
The three TOML layers merge once, but a branch or budget value then travels two ways: the conductor reads it directly, while the hooks only see it if preflight re-injects it as env:
|
|
98
100
|
|
package/docs/comparison.md
CHANGED
|
@@ -5,13 +5,13 @@ description: An honest, side-by-side comparison of UltraCode Goal and bmad-code-
|
|
|
5
5
|
|
|
6
6
|
Both UltraCode Goal (UCG) and [bmad-loop](https://github.com/bmad-code-org/bmad-loop) (formerly bmad-auto; renamed at v0.8.0) automate the BMAD implementation phase without a babysitter. They are siblings, not clones: they make opposite bets on where the control loop lives and how completion is judged. This page compares them honestly, including the places where bmad-loop is the better tool.
|
|
7
7
|
|
|
8
|
-
Snapshot: UCG
|
|
8
|
+
Snapshot: UCG v1.0.0 and bmad-loop v0.9.0, as of 2026-07-28, both released versions. Both projects are young and moving fast. bmad-loop's v0.9.0 (released 2026-07-21) shipped four of the five items the previous snapshot listed as unreleased work on main: a `stories.yaml` planning mode with per-story checkpoints, patch-restore escalation recovery, a pluggable multiplexer-backend registry, and the integrity fixes to its verify gate. The fifth was this page's error rather than a gap in the release: those adversarial review layers are BMAD-METHOD's, declared in `bmad-dev-auto` and run against BMAD-METHOD's own review skills, and what v0.9.0 added was a preflight that refuses to start when they are missing. It also added a graceful stop that finishes the in-flight item before ending a run, an active-agent indicator in the dashboard, an OpenCode adapter driven over HTTP rather than a multiplexer, and stable, schema-versioned `--json` documents for six more commands: `status`, `list`, `validate`, `decisions`, `clean`, and `cleanup`. Eight commands now emit versioned documents, `diagnose` and `probe-adapter` having been converted from a JSON block appended to a text report; most of what is left is action commands with no document to emit. UCG reached v1.0.0 on 2026-07-28. Treat every line below as a point-in-time reading of two *released* versions, and verify the current state for yourself (links at the bottom); both projects' main branches run well ahead of their tags.
|
|
9
9
|
|
|
10
10
|
## The one difference everything else follows from
|
|
11
11
|
|
|
12
|
-
bmad-loop puts the control loop in **plain Python, outside the agent**. A deterministic orchestrator picks the next story, spawns a fresh, disposable coding-agent session (over tmux) for each step, watches structured hook events the session writes, and decides retries, gates, and completion in code. No LLM sits in the control loop.
|
|
12
|
+
bmad-loop puts the control loop in **plain Python, outside the agent**. A deterministic orchestrator picks the next story, spawns a fresh, disposable coding-agent session (over tmux by default) for each step, watches structured hook events the session writes, and decides retries, gates, and completion in code. No LLM sits in the control loop.
|
|
13
13
|
|
|
14
|
-
UCG puts the control loop **inside Claude Code**. The run is a Claude Code skill that composes `/goal`, Auto Mode, runtime hooks, and
|
|
14
|
+
UCG puts the control loop **inside Claude Code**. The run is a Claude Code skill that composes `/goal`, Auto Mode, Auto Memory, and runtime hooks; the experimental `--parallel` fan-out additionally uses a dynamic workflow, and degrades to the sequential spine when one is unavailable. The per-story loop is paced by Claude Code's `/goal` evaluator (an LLM), while the binding completion verdict is a deterministic script (`gate_eval.py`) that reads the Test Architect's (TEA) gate artifact.
|
|
15
15
|
|
|
16
16
|
The consequence cascades: bmad-loop is a tool you run beside any supported agent; UCG is a capability that lives within one specific agent.
|
|
17
17
|
|
|
@@ -19,20 +19,20 @@ The consequence cascades: bmad-loop is a tool you run beside any supported agent
|
|
|
19
19
|
|
|
20
20
|
| Dimension | bmad-loop | UltraCode Goal (UCG) |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| Runtime | External Python process plus tmux; Linux, macOS, or WSL (native Windows is planned) | A skill inside Claude Code; no daemon, no
|
|
22
|
+
| Runtime | External Python process plus a terminal multiplexer, tmux being the bundled default (the OpenCode profile runs over HTTP with no multiplexer window); Linux, macOS, or WSL (native Windows is planned) | A skill inside Claude Code; no daemon, no multiplexer, no session to attach to. Runs wherever Claude Code does, given Python 3.11+, `uv`, and `git`, and a Claude Code new enough for `/goal`, dynamic workflows, and Auto Memory, the three versions preflight pins and refuses to launch below. One optional exception: a ~900-line driver script that runs one session per story on long Epics |
|
|
23
23
|
| Control loop | Deterministic Python, no LLM in the loop | LLM-paced `/goal` spine with a deterministic completion gate |
|
|
24
24
|
| Agent / CLI | claude, codex, gemini, copilot, antigravity, opencode (mix per stage) | Claude Code only |
|
|
25
|
-
| Scope | Implementation phase: `backlog` and `ready-for-dev` stories through dev, review, verify, commit | Whole Epic: planning-readiness preflight, ATDD (acceptance-test-driven development) test generation, execute, TEA gate, finalize |
|
|
25
|
+
| Scope | Implementation phase: `backlog` and `ready-for-dev` stories from `sprint-status.yaml`, or opt-in from a typed `stories.yaml`, through dev, review, verify, commit | Whole Epic, six stages: ingest and scope, planning-readiness preflight, ATDD (acceptance-test-driven development) test generation, execute, TEA gate, finalize, whose terminal step is a workflow health check that the skill's own table numbers as a seventh stage |
|
|
26
26
|
| Completion authority | Checks on the spec and result artifacts, a proof-of-work diff, and your test and lint commands; opt-in TEA gate steps via a bundled plugin (advisory by default) | TEA quality gate: `gate-decision.json` (P0/P1/overall), combined in the default profile with NFR and test-review artifacts, read fail-closed by `gate_eval.py` |
|
|
27
27
|
| Test strategy | Your `[verify].commands` plus adversarial review hunters; opt-in TEA test-design and ATDD workflows via the bundled plugin | ATDD: acceptance criteria become executable red-phase tests driven to green; TEA traceability |
|
|
28
|
-
| Pre-launch gate | `validate
|
|
29
|
-
| Observability | A live terminal dashboard (built with Textual): runs table, attach to live sessions, journal, cost-weighted token totals | Files: `.decision-log.md`, a `run-status.json` heartbeat, a transcript ticker,
|
|
30
|
-
| Deferred work | A triage-and-execute **sweep** engine plus a decisions workflow |
|
|
31
|
-
| Escalation | Typed (CRITICAL / PREFERENCE) plus an interactive resolve agent | An escalate verdict
|
|
28
|
+
| Pre-launch gate | `validate`: 26 registered checks at v0.9.0 (BMAD config, policy, sprint-status, git, multiplexer and process host, CLI binary and profile, hook registration, base skills, stories-mode manifest and dispatch) | A mechanical preflight script plus a readiness check and a semantic scan that refuse to launch on an undecided product or architecture decision |
|
|
29
|
+
| Observability | A live terminal dashboard (built with Textual): runs table, attach to live sessions, journal, cost-weighted token totals, an active-agent indicator naming what is driving the current stage, plus schema-versioned `--json` documents for scripted readers | Files plus a read-only renderer: `.decision-log.md`, a `run-status.json` heartbeat on the sequential spine (the `--parallel` fan-out uses the `/workflows` view instead and writes no heartbeat), a transcript ticker that prints each gate verdict, a `gate-trail.md` evidence trail at finalize, and `/ucg-status` to assemble all of it on demand |
|
|
30
|
+
| Deferred work | A triage-and-execute **sweep** engine plus a decisions workflow | A ledger the gate only appends to, surfaced at finalize and readable mid-run through `/ucg-status`, with `/ucg-resolve` able to mark an answered decision row resolved; no execute engine |
|
|
31
|
+
| Escalation | Typed (CRITICAL / PREFERENCE) plus an interactive resolve agent that re-arms the spec and re-applies the saved patch, so review resumes on the restored diff | An `escalate` verdict, a typed `escalation-<story-id>.json` sidecar (`source`, `kind`, `decision_needed`, `evidence`), an `on_escalation` hook, a path-pinned `run-result.json` for every headless terminal exit that got far enough to resolve its artifacts path, not only blocked ones, and `/ucg-resolve` to answer what is pending; resume from the decision log |
|
|
32
32
|
| Isolation | In place by default; opt-in git worktree per story or bundle, merged back locally | None by default (stories run sequentially in one session); an experimental `--parallel` mode fans stories out into git worktrees |
|
|
33
|
-
| Extensibility | A plugin system (observe, veto, mutate) with bundled TEA and Unity plugins | `customize.toml` knobs
|
|
33
|
+
| Extensibility | A plugin system (observe, veto, mutate) with bundled TEA and Unity plugins | `customize.toml` knobs, planning-shaping fragments, and two optional third-party integrations configured there, both off by default and neither able to touch a gate verdict: [claude-mem recall](./cross-session-recall.md) and a [graphify knowledge-graph refresh](./knowledge-graph-refresh.md) |
|
|
34
34
|
| Self-improvement | Not shipped | A health check that files deduplicated GitHub issues about its own friction |
|
|
35
|
-
| Maturity | First-party (bmad-code-org); v0.9.0; rich docs; CI + test suite | Community module;
|
|
35
|
+
| Maturity | First-party (bmad-code-org); v0.9.0, whose headline is stable schema-versioned `--json` contracts that evolve additively; rich docs; CI + test suite | Community module; v1.0.0, which binds an already-stated contract (the headless envelope and `gate_eval.py`'s verdict vocabulary were covered at 0.x) under SemVer and adds `run-result.json` to it; docs site; CI + test suite |
|
|
36
36
|
| License | MIT | MIT |
|
|
37
37
|
|
|
38
38
|
## Where bmad-loop is stronger
|
|
@@ -41,8 +41,8 @@ This is a genuinely strong tool; pretending otherwise would make this page usele
|
|
|
41
41
|
|
|
42
42
|
1. **A deterministic control loop.** Story selection, retry budgets, gates, and completion checks are ordinary Python, so they are debuggable, reproducible, and cost no tokens. UCG's `/goal` pacing is LLM-driven; its deterministic pieces (the per-story and epic-level gate reads, the preflight scripts, the commit-guard and budget hooks) bound the loop rather than run it. If you want zero LLM judgment in the orchestration itself, bmad-loop is the cleaner model.
|
|
43
43
|
2. **Agent portability.** It drives claude, codex, gemini, GitHub Copilot CLI, antigravity, or OpenCode, and can run dev on one model and review on another via per-stage profiles. UCG is deliberately Claude Code only.
|
|
44
|
-
3. **Observability and control.** A live terminal UI (built with Textual) gives you a runs dashboard, a sprint tree, the deferred-work ledger, per-story token totals, attach-to-session, and a policy editor. UCG's window
|
|
45
|
-
4. **A deferred-work engine, not just a ledger.** `bmad-loop sweep` triages the ledger against the real code, bundles cohesive work, executes it, and has a decisions workflow for the human calls. UCG appends to a ledger
|
|
44
|
+
3. **Observability and control.** A live terminal UI (built with Textual) gives you a runs dashboard, a sprint tree, the deferred-work ledger, per-story token totals, attach-to-session, and a policy editor. UCG's window is files, the transcript, and a read-only `/ucg-status` render assembled from those same files: there is still no live view and no session to attach to.
|
|
45
|
+
4. **A deferred-work engine, not just a ledger.** `bmad-loop sweep` triages the ledger against the real code, bundles cohesive work, executes it, and has a decisions workflow for the human calls. UCG appends to a ledger, surfaces it at the end, and can render it mid-run through `/ucg-status`; acting on it is still manual, and there is no execute engine.
|
|
46
46
|
5. **Extensibility and reach.** It has a real plugin system (observe, veto, mutate the cycle) with bundled plugins: a TEA plugin that can add Test Architect workflows to its pipeline, and a Unity game-engine integration. UCG exposes configuration knobs, not a plugin API.
|
|
47
47
|
6. **Operational maturity.** It ships disk reclamation (clean and archive, retention windows, worktree teardown), cost-weighted token budgets that discount cache reads, and an adapter-authoring path for new CLIs, and it carries the backing of the bmad-code-org org.
|
|
48
48
|
|
|
@@ -51,27 +51,28 @@ This is a genuinely strong tool; pretending otherwise would make this page usele
|
|
|
51
51
|
1. **The TEA gate is the default, binding completion authority, not an opt-in layer.** UCG's completion authority is the Test Architect's gate: a traceability matrix that holds acceptance criteria to hard thresholds (P0 coverage at 100%, P1 at 90% or above, overall at 80% or above). UCG's default profile combines that verdict with an NFR (non-functional requirements) assessment and a test-review score, and `gate_eval.py` reads the result fail-closed: a missing or unreadable signal downgrades the verdict, never upgrades it. Since v0.5.0 the default sequential path also re-runs the full test, lint, and build suite on each story's committed HEAD before advancing, so a story that is green pre-commit but red once its new files are tracked cannot slip through to the gate.
|
|
52
52
|
|
|
53
53
|
bmad-loop can reach similar territory, but differently. Its default gate is checks on the spec and result artifacts, a proof-of-work diff (the commit must contain real changes since the story's baseline), and your test and lint commands; its bundled TEA plugin can add trace, NFR, and test-review steps before every commit. That plugin is opt-in, its gate steps ship advisory (non-blocking), and they fail open when an artifact is missing or unparseable. That gap narrowed in v0.9.0: at v0.8.1 bmad-loop's independent baseline-commit cross-check could not actually fire, because it read a spec key the dev skill does not write, so a spec claiming a stale or foreign baseline sailed through; v0.9.0 fixed it to accept either key and re-cut the test fixture that had been fabricating the missing one. The advisory-by-default and fail-open-on-missing-artifact properties of the TEA plugin's gate steps are unchanged. If you want acceptance-criterion-to-test traceability enforced by default, fail-closed, with nothing to configure, that is UCG's defining bet.
|
|
54
|
-
2. **ATDD-first.** UCG turns each story's acceptance criteria into executable acceptance tests (scaffolded as red-phase `test.skip` placeholders) before any code is written, then un-skips them and drives them to green. The acceptance tests are a first-class generated artifact, not a by-product. One scope note: TEA
|
|
55
|
-
3. **A planning-readiness gate that can refuse to launch.** UCG's preflight hands the PRD, the architecture, and the stories to a throwaway subagent that hunts for undecided product or architecture decisions, contradictions between the PRD and the architecture, and any story whose "done" cannot be pinned down. The scan grades what it finds, and any RED verdict stops the run rather than letting an unattended agent guess. That scan is itself LLM judgment, the very thing bmad-loop keeps out of its loop; the difference is that it can only block a launch, never pass one
|
|
56
|
-
4. **Almost no moving parts outside the agent.**
|
|
54
|
+
2. **ATDD-first.** UCG turns each story's acceptance criteria into executable acceptance tests (scaffolded as red-phase `test.skip` placeholders) before any code is written, then un-skips them and drives them to green. The acceptance tests are a first-class generated artifact, not a by-product. One scope note, about what the generator *emits* rather than what it accepts: the TEA release installed here does detect a backend stack, but its scaffolds are Playwright and TypeScript, and the browser-recording path loads only for a frontend or fullstack project, so a stack with no JS or TS harness still gets nothing runnable. UCG's preflight therefore steers those runs to `--light`, where the story's acceptance criteria (not generated tests) are the trace oracle, or you author the acceptance tests in the stack's own harness. bmad-loop's default pipeline relies on whatever tests the dev skill writes while implementing, plus the test commands you supply; TEA test generation exists there only as an opt-in plugin step that runs after dev, not as the default path.
|
|
55
|
+
3. **A planning-readiness gate that can refuse to launch.** UCG's preflight hands the PRD, the architecture, and the stories to a throwaway subagent that hunts for undecided product or architecture decisions, contradictions between the PRD and the architecture, and any story whose "done" cannot be pinned down. The scan grades what it finds, and any RED verdict stops the run rather than letting an unattended agent guess; the one way past a RED is an operator recording a `close` for it, since a `defer` does not clear one and an unreadable decisions file clears nothing. That scan is itself LLM judgment, the very thing bmad-loop keeps out of its loop; the difference is that it can only block a launch, never pass one, and the readiness kernel beside it is deterministic (v1.0.0 closed three fail-opens there, where an Epic with no stories, a story with no acceptance criteria, and a partially seeded story set each used to score `ready`). bmad-loop's preflight is mechanical and assumes the sprint's stories are already ready to build.
|
|
56
|
+
4. **Almost no moving parts outside the agent.** The autonomous run is a skill: no daemon, no multiplexer, no session to attach to. For a Claude Code user that is a smaller operational surface, and it is also exactly why UCG cannot run anywhere else. Two qualifiers, added honestly. Three companion skills ship alongside the run and none is required by one: `ucg-formalize` (the standalone readiness gate), `ucg-status` (the read-only run view), and `ucg-resolve` (the decide-surface for a stopped run). And a long Epic accumulates every story's transcript in one session, so UCG ships an optional driver script that spawns one `claude -p` per story; use it and you are running a loop outside the agent after all, which is bmad-loop's model in miniature. The difference is that it is opt-in and about 900 lines, where bmad-loop's orchestrator is the product; skip it and the skill still runs standalone, since `--max-stories` is a flag on the skill rather than something the script provides.
|
|
57
57
|
5. **A self-improvement loop.** UCG's finalize step can file deduplicated GitHub issues about friction in its own workflow, so the tool reports its own rough edges.
|
|
58
58
|
|
|
59
59
|
## What they share
|
|
60
60
|
|
|
61
|
-
- A deterministic completion authority the model cannot talk its way past: bmad-loop's artifact, diff, and command checks; UCG's TEA gate read (on
|
|
62
|
-
-
|
|
63
|
-
-
|
|
61
|
+
- A deterministic completion authority the model cannot talk its way past: bmad-loop's artifact, diff, and command checks; UCG's TEA gate read (on a non-web stack, under either profile, the trace artifacts are agent-authored under strict honesty rules, so the guarantee there is procedural rather than mechanical).
|
|
62
|
+
- Proof that the commit is real work, not a claim about work. bmad-loop cross-checks the diff against the story's baseline commit; UCG enforces the equivalent one layer down, in a `PreToolUse` hook that denies the `git commit` outright unless a tests-ran marker exists whose recorded baseline SHA matches the story's character for character, and unless the staged index is non-empty. On a production run it also refuses a commit whose staged acceptance tests are still skipped, though that check reads `test.skip(` and so does nothing on the non-web stacks the ATDD note above steers to `--light`.
|
|
63
|
+
- Fresh-context review separated from implementation, to kill self-review anchoring bias, on both defaults with a caveat each: bmad-loop's separate session is gated by `review.trigger`, which defaults to `recommended` (set it to `always` for every story), and UCG runs a code-review pass on its production profile but none under `--light`.
|
|
64
|
+
- Adversarial review passes, bounded so they cannot oscillate forever: bmad-loop by `max_review_cycles` (default 3), UCG by `max_turns_per_story`, where a re-loop that would exceed the budget escalates instead.
|
|
64
65
|
- Optional git worktree isolation.
|
|
65
|
-
- Resumable runs with a per-story budget: bmad-loop's is a cost-weighted token ceiling that discounts cache reads; UCG's is a turn cap, encoded in the `/goal` condition and enforced at the gate
|
|
66
|
-
- `sprint-status.yaml` as planning
|
|
66
|
+
- Resumable runs with a per-story budget: bmad-loop's is a cost-weighted token ceiling that discounts cache reads; UCG's is a turn cap, encoded in the `/goal` condition and enforced at the gate. UCG adds a second axis, `--max-stories N`, a per-invocation work bound whose exhaustion still ends the run `complete` with stories remaining, so that status means "this invocation finished", not "the Epic is done". Note the asymmetry: UCG has no token or cost bound at all, and `story_token_budget` is now a deprecated no-op.
|
|
67
|
+
- `sprint-status.yaml` as the shared planning ledger, and both build on BMAD-METHOD. Neither leaves it write-only to the BMAD skills any more: UCG's gate writes the story's `done` row at the `advance` route, and bmad-loop's orchestrator syncs the board itself.
|
|
67
68
|
|
|
68
69
|
## Which to reach for
|
|
69
70
|
|
|
70
71
|
Choose **bmad-loop** if you use codex, gemini, or GitHub Copilot CLI (or want to mix models per stage), you want a code-only orchestrator you can step through and debug, you want a live dashboard and attach-to-session control, you have a backlog of deferred work to triage and sweep, you need plugin extensibility or game-engine support, or you prefer a first-party tool maintained under the bmad-code-org org.
|
|
71
72
|
|
|
72
|
-
Choose **UCG** if you are on Claude Code and any of these fit: you want the Test Architect's gate as the default, binding, fail-closed completion authority (every P0 criterion traced to a passing test, with P1 at 90% or above and overall at 80% or above) rather than an opt-in layer; you want acceptance criteria compiled into executable tests up front; you want a run that refuses to start while a product or architecture decision is still undecided; or you want a single skill with
|
|
73
|
+
Choose **UCG** if you are on Claude Code and any of these fit: you want the Test Architect's gate as the default, binding, fail-closed completion authority (every P0 criterion traced to a passing test, with P1 at 90% or above and overall at 80% or above) rather than an opt-in layer; you want acceptance criteria compiled into executable tests up front; you want a run that refuses to start while a product or architecture decision is still undecided; or you want the autonomous run itself to be a single skill with no daemon and no session to attach to (the three optional companion skills and the per-story driver above are all opt-in, and a run needs none of them).
|
|
73
74
|
|
|
74
|
-
They are not mutually exclusive. Both read the same `sprint-status.yaml` and BMAD artifacts, so
|
|
75
|
+
They are not mutually exclusive. Both read the same `sprint-status.yaml` and BMAD artifacts, so an Epic planned and gated UCG's way is a board bmad-loop can pick up. Their deferred-work ledgers are not interchangeable, though: they share the path but not the schema, since `bmad-loop sweep` parses `### DW-<n>:` sections and UCG never writes one, so a sweep will not see UCG's parked rows.
|
|
75
76
|
|
|
76
77
|
## Verify this yourself
|
|
77
78
|
|
|
@@ -80,4 +81,4 @@ Both tools change weekly, so re-check before you rely on anything above:
|
|
|
80
81
|
- bmad-loop: its [README](https://github.com/bmad-code-org/bmad-loop), [docs/FEATURES.md](https://github.com/bmad-code-org/bmad-loop/blob/main/docs/FEATURES.md), and [docs/ROADMAP.md](https://github.com/bmad-code-org/bmad-loop/blob/main/docs/ROADMAP.md).
|
|
81
82
|
- UCG: [How It Works](./how-it-works.md) and the [Gate Model](./gate-model.md).
|
|
82
83
|
|
|
83
|
-
This snapshot was re-cut on 2026-07-28 against bmad-loop v0.9.0 (released 2026-07-21) and UCG
|
|
84
|
+
This snapshot was re-cut on 2026-07-28 against bmad-loop v0.9.0 (released 2026-07-21) and UCG v1.0.0 (released 2026-07-28); the previous cut (2026-07-12) read bmad-loop v0.8.1 and UCG v0.5.1, and the one before it (2026-06-28, bmad-auto v0.7.4 and UCG v0.4.0) predates the rename.
|
|
@@ -62,7 +62,7 @@ What it honestly does **not** do:
|
|
|
62
62
|
|
|
63
63
|
## Turning it on
|
|
64
64
|
|
|
65
|
-
Set the knob in your project's `_bmad/custom/ultracode-goal.toml
|
|
65
|
+
Set the knob in your project's `_bmad/custom/ultracode-goal.toml`. **No installer creates that file**, so on most projects you are creating it: `_bmad/custom/` exists already, but the `config.toml` sitting in it belongs to BMAD's own configuration, and putting a UCG knob there does nothing.
|
|
66
66
|
|
|
67
67
|
```toml
|
|
68
68
|
[workflow]
|
package/docs/getting-started.md
CHANGED
|
@@ -13,7 +13,7 @@ UltraCode Goal conducts BMAD and TEA skills and runs deterministic Python under
|
|
|
13
13
|
|------|--------------|---------|
|
|
14
14
|
| Claude Code | **The runtime: non-negotiable.** UCG composes `/goal`, Auto Mode, Auto Memory, and runtime hooks, which only exist in Claude Code; the autonomous run cannot execute anywhere else | <https://claude.com/product/claude-code> |
|
|
15
15
|
| Node.js >= 22 | Installation, `npx` commands | <https://nodejs.org> |
|
|
16
|
-
| Python >= 3.
|
|
16
|
+
| Python >= 3.11 | The deterministic gate, preflight, and hook scripts (run via `uv`) | <https://www.python.org> |
|
|
17
17
|
| `uv` | Running the module's Python scripts with automatic dependency management | <https://docs.astral.sh/uv/> |
|
|
18
18
|
| `git` | Epic-branch isolation and per-story commits (the real rollback) | <https://git-scm.com> |
|
|
19
19
|
| `gh` (GitHub CLI) | Submitting or queuing [health-check](./health-check.md) findings | <https://cli.github.com> |
|
package/docs/how-it-works.md
CHANGED
|
@@ -109,7 +109,7 @@ The production AND fails closed: a missing or unparseable `nfr-assessment.md` or
|
|
|
109
109
|
|
|
110
110
|
### Stage 6: Finalize
|
|
111
111
|
|
|
112
|
-
Make the run pay off for the next one. Capture learnings deliberately: machine-local quirks to Auto Memory (`remember X`), team standards to the project's CLAUDE.md or `.claude/rules`. Optionally run the retrospective (`--retro`). Audit every `.decision-log.md` entry into the report, the addendum, or explicit process-noise. Produce a `run-report.md` (Epic, profile, per-story outcomes, the Epic-level gate, budget consumed, learnings, a pointer to the ledger), write the terminal `run-status.json`, surface this Epic's deferred-work ledger heading to the user, and fire the `on_epic_complete` hook **only** when the Epic actually advanced. See [`references/finalize.md`](https://github.com/armelhbobdad/bmad-module-ultracode-goal/blob/main/skills/ultracode-goal/references/finalize.md).
|
|
112
|
+
Make the run pay off for the next one. Capture learnings deliberately: machine-local quirks to Auto Memory (`remember X`), team standards to the project's CLAUDE.md or `.claude/rules`. Optionally run the retrospective (`--retro`). Audit every `.decision-log.md` entry into the report, the addendum, or explicit process-noise. Produce a `run-report.md` (Epic, profile, per-story outcomes, the Epic-level gate, budget consumed, learnings, a pointer to the ledger), write the terminal `run-status.json`, surface this Epic's deferred-work ledger heading to the user, and fire the `on_epic_complete` hook **only** when the Epic actually advanced. One optional step also lives here and is off by default: the [knowledge-graph refresh](./knowledge-graph-refresh.md). See [`references/finalize.md`](https://github.com/armelhbobdad/bmad-module-ultracode-goal/blob/main/skills/ultracode-goal/references/finalize.md).
|
|
113
113
|
|
|
114
114
|
## Production vs. `--light`
|
|
115
115
|
|
package/docs/index.md
CHANGED
|
@@ -63,5 +63,6 @@ The docs split into three buckets: **Why** (start here), **Try** (do stuff), and
|
|
|
63
63
|
- [Gate Model](./gate-model.md): how `gate_eval.py` maps `gate_status` to a verdict, the thresholds, and the fail-closed contract.
|
|
64
64
|
- [Health Check](./health-check.md): the terminal self-improvement reflection: what it sends, the privacy model, and how to disable it.
|
|
65
65
|
- [Cross-Session Recall](./cross-session-recall.md): the optional claude-mem integration and its trust model.
|
|
66
|
+
- [Knowledge-Graph Refresh](./knowledge-graph-refresh.md): the optional graphify integration, its preconditions, and what it sends where.
|
|
66
67
|
- [Troubleshooting](./troubleshooting.md): real failure modes and their remediations.
|
|
67
68
|
- [UCG vs bmad-loop](./comparison.md): a side-by-side comparison with bmad-code-org's bmad-loop orchestrator (formerly bmad-auto).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Knowledge-Graph Refresh
|
|
3
|
+
description: The optional graphify integration - UCG refreshes your project's knowledge graph as a run exits, so the next session starts from a current graph. Opt-in, advisory, never in the gate path, off by default.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Optional, opt-in, off by default.** The refresh is one time-boxed call on the way out of a run. It can add an artifact to your machine, and it can change nothing else: not the gate verdict, not the recorded run-status, not the headless envelope. When it is off, or when the [graphify](https://github.com/Graphify-Labs/graphify) CLI is absent, the run is byte-for-byte the same as a run without it.
|
|
7
|
+
|
|
8
|
+
## What it does
|
|
9
|
+
|
|
10
|
+
A knowledge graph of your codebase goes stale the moment a run lands eight stories of new code and the documents that came with them, which is exactly what a UCG run produces. With `graphify_integration = "refresh"`, Stage 6 Finalize spends one incremental, local rebuild, so the next session starts from a current picture instead of a stale one. It refreshes what can be parsed and leaves what needs a model alone; [what it runs](#what-it-runs-and-where-it-writes) draws that line precisely.
|
|
11
|
+
|
|
12
|
+
Finalize is the only call site. No preflight step, no per-story step, and nothing in the gate path calls graphify or reads its output. See [how it works](./how-it-works.md) for where Stage 6 sits.
|
|
13
|
+
|
|
14
|
+
## What you need
|
|
15
|
+
|
|
16
|
+
The third-party [graphify](https://github.com/Graphify-Labs/graphify) CLI, whose package name is not its command name:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv tool install graphifyy # or: pipx install graphifyy. The command is `graphify`.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> graphify is a third-party tool maintained independently of this module. We don't bundle, endorse, or install it; the refresh simply uses it when you already have it.
|
|
23
|
+
|
|
24
|
+
You also need a graph to refresh, since this step updates one and never builds one. Build it once yourself (`graphify .`, which is the full pipeline and does use an LLM backend), and the run keeps its parsed layer current after that.
|
|
25
|
+
|
|
26
|
+
## Turning it on
|
|
27
|
+
|
|
28
|
+
Set the knob in your project's `_bmad/custom/ultracode-goal.toml`. **No installer creates that file**, so on most projects you are creating it: `_bmad/custom/` exists already, but the `config.toml` sitting in it belongs to BMAD's own configuration, and putting a UCG knob there does nothing.
|
|
29
|
+
|
|
30
|
+
```toml
|
|
31
|
+
[workflow]
|
|
32
|
+
# Knowledge-graph refresh: one incremental rebuild as the run exits.
|
|
33
|
+
# Needs the graphify CLI and an existing graphify-out/. Advisory, never gates.
|
|
34
|
+
graphify_integration = "refresh"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `[workflow]` table header matters: the resolver extracts the `workflow` block from the merged files, so a bare top-level `graphify_integration` line is silently discarded and the feature stays off.
|
|
38
|
+
|
|
39
|
+
## Three things to know before you turn it on
|
|
40
|
+
|
|
41
|
+
- **The values are `off` and `refresh`, not `on` and `off`.** `cross_session_recall` sits directly above it in the shipped file and takes `on`, so copying that shape here produces `"on"`, which is not a legal value and leaves the step off.
|
|
42
|
+
- **A first-ever enable does nothing, deliberately.** Two preconditions are both required: `graphify` resolves on `PATH`, and a `graphify-out/graph.json` already exists under the project root to update. Refresh means refresh: with no graph there is nothing to update, and building one from nothing walks the whole corpus, which is not something a bounded exit step may do. Build the graph once yourself, and the run keeps its parsed layer current from then on.
|
|
43
|
+
- **Absence is silent, failure is logged.** When either precondition is missing, the run is byte-identical to an `off` run: no probe output, no decision-log line, nothing. When the pass does run and then fails or exceeds its 300 second time box, Finalize logs one `WARN graphify-refresh-failed` line to `.decision-log.md` and moves on. It is never retried.
|
|
44
|
+
|
|
45
|
+
## What it runs, and where it writes
|
|
46
|
+
|
|
47
|
+
The delegation is exactly one command, `graphify update .`, time-boxed to 300 seconds and never retried. That subcommand re-extracts the graph's **parsed layer** against what is on disk, using tree-sitter: **no LLM call, no API key, no network request, no token spend** at the end of a run you were not watching.
|
|
48
|
+
|
|
49
|
+
The parsed layer is everything graphify has an extractor for: your source code, plus the Markdown family (`.md`, `.mdx`, `.qmd`, `.skill`). So an Epic's new modules and the story and documentation files it wrote are both picked up. What stays as the last full build left it is the **semantic** layer: images, PDFs and papers, and anything an LLM derived from a document. That pass is the one that would send your files to a model provider and spend your API budget, which is exactly what an unattended exit step should not decide to do. Run it yourself, on your own terms, when you want it.
|
|
50
|
+
|
|
51
|
+
One behaviour worth knowing, because it is the opposite of what people expect:
|
|
52
|
+
|
|
53
|
+
- **Deleting code shrinks the graph, and nothing warns.** That is correct: the rebuild accounts for sources that are gone and writes the smaller graph, exit 0.
|
|
54
|
+
- **What graphify refuses is an unexplained loss**, where nodes vanish while their source is still sitting on disk. An Epic that adds a `.gitignore` rule, or otherwise narrows what gets scanned, produces exactly that. Then graphify declines the write, exits non-zero, and you get a `WARN graphify-refresh-failed` line with the graph left intact. Whether to re-run `graphify update . --force` is a decision the run does not make for you.
|
|
55
|
+
|
|
56
|
+
The output is a `graphify-out/` directory at your project root, not in the run folder, so it is not part of the run's evidence and nothing in the gate path reads it. It regenerates on every refresh and holds a `graph.json`, a `graph.html`, a report, and a cache, so **add `graphify-out/` to your `.gitignore`**: UCG commits each green story, and an untracked-but-not-ignored tree at the repo root is exactly what a story commit should never sweep up.
|
|
57
|
+
|
|
58
|
+
## What it never touches
|
|
59
|
+
|
|
60
|
+
The refresh is advisory in the same sense [Cross-Session Recall](./cross-session-recall.md) is, and the two are independent: either can be on without the other.
|
|
61
|
+
|
|
62
|
+
- The **gate verdict** is `gate_eval.py` reading TEA's `gate-decision.json`, and only that. See the [gate model](./gate-model.md).
|
|
63
|
+
- The **recorded run-status** and the **headless envelope** are identical whether the refresh ran, failed, or never fired.
|
|
64
|
+
- A graphify failure or timeout **never** blocks, re-loops, or escalates a story, and never changes a run's `complete` / `blocked` / `partial-complete` outcome.
|
|
65
|
+
|
|
66
|
+
Verified against graphify 0.9.26 on 2026-07-28. It is a pre-1.0 tool whose CLI surface moves; if the install name, the command name, or the output layout above no longer match what you have, trust `graphify --help`.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "bmad-module-ultracode-goal",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.1",
|
|
5
5
|
"description": "BMAD module — Run a BMAD Epic autonomously to a machine-checked, TEA-gated Definition-of-Done.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"bmad",
|
|
@@ -75,8 +75,7 @@ cross_session_recall = "off"
|
|
|
75
75
|
|
|
76
76
|
# --- Knowledge-graph refresh (optional; runs at Finalize only) ---
|
|
77
77
|
# Advisory only, never gates. Requires the third-party graphify CLI on PATH and
|
|
78
|
-
# a prior graphify-out/
|
|
79
|
-
# without either. "off" = never touch it | "refresh" = one incremental,
|
|
78
|
+
# a prior graphify-out/graph.json to update; silently inactive without either. "off" = never touch it | "refresh" = one incremental,
|
|
80
79
|
# time-boxed rebuild as the run exits, so the next session starts from a
|
|
81
80
|
# current graph rather than a stale one. Finalize is the only call site: no
|
|
82
81
|
# preflight step, no per-story step, and no effect on any gate verdict, the
|
|
@@ -81,17 +81,21 @@ Resolve the mode exactly as the hooks below resolve theirs:
|
|
|
81
81
|
|
|
82
82
|
Two values, and no others. `off` is the shipped default and a complete no-op — no probe, no delegation, no decision-log line, no output; there is nothing to read further in this section. `refresh` refreshes the project's knowledge graph on the way out, so the next session starts from a current one instead of a stale one.
|
|
83
83
|
|
|
84
|
-
**Probe first, and degrade to silence.** Two preconditions, both required: graphify resolves on PATH (`command -v graphify`), and a prior `graphify-out/
|
|
84
|
+
**Probe first, and degrade to silence.** Two preconditions, both required: graphify resolves on PATH (`command -v graphify`), and a prior `graphify-out/graph.json` exists under `{project-root}` to update. If either is missing there is nothing to refresh — do nothing, print nothing, and write no `.decision-log.md` entry, so the run stays byte-identical to an `off` run. A "skipped it" log line is exactly the difference that would break that, so do not add one. Absence is silent; failure is logged. They are different events.
|
|
85
85
|
|
|
86
|
-
The
|
|
86
|
+
The graph precondition is not defensive padding. Refresh means refresh: with no graph there is nothing to update, and building one from nothing walks the whole corpus, which is the opposite of what a bounded step on the way out may do. A first-ever run in this mode therefore refreshes nothing and says nothing.
|
|
87
87
|
|
|
88
88
|
**With both preconditions met, delegate one incremental rebuild from `{project-root}`** — graphify writes `graphify-out/` relative to the current working directory:
|
|
89
89
|
|
|
90
90
|
```
|
|
91
|
-
timeout 300 graphify .
|
|
91
|
+
timeout 300 graphify update .
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
`graphify update` is the subcommand that re-extracts the graph's **parsed layer** against what is on disk, with no LLM call: no API key, no network, no token spend at the end of an unattended run. Never a cold full build. That layer is everything graphify has a tree-sitter extractor for, which is the source code plus the Markdown family (`.md`, `.mdx`, `.qmd`, `.skill`), so an Epic's new modules *and* the story and doc files it wrote are both picked up. What it does not run is the semantic pass: images, PDFs and papers, and any LLM-derived layer over a document, stay as the last full build left them, because that path spends API budget and a bounded exit step may not take it unattended.
|
|
95
|
+
|
|
96
|
+
Deleting code shrinks the graph, and that is the correct outcome, not a failure: the rebuild accounts for sources that are gone from disk and writes the smaller graph, exit 0, no `WARN`. What graphify refuses is an **unexplained** loss, where nodes disappear but their source is still on disk, which is what an Epic that adds a `.gitignore` rule or otherwise narrows the scan corpus produces. That refusal exits non-zero, so the `WARN` below records it and the graph is left untouched; whether to re-run with `--force` is a decision this step does not get to make.
|
|
97
|
+
|
|
98
|
+
Pass no other flags. Unlike `graphify extract`, this subcommand rejects an unknown option with a usage error instead of ignoring it, so a flag that stops being real fails loudly here rather than silently doing nothing.
|
|
95
99
|
|
|
96
100
|
The delegation is hard time-boxed by the `timeout 300` prefix above and is **not retried**. On a non-zero exit or a timeout, log one `WARN graphify-refresh-failed` line to `.decision-log.md` and move on.
|
|
97
101
|
|
package/website/astro.config.mjs
CHANGED
|
@@ -121,6 +121,7 @@ export default defineConfig({
|
|
|
121
121
|
{ label: 'Gate Model', slug: 'gate-model' },
|
|
122
122
|
{ label: 'Health Check', slug: 'health-check' },
|
|
123
123
|
{ label: 'Cross-Session Recall', slug: 'cross-session-recall' },
|
|
124
|
+
{ label: 'Knowledge-Graph Refresh', slug: 'knowledge-graph-refresh' },
|
|
124
125
|
{ label: 'Troubleshooting', slug: 'troubleshooting' },
|
|
125
126
|
{ label: 'UCG vs bmad-loop', slug: 'comparison' },
|
|
126
127
|
],
|