bmad-module-ultracode-goal 0.1.1-alpha.0 → 0.2.0

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.
Files changed (45) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +33 -1
  3. package/docs/404.md +23 -0
  4. package/docs/_internal/RELEASING.md +32 -3
  5. package/docs/_internal/STABILITY.md +17 -1
  6. package/docs/architecture.md +71 -1
  7. package/docs/cross-session-recall.md +107 -0
  8. package/docs/gate-model.md +43 -1
  9. package/docs/getting-started.md +30 -1
  10. package/docs/health-check.md +42 -1
  11. package/docs/how-it-works.md +67 -1
  12. package/docs/index.md +57 -16
  13. package/docs/parallel-mode.md +36 -1
  14. package/docs/troubleshooting.md +42 -1
  15. package/docs/why-ultracode-goal.md +46 -1
  16. package/package.json +4 -1
  17. package/skills/ultracode-goal/SKILL.md +1 -0
  18. package/skills/ultracode-goal/customize.toml +5 -0
  19. package/skills/ultracode-goal/references/finalize.md +26 -1
  20. package/skills/ultracode-goal/references/ingest-and-scope.md +33 -0
  21. package/skills/ultracode-goal/references/preflight.md +3 -0
  22. package/skills/ultracode-goal/scripts/hooks/guard_pretooluse.py +158 -2
  23. package/skills/ultracode-goal/scripts/mem_common.py +366 -0
  24. package/skills/ultracode-goal/scripts/mem_observation.py +423 -0
  25. package/skills/ultracode-goal/scripts/mem_recall.py +537 -0
  26. package/tools/build-docs.js +326 -0
  27. package/tools/cli/lib/ui.js +55 -12
  28. package/website/README.md +92 -0
  29. package/website/astro.config.mjs +148 -0
  30. package/website/package-lock.json +8454 -0
  31. package/website/package.json +26 -0
  32. package/website/public/favicon.svg +13 -0
  33. package/website/public/img/ucg-logo.svg +73 -0
  34. package/website/public/js/mermaid-lightbox.js +67 -0
  35. package/website/public/robots.txt +36 -0
  36. package/website/src/components/Banner.astro +82 -0
  37. package/website/src/components/Header.astro +146 -0
  38. package/website/src/components/MobileMenuFooter.astro +69 -0
  39. package/website/src/content/config.ts +6 -0
  40. package/website/src/lib/site-url.js +28 -0
  41. package/website/src/pages/404.astro +11 -0
  42. package/website/src/rehype-base-paths.js +83 -0
  43. package/website/src/rehype-markdown-links.js +112 -0
  44. package/website/src/styles/custom.css +674 -0
  45. package/website/tsconfig.json +9 -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": "0.1.1-alpha.0",
22
+ "version": "0.2.0",
23
23
  "author": {
24
24
  "name": "Armel"
25
25
  },
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  [![BMAD Module](https://img.shields.io/badge/BMAD-module-blue)](https://github.com/bmad-code-org/BMAD-METHOD)
14
14
  [![Python Version](https://img.shields.io/badge/python-%3E%3D3.10-blue?logo=python&logoColor=white)](https://www.python.org)
15
15
  [![uv](https://img.shields.io/badge/uv-package%20manager-blueviolet?logo=uv)](https://docs.astral.sh/uv/)
16
- [![Docs](https://img.shields.io/badge/docs-online-green)](./docs/index.md)
16
+ [![Docs](https://img.shields.io/badge/docs-online-green)](https://armelhbobdad.github.io/bmad-module-ultracode-goal/)
17
17
  [![GitHub stars](https://img.shields.io/github/stars/armelhbobdad/bmad-module-ultracode-goal?style=social)](https://github.com/armelhbobdad/bmad-module-ultracode-goal/stargazers)
18
18
 
19
19
  **Built for [Claude Code](https://www.anthropic.com/claude-code) — and only Claude Code.** UCG composes `/goal`, Auto Mode, Auto Memory, and runtime hooks, which exist nowhere else. Other editors can hold the skill files; the autonomous run itself requires Claude Code.
@@ -120,6 +120,24 @@ UCG runs six stages in order, each routing by the testable conditions stated in
120
120
  5. **Gate** — `gate_eval.py` reads TEA's verdict and routes: advance / defer / reloop / escalate.
121
121
  6. **Finalize** — Auto Memory capture, optional retrospective, decision-log audit, run report.
122
122
 
123
+ The run is a straight line until the gate, which branches — and a `reloop` sends the story back through Execute within budget, while an unresolved blocker stops the run rather than guessing:
124
+
125
+ ```mermaid
126
+ flowchart TD
127
+ I["Stage 1 Ingest and Scope"] --> P{"Stage 2 Preflight hard gate"}
128
+ P -->|"red blocker"| STOP["STOP / blocked"]
129
+ P -->|"budget 0, green"| D["Stage 3 Define Done"]
130
+ D --> X["Stage 4 Execute"]
131
+ X --> G{"Stage 5 gate_eval.py reads TEA verdict"}
132
+ G -->|"advance, PASS or WAIVED"| F["Stage 6 Finalize"]
133
+ G -->|"defer, CONCERNS"| L["Ledger then advance"]
134
+ L --> F
135
+ G -->|"reloop, FAIL or signal downgrade"| X
136
+ G -->|"escalate, NOT_EVALUATED or budget out"| STOP
137
+ classDef gate fill:#6366F1,stroke:#4F46E5,color:#fff
138
+ class P,G gate
139
+ ```
140
+
123
141
  Three enforcement layers keep the autonomy honest:
124
142
 
125
143
  - **Hooks are the invariants** — `PreToolUse` guards (no commit on a protected branch; no commit before tests ran for the story) live in `settings.local.json`, where the runtime enforces them, not in memory.
@@ -146,6 +164,19 @@ uv run skills/ultracode-goal/scripts/gate_eval.py \
146
164
 
147
165
  The JSON it prints is the same object UCG routes on — `verdict`, `gate_status`, and the `reasons` trail that explains how it got there. Nothing is hidden behind the model.
148
166
 
167
+ ## Optional: Cross-Session Recall
168
+
169
+ If you run claude-mem, this executor consults your past runs in this codebase before it scopes a new Epic and before its preflight gate — so it surfaces what bit you here last time instead of starting amnesiac. You stay in the driver's seat; it informs, it doesn't auto-decide.
170
+
171
+ Optional. Powered by claude-mem if installed; a silent no-op if not. It is advisory only — never in the gate path — and off by default. Enable it in `_bmad/custom/ultracode-goal.toml`:
172
+
173
+ ```toml
174
+ [workflow]
175
+ cross_session_recall = "on"
176
+ ```
177
+
178
+ See [Cross-Session Recall](./docs/cross-session-recall.md) for the touchpoints, the trust model, and the OFF-coherence disclosure.
179
+
149
180
  ## Help UCG Improve
150
181
 
151
182
  Every run that reaches Finalize ends with a self-improvement check. When it finds a defect in its own stage references, it can file a GitHub issue — deduplicated by a deterministic fingerprint so re-reporting is safe — with your approval. Headless runs queue findings to a machine-local cache instead of filing live. The fingerprint is install-mode-invariant, so the same defect maps to the same issue whether it surfaced in a dev checkout or an installed tree. **Please let runs finish through Finalize**, or [open an issue](https://github.com/armelhbobdad/bmad-module-ultracode-goal/issues/new/choose) directly. If UCG saved you an afternoon of babysitting, a ⭐ helps others find it.
@@ -169,6 +200,7 @@ The docs are organized into three buckets — **Why** (start here), **Try** (do
169
200
  - **[Architecture](./docs/architecture.md)** — the conductor model, enforcement layers in depth, and `customize.toml` resolution.
170
201
  - **[Gate Model](./docs/gate-model.md)** — how `gate_eval.py` maps `gate_status` to a verdict, and the production AND-signals.
171
202
  - **[Health Check](./docs/health-check.md)** — the terminal self-improvement loop: what it sends, privacy, and how to disable it.
203
+ - **[Cross-Session Recall](./docs/cross-session-recall.md)** — the optional claude-mem integration: touchpoints, trust model, and how to enable it.
172
204
  - **[Troubleshooting](./docs/troubleshooting.md)** — real failure modes and their remediations.
173
205
 
174
206
  ## Acknowledgements
package/docs/404.md ADDED
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: Page Not Found
3
+ description: That URL did not resolve. A path the docs cannot verify does not pass — use the search or the cited links below to continue.
4
+ template: splash
5
+ ---
6
+
7
+ ## 404 — this URL does not pass
8
+
9
+ No page resolves to that address. In the spirit of the rest of this project, a claim that cannot be verified does not get to advance — and that includes a URL the docs site made to itself.
10
+
11
+ Use the **search bar** at the top of the page, or jump to one of these pages that *do* resolve, grouped the way the sidebar groups them:
12
+
13
+ **Why** — [Why UltraCode Goal](./why-ultracode-goal.md)
14
+
15
+ **Try** — [Getting Started](./getting-started.md) · [How It Works](./how-it-works.md) · [Parallel Mode](./parallel-mode.md)
16
+
17
+ **Reference** — [Architecture](./architecture.md) · [Gate Model](./gate-model.md) · [Health Check](./health-check.md) · [Troubleshooting](./troubleshooting.md)
18
+
19
+ ---
20
+
21
+ ### Think this page should exist?
22
+
23
+ A missing page is drift — a link the docs made to themselves that no longer reads green. [Open an issue](https://github.com/armelhbobdad/bmad-module-ultracode-goal/issues/new/choose) with the URL you tried. The same instinct that makes UltraCode Goal re-loop on a failing gate applies here: if a broken path slipped through, it is a defect worth reporting.
@@ -1,4 +1,7 @@
1
- # Releasing
1
+ ---
2
+ title: Releasing
3
+ description: Maintainer runbook for cutting an UltraCode Goal release via the manual-dispatch, OIDC trusted-publishing release.yaml workflow.
4
+ ---
2
5
 
3
6
  Maintainer runbook for cutting a release of `bmad-module-ultracode-goal`. The canonical release path is [`.github/workflows/release.yaml`](../../.github/workflows/release.yaml) — manual dispatch, OIDC trusted publishing, no token secrets.
4
7
 
@@ -18,6 +21,30 @@ Dispatching `release.yaml` from `main` runs, in order:
18
21
 
19
22
  Dispatching from a non-`main` ref skips the PR flow: the tag anchors on the CI-ephemeral commit and `main` is not advanced. This is the expected path for prerelease cuts from feature branches.
20
23
 
24
+ How the dispatch ref forks the pipeline, and where the two paths rejoin to tag and publish:
25
+
26
+ ```mermaid
27
+ flowchart TD
28
+ D["Dispatch release.yaml"] --> P["Approve release environment"]
29
+ P --> Q["Quality gate, version bump, marketplace + CHANGELOG sync"]
30
+ Q --> DR["npm publish --dry-run"]
31
+ DR --> REF{"Dispatched from main?"}
32
+ REF -->|"yes"| BR["Push commit to temp branch, open bot PR"]
33
+ BR --> FT["Force-dispatch quality.yaml on temp branch"]
34
+ FT --> WC["Wait for required status checks"]
35
+ WC --> AUTH{"Approved or admin-merged?"}
36
+ AUTH -->|"maintainer approval"| AM["Auto-merge with merge commit"]
37
+ AUTH -->|"admin bypass-merge"| MG["Merged on main"]
38
+ AM --> MG
39
+ MG --> TAG["Tag vX.Y.Z on merge commit"]
40
+ REF -->|"no"| SKIP["Skip PR flow, anchor tag on CI-ephemeral commit"]
41
+ SKIP --> TAG
42
+ TAG --> PUB["npm publish via OIDC trusted publishing"]
43
+ PUB --> REL["Create GitHub Release"]
44
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
45
+ class REF,AUTH verdict
46
+ ```
47
+
21
48
  ## One-time setup
22
49
 
23
50
  These must exist before the first `main`-dispatch release. Order matters.
@@ -61,13 +88,15 @@ On [npmjs.com](https://www.npmjs.com/) → package settings → Trusted Publishe
61
88
 
62
89
  The workflow upgrades npm to ≥ 11.5.1 (the OIDC trusted-publishing floor) and pins `NPM_TOKEN: ""` on both publish steps so a stale runner-env token can never be picked up silently. Note: the very first publish of a brand-new package may need to be performed manually (`npm publish` with a granular token) before Trusted Publisher can be attached to the package — check current npm rules when cutting `0.1.0`.
63
90
 
64
- ### 5. Auto-merge repo setting
91
+ ### 5. Repo settings: auto-merge + Actions PR creation
65
92
 
66
93
  ```bash
67
94
  gh api --method PATCH /repos/armelhbobdad/bmad-module-ultracode-goal -f allow_auto_merge=true
95
+ gh api --method PUT /repos/armelhbobdad/bmad-module-ultracode-goal/actions/permissions/workflow \
96
+ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true
68
97
  ```
69
98
 
70
- Without it, `gh pr merge --auto` in the workflow fails.
99
+ Without `allow_auto_merge`, `gh pr merge --auto` in the workflow fails. Without `can_approve_pull_request_reviews` ("Allow GitHub Actions to create and approve pull requests" in Settings → Actions → General — **off by default**), the `Open bot PR` step fails with `GraphQL: GitHub Actions is not permitted to create or approve pull requests`. The workflow-level `permissions: pull-requests: write` declaration is necessary but NOT sufficient — this repo-level toggle gates it independently.
71
100
 
72
101
  ### 6. Health-check labels
73
102
 
@@ -1,4 +1,7 @@
1
- # Stability and Public Contract
1
+ ---
2
+ title: Stability and Public Contract
3
+ description: The 0.1.0 stability posture — which CLI, config, JSON, and gate surfaces are the supported public contract versus everything that is @internal and free to change.
4
+ ---
2
5
 
3
6
  > **Status:** 0.x — pre-1.0. The surfaces below are the intended public contract at `0.1.0`. Per [Semantic Versioning 2.0.0](https://semver.org/), a `0.x` series makes no stability guarantee across minor versions; this document records what we *try* to hold stable and what is explicitly `@internal`, so a consumer knows which surfaces to pin against and which to treat as free to change.
4
7
 
@@ -45,6 +48,19 @@ The skill name `ultracode-goal` and its documented invocation phrases — "run a
45
48
  - **CLI flags**: `--trace-output` (required), `--profile` (`light` | `production`, required), `--nfr`, `--test-review` (production only).
46
49
  - **Verdict vocabulary**: the `verdict` values `advance` / `defer` / `reloop` / `escalate`, and the `gate_status` values `PASS` / `CONCERNS` / `FAIL` / `WAIVED` / `NOT_EVALUATED`, plus the mapping between them. See the [gate model](../gate-model.md).
47
50
 
51
+ The contractual mapping each `gate_status` resolves to:
52
+
53
+ ```mermaid
54
+ flowchart LR
55
+ PASS["PASS"] --> ADV["advance"]
56
+ WAIVED["WAIVED"] --> ADV
57
+ CONCERNS["CONCERNS"] --> DEF["defer"]
58
+ FAIL["FAIL"] --> REL["reloop"]
59
+ NE["NOT_EVALUATED"] --> ESC["escalate"]
60
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
61
+ class ADV,DEF,REL,ESC verdict
62
+ ```
63
+
48
64
  The printed JSON object's key set (`verdict`, `gate_status`, `p0_status`, `p1_status`, `overall_status`, `nfr_status`, `review_score`, `reasons`) is the consumable shape; the human-readable `reasons` strings are not contractual wording.
49
65
 
50
66
  ## @internal — not covered
@@ -1,4 +1,7 @@
1
- # Architecture
1
+ ---
2
+ title: Architecture
3
+ description: How UltraCode Goal works as a conductor over BMAD, TEA, and Claude Code primitives — the three enforcement layers, file layout, and customization resolution.
4
+ ---
2
5
 
3
6
  UltraCode Goal is a conductor. It orchestrates the installed BMAD epic toolbox and the TEA gates, composing Claude Code primitives — `/goal`, Auto Mode, Auto Memory, hooks, git/worktree isolation — and replaces none of them. This page covers the conductor model, the three enforcement layers in depth, the file layout, customization resolution, and why the hooks live where they do.
4
7
 
@@ -12,6 +15,38 @@ The skill owns no implementation logic of its own for building features or runni
12
15
 
13
16
  Because it is a conductor, the truth of "is this done" lives in the artifacts its delegates produce, not in the conductor's own reasoning. That is the whole design: the model arranges the work, but a script reads the verdict.
14
17
 
18
+ The conductor sits between three sets of things it does not own — the BMAD epic toolbox it orchestrates, the TEA gates it sequences, and the Claude Code primitives it composes:
19
+
20
+ ```mermaid
21
+ flowchart TD
22
+ UCG["UltraCode Goal conductor - owns order, gates, enforcement"]
23
+ subgraph toolbox["BMAD epic toolbox"]
24
+ SP["sprint-planning"]
25
+ CS["create-story"]
26
+ DS["dev-story"]
27
+ CR["code-review"]
28
+ CC["correct-course"]
29
+ end
30
+ subgraph tea["TEA gates"]
31
+ TD["test-design"]
32
+ ATDD["atdd"]
33
+ TR["trace writes gate-decision.json"]
34
+ NFR["nfr"]
35
+ end
36
+ subgraph cc["Claude Code primitives"]
37
+ GOAL["/goal loop"]
38
+ AUTO["Auto Mode"]
39
+ MEM["Auto Memory"]
40
+ HOOKS["PreToolUse + Stop hooks"]
41
+ GIT["git branch + worktrees"]
42
+ end
43
+ UCG -->|"delegates building"| toolbox
44
+ UCG -->|"sequences"| tea
45
+ UCG -->|"composes"| cc
46
+ classDef accent fill:#6366F1,stroke:#4F46E5,color:#fff
47
+ class UCG accent
48
+ ```
49
+
15
50
  ## The three enforcement layers
16
51
 
17
52
  These are the module's non-negotiables. Each exists because the documented mechanics make the intuitive shortcut wrong (see [why](why-ultracode-goal.md)).
@@ -20,6 +55,23 @@ These are the module's non-negotiables. Each exists because the documented mecha
20
55
 
21
56
  `scripts/gate_eval.py` reads TEA's `gate-decision.json` and maps its gate status to a routing verdict. It never re-derives TEA's thresholds and never reads the transcript. The `/goal` evaluator that drives execution can only see what the run surfaces — it cannot open the gate file — so it is structurally incapable of being the completion authority. The script is. See the [gate model](gate-model.md) for the full mapping, thresholds, and the fail-closed contract.
22
57
 
58
+ The mapping is fixed, and in production two extra signals can only downgrade an `advance`, never lift a lower verdict:
59
+
60
+ ```mermaid
61
+ flowchart TD
62
+ READ["gate_eval.py reads gate-decision.json"]
63
+ READ --> ST{"gate_status"}
64
+ ST -->|"PASS or WAIVED"| ADV["advance"]
65
+ ST -->|"CONCERNS"| DEF["defer - park to ledger, keep moving"]
66
+ ST -->|"FAIL"| REL["reloop - correct-course, re-run in budget"]
67
+ ST -->|"NOT_EVALUATED"| ESC["escalate - stop"]
68
+ ADV --> PROD{"production profile"}
69
+ PROD -->|"nfr FAIL, review under 80, Block, or unreadable signal"| REL
70
+ PROD -->|"both signals read and pass"| ADVOK["advance confirmed"]
71
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
72
+ class ADV,DEF,REL,ESC,ADVOK verdict
73
+ ```
74
+
23
75
  ### 2. Hooks as invariants
24
76
 
25
77
  Two invariants must hold for every commit, and neither can live in memory, which is context the model may or may not weigh:
@@ -72,6 +124,24 @@ Configuration resolves in three layers, base → team → user, via `resolve_cus
72
124
 
73
125
  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 budgets (`max_turns_per_story`, `story_token_budget`), the experimental `parallel_max_concurrency`, the `allowlist_commands`, and the `on_epic_complete` hook. 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).
74
126
 
127
+ 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:
128
+
129
+ ```mermaid
130
+ flowchart LR
131
+ BASE["Base - customize.toml"]
132
+ TEAM["Team - ultracode-goal.toml"]
133
+ USER["User - ultracode-goal.user.toml"]
134
+ BASE --> RES["resolve_customization.py merges base then team then user"]
135
+ TEAM --> RES
136
+ USER --> RES
137
+ RES --> WF["resolved workflow block"]
138
+ WF -->|"conductor reads scalars directly"| COND["conductor stages"]
139
+ WF -->|"preflight injects ULTRACODE_* env"| HOOKS["PreToolUse + Stop hooks"]
140
+ HOOKS -. "no env injected, falls back to defaults" .-> DROP["override no-ops at enforcement"]
141
+ classDef accent fill:#6366F1,stroke:#4F46E5,color:#fff
142
+ class WF accent
143
+ ```
144
+
75
145
  ## Why the hooks live in settings.local.json (decision D6)
76
146
 
77
147
  The PreToolUse and Stop hooks are auto-merged into `{project-root}/.claude/settings.local.json` — machine-local, gitignored, honored after the workspace trust dialog — not into a committed settings file or memory. The reasoning: these hooks are **enforcement, not context**. A committed hook would impose this module's commit guard on every contributor and every unrelated session in the repo; a hook in memory would not block a commit at all. The machine-local file scopes enforcement to the machine actually running the unattended Epic, and the gitignore keeps it out of shared history. The skill re-merges them every run (idempotently) and asserts they are active before the run goes unattended — it does not assume a prior run left them in place. Because the file is machine-local and executes on your machine, review what is merged; see [SECURITY.md](../SECURITY.md).
@@ -0,0 +1,107 @@
1
+ ---
2
+ title: Cross-Session Recall
3
+ description: The optional claude-mem integration — UCG consults your past runs in this repo before it scopes an Epic and before its preflight gate, advisory only and never in the gate path. Opt-in, hook-latched, off by default.
4
+ ---
5
+
6
+ > **Optional, opt-in, off by default.** Cross-Session Recall is an *advisory* read of your own past runs. It informs the model; it never decides anything. It is wired so it can **never** sit in the gate or completion path, it **fails closed** during a run, and when it is off — or when claude-mem is absent — the run is byte-for-byte the same as a run without it.
7
+
8
+ ## What it does
9
+
10
+ Cross-Session Recall lets UCG learn from its own history in *this* codebase instead of starting amnesiac every Epic. If you run [claude-mem](https://github.com/thedotmack/claude-mem), this executor consults your past runs in this codebase before it scopes a new Epic and before its preflight gate — so it surfaces what bit you here last time instead of starting amnesiac. You stay in the driver's seat; it informs, it doesn't auto-decide.
11
+
12
+ The benefit compounds — your first Epic teaches it, your third Epic consults two.
13
+
14
+ ## What you need
15
+
16
+ You need [claude-mem](https://github.com/thedotmack/claude-mem) installed and the `cross_session_recall` knob set to `on`. That is the whole dependency: UCG reads and writes through claude-mem's MCP tools when they are present, and does nothing recall-related when they are not.
17
+
18
+ > claude-mem is a third-party plugin maintained independently of this module. We don't bundle, endorse, or install it; Cross-Session Recall simply uses it when you already have it.
19
+
20
+ ## The touchpoints
21
+
22
+ Recall touches the run in exactly three places, and a machine latch (`.mem-state.json`) gates every one of them. The latch is written **once** at Ingest and removed at Finalize close-out; while it is present a `PreToolUse` hook allows claude-mem calls only when recall is green, and denies them otherwise — fail closed. The Execute and Gate stages are never touched.
23
+
24
+ ```mermaid
25
+ flowchart TD
26
+ I["Stage 1 Ingest — write latch, advisory scope-recall read"] --> P{"Stage 2 Preflight — prior-failure recall reuses the same fetch"}
27
+ P -->|"advisory only, voice never vote"| X["Stage 4 Execute — untouched"]
28
+ X --> G["Stage 5 Gate — untouched, gate_eval.py only"]
29
+ G --> F["Stage 6 Finalize — one structured write, then remove latch"]
30
+
31
+ LATCH{".mem-state.json latch — present and green gates reads and writes; absent or not green denies, fail closed"}
32
+ LATCH -.->|"gates"| I
33
+ LATCH -.->|"gates"| P
34
+ LATCH -.->|"gates"| F
35
+
36
+ classDef gate fill:#6366F1,stroke:#4F46E5,color:#fff
37
+ class P,LATCH gate
38
+ ```
39
+
40
+ - **Ingest (read).** Before UCG scopes the Epic, one advisory read pulls prior run summaries for this repo, sanitizes them, and surfaces what recurred.
41
+ - **Preflight (read, reused).** The prior-failure recall reuses that same fetch — no second round-trip — so the preflight reasoning can see failures that bit you here before. It is advisory context, never a gate input.
42
+ - **Finalize (write).** At close-out UCG records exactly one structured observation summarizing the run's outcome and signatures. The optional retrospective reuses the recurrence counts already computed during the reads.
43
+
44
+ Outside a run — when the latch file is absent — the hook never touches your claude-mem usage at all. Recall is scoped strictly to an active UCG run.
45
+
46
+ ## The trust model
47
+
48
+ The rule is **data, never directive**: recalled content is treated as facts to consider, never as instructions to follow, and it never reaches the gate.
49
+
50
+ What the sanitizer **does** before any advisory is surfaced:
51
+
52
+ - **Scopes to this repo.** A repository fingerprint pins recall to the same origin and root commit, so another project's history cannot leak in.
53
+ - **Redacts secrets.** High-precision patterns — AWS keys, `ghp_`/`gho_` tokens, `sk-` keys, bearer tokens, PEM headers, `password=`/`token=`/`api_key=` values — are replaced with `[redacted]`.
54
+ - **Neutralizes shape.** Bidi controls are stripped, backticks and code fences removed, newlines collapsed, and each surfaced title clamped to 80 codepoints — so an advisory cannot carry instruction-shaped or prompt-injection payloads.
55
+ - **Drops the stale and the foreign.** Records past the recency horizon are dropped (signatures that recurred across two or more distinct runs earn per-signal horizon immunity), foreign-project and cross-schema records are filtered out, and malformed records are discarded.
56
+
57
+ What it honestly does **not** do:
58
+
59
+ - It is **not** a complete secret scrubber — redaction is high-precision pattern matching, not a guarantee that nothing sensitive ever survives.
60
+ - It does **not** vote. Advisories carry only a mechanical `recurred` field (`yes`/`no`/`unknown`) — there are no LLM self-grades, and nothing recall surfaces is ever an input to `gate_eval.py`. The gate reads TEA's `gate-decision.json` and only that. See the [gate model](gate-model.md).
61
+ - It does **not** keep working when claude-mem looks wrong. If the capability contract fails — a missing tool, a malformed probe, a breaking schema change — the latch records recall as absent and the hook denies claude-mem calls for the run. Fail closed, never fail open.
62
+
63
+ ## Turning it on
64
+
65
+ Set the knob in your project's `_bmad/custom/ultracode-goal.toml` (the same file the other knobs use):
66
+
67
+ ```toml
68
+ [workflow]
69
+ # Cross-Session Recall — consult and record prior runs of this repo via claude-mem.
70
+ # Requires claude-mem installed; advisory only, never part of the gate. Off by default.
71
+ cross_session_recall = "on"
72
+ ```
73
+
74
+ The `[workflow]` table header matters: the resolver extracts the `workflow` block from the merged files, so a bare top-level `cross_session_recall` line is silently discarded and the feature stays off.
75
+
76
+ With it `on` and claude-mem installed, the next run reads at Ingest and Preflight and writes one observation at Finalize. Nothing else about the run changes.
77
+
78
+ ## Turning it off
79
+
80
+ Set the knob back to `off` (its default):
81
+
82
+ ```toml
83
+ [workflow]
84
+ cross_session_recall = "off"
85
+ ```
86
+
87
+ > **OFF-coherence disclosure.** Setting `cross_session_recall` to `off` disables **UCG's own** recall and write only. A separately-installed claude-mem still injects its session-start index into your Claude Code sessions — that is claude-mem's behavior, not UCG's. To stop that, configure or uninstall claude-mem itself.
88
+
89
+ ## What happens when claude-mem is absent
90
+
91
+ Nothing — the run is identical. There is no fallback to emulate, no degraded path, no warning. UCG's control flow is the same whether claude-mem is installed or not; absent claude-mem, the recall touchpoints are simply no-ops and Finalize skips the write. A run with the knob `on` and claude-mem missing behaves exactly like a run with the knob `off`.
92
+
93
+ ## Known limits — be honest
94
+
95
+ Recall is deliberately bounded. Treat these as the residuals you are signing up for:
96
+
97
+ - **A factual advisory still informs reasoning.** Sanitized advisories carry no instruction-shaped, stale, or foreign content and never reach the gate — but a well-formed factual advisory can still inform the model's reasoning. That is the feature, bounded; it is not a side channel into the verdict.
98
+ - **UCG serializes only its own writes.** It writes its one observation per run safely, but it cannot control other processes writing the same claude-mem store concurrently.
99
+ - **One structured write per run, in every mode.** UCG contributes exactly one structured observation at Finalize regardless of mode. Any *additional* auto-capture you see is claude-mem's own behavior and may differ in headless runs.
100
+ - **Redaction is high-precision, not complete.** Secret redaction is pattern matching tuned for precision; it is not a complete data-loss-prevention layer.
101
+ - **A breaking claude-mem change latches loudly absent.** If claude-mem ships a schema change that breaks the capability pin, recall latches as absent — loudly off, never silently wrong — until the pin is updated. Run the recall selftest to check the pin against your installed claude-mem.
102
+
103
+ ## The default, and what would flip it
104
+
105
+ Cross-Session Recall ships **off**. That is the honest default: an advisory that reads your history is worth shipping on by default only once opt-in usage proves it earns its keep without ever touching a verdict.
106
+
107
+ The default flips to `on` only if, across sustained real-world opt-in use, recalled advisories are corroborated by run outcomes **and** there are zero gate-influence incidents. Until that bar is met, off is the honest default — and "stays off" is a perfectly valid outcome. The criterion is falsifiable on purpose: it is a claim that can fail, not a roadmap promise.
@@ -1,4 +1,7 @@
1
- # Gate Model
1
+ ---
2
+ title: Gate Model
3
+ description: How gate_eval.py turns TEA's gate-decision.json into a fail-closed advance, defer, reloop, or escalate verdict.
4
+ ---
2
5
 
3
6
  Completion in UltraCode Goal is decided by a deterministic artifact read, not by judgment. `scripts/gate_eval.py` reads TEA's `gate-decision.json` and returns a routing verdict the skill executes. This page documents the verdict mapping, the production AND, the thresholds, the fail-closed contract, and why the `/goal` evaluator alone is insufficient — all traced to [`../skills/ultracode-goal/scripts/gate_eval.py`](../skills/ultracode-goal/scripts/gate_eval.py).
4
7
 
@@ -12,6 +15,27 @@ The script resolves the gate artifact from the trace output directory:
12
15
 
13
16
  The script never re-derives TEA's thresholds; it reads `gate_status` as given by the trace workflow.
14
17
 
18
+ How the script resolves an artifact into a `gate_status`:
19
+
20
+ ```mermaid
21
+ flowchart TD
22
+ A["Scan trace-output for a trace report"] --> B{"Frontmatter names a slim gate file?"}
23
+ B -->|"yes"| C["Use the hinted path"]
24
+ B -->|"no"| D["Default to gate-decision.json"]
25
+ C --> E{"Slim file present?"}
26
+ D --> E
27
+ E -->|"yes"| F["Read gate_status from slim file"]
28
+ E -->|"no"| G{"e2e-trace-summary.json present?"}
29
+ G -->|"yes, has gate fields"| H["Lift gate_status from summary"]
30
+ G -->|"yes, no gate fields"| I["gate_status = NOT_EVALUATED"]
31
+ G -->|"no"| I
32
+ F --> Z["gate_status to verdict mapping"]
33
+ H --> Z
34
+ I --> Z
35
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
36
+ class Z verdict
37
+ ```
38
+
15
39
  ## Verdict mapping
16
40
 
17
41
  The gate status maps to a verdict (`GATE_VERDICT` in the script):
@@ -33,6 +57,24 @@ Under `--profile production`, an otherwise-`advance` verdict is additionally AND
33
57
  - **NFR** (`nfr-assessment.md`): the audit's Overall Status must not be `FAIL`.
34
58
  - **Test review** (`test-review.md`): the Quality Score must be `>= 80` **and** the Recommendation must not be `Block`.
35
59
 
60
+ How the AND folds the two signals in, with every unreadable path counting as a failure:
61
+
62
+ ```mermaid
63
+ flowchart TD
64
+ V{"Verdict is advance?"} -->|"no, defer/reloop/escalate"| K["Unchanged"]
65
+ V -->|"yes"| N{"NFR Overall Status"}
66
+ N -->|"FAIL"| F["Signal failed"]
67
+ N -->|"file missing or unparsable"| F
68
+ N -->|"parsed and not FAIL"| R{"Test review"}
69
+ R -->|"score lt 80 or Block"| F
70
+ R -->|"score unparsable, file missing"| F
71
+ R -->|"score gte 80 and not Block"| P["Both signals passed"]
72
+ F --> D["Downgrade advance to reloop"]
73
+ P --> A["Stay advance"]
74
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
75
+ class A,D,K verdict
76
+ ```
77
+
36
78
  Under `--profile light` none of this applies — the trace gate is the whole decision.
37
79
 
38
80
  ## The thresholds
@@ -1,4 +1,7 @@
1
- # Getting Started
1
+ ---
2
+ title: Getting Started
3
+ description: Install UltraCode Goal, point it at a BMAD Epic, and walk the first autonomous run from install through preflight, gate, and run report.
4
+ ---
2
5
 
3
6
  Install UltraCode Goal into a BMAD project, point it at an Epic, and let it run that Epic to a gate-passed Definition-of-Done. This page covers prerequisites, install, the first-run walkthrough, and the run-mode flags.
4
7
 
@@ -36,6 +39,32 @@ Invoke the skill with one of its trigger phrases — "run an epic autonomously",
36
39
 
37
40
  From there the run is autonomous: it defines done with TEA, executes each story to a green commit, gates each one deterministically, and finalizes with a run report and the deferred-work ledger. See [how it works](how-it-works.md) for the full stage-by-stage narration.
38
41
 
42
+ The whole first run, from install to run report, with the two points where it can refuse to launch and the verdict that decides each story:
43
+
44
+ ```mermaid
45
+ flowchart TD
46
+ I["npx install"] --> A["Activate skill via trigger phrase"]
47
+ A --> N["Stage 1: name the Epic"]
48
+ N --> BMAD{"BMAD project?"}
49
+ BMAD -->|"no"| STOP1["Stop: point at setup skills"]
50
+ BMAD -->|"yes"| PF["Stage 2: preflight check then auto-remediate ambers"]
51
+ PF --> GATE{"Budget 0 and no red blocker?"}
52
+ GATE -->|"no"| STOP2["Stop: write blockers to decision log"]
53
+ GATE -->|"yes"| BRIEF["Arm branch, hooks, allowlist; launch briefing; one soft confirm"]
54
+ BRIEF --> RUN["Autonomous run: define done, execute each story to a green commit"]
55
+ RUN --> EVAL["Stage 5: gate_eval.py reads TEA gate-decision.json"]
56
+ EVAL --> V{"verdict"}
57
+ V -->|"advance"| NEXT["Next story, or finalize when last"]
58
+ V -->|"defer"| NEXT
59
+ V -->|"reloop"| RUN
60
+ V -->|"escalate"| STOP3["Stop: surface the blocker"]
61
+ NEXT --> RPT["Stage 6: run report and deferred-work ledger"]
62
+ class STOP1,STOP2,STOP3 stop
63
+ class RPT verdict
64
+ classDef stop fill:#9CA3AF,stroke:#6B7280,color:#fff
65
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
66
+ ```
67
+
39
68
  ## Run-mode flags
40
69
 
41
70
  | Flag | Effect |
@@ -1,4 +1,7 @@
1
- # Health Check
1
+ ---
2
+ title: Health Check
3
+ description: The Finalize self-improvement reflection — what it computes locally, what leaves your machine and only after approval, how it dedups, and how to turn it off.
4
+ ---
2
5
 
3
6
  Every UltraCode Goal run that reaches Finalize ends with a health check: a brief self-improvement reflection that audits the run for friction, gaps, or bugs in *this module* and, when it finds something, offers to file a structured GitHub issue. The expected outcome is **zero findings** — a clean run exits in a line. This page covers exactly what it sends, the privacy model, how it dedups, and how to turn it off. The deterministic fingerprint and seen-cache plumbing is [`../skills/ultracode-goal/scripts/health_check_fp.py`](../skills/ultracode-goal/scripts/health_check_fp.py).
4
7
 
@@ -24,6 +27,44 @@ Explicitly **not** sent: no source code, no Epic content, no secrets. The eviden
24
27
 
25
28
  Issues are filed publicly on `armelhbobdad/bmad-module-ultracode-goal`. On an **attended** run nothing is sent silently: the health check always **HALTS at a `[Y]` / `[N]` / `[E]` gate** before submitting — yes to file, no to skip, edit to adjust first. You see the finding and approve it before it leaves your machine.
26
29
 
30
+ The boundary below shows the disable path, everything computed on your machine, and the two points where anything crosses to GitHub — both behind a gate:
31
+
32
+ ```mermaid
33
+ flowchart TD
34
+ Start["Reaches Finalize"] --> Enabled{"health_check_enabled true"}
35
+ Enabled -->|"false"| Off["Log one line and exit. Nothing computed, nothing sent"]
36
+ Enabled -->|"true"| Reflect["Reflect on this run. Grade bug, friction, gap"]
37
+ Reflect --> Clean{"Any findings"}
38
+ Clean -->|"no"| Done["Clean run. Exit in one line"]
39
+ Clean -->|"yes"| Gate{"Approved to submit"}
40
+ Gate -->|"no, queue or skip"| Queue["Write finding to local queue. Stays on disk"]
41
+ Gate -->|"yes"| Fp["Compute fingerprint and check seen-cache"]
42
+ Fp --> Search["Remote dedup search on GitHub"]
43
+ Search --> Create["Create or react on public issue"]
44
+
45
+ subgraph local["On your machine"]
46
+ Enabled
47
+ Off
48
+ Reflect
49
+ Clean
50
+ Done
51
+ Gate
52
+ Queue
53
+ Fp
54
+ end
55
+ subgraph net["Leaves the machine"]
56
+ Search
57
+ Create
58
+ end
59
+
60
+ classDef accent fill:#6366F1,stroke:#4F46E5,color:#fff
61
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
62
+ class Gate accent
63
+ class Create verdict
64
+ ```
65
+
66
+ The gate that admits anything to the right of the boundary is the `[Y]` approval on an attended run, or the autosubmit opt-in restricted to `bug`-severity findings on a headless run; the Environment table — never source code, Epic content, or secrets — is all that travels with a filed issue.
67
+
27
68
  ## Unattended behavior
28
69
 
29
70
  Headless runs do not have a human at the gate, so by default they **queue findings locally and never live-submit**. Two config knobs (set in `{project-root}/_bmad/custom/ultracode-goal.toml`) change this:
@@ -1,4 +1,7 @@
1
- # How It Works
1
+ ---
2
+ title: How It Works
3
+ description: A faithful walkthrough of UltraCode Goal's six stages, the testable conditions that route between them, and the headless contract.
4
+ ---
2
5
 
3
6
  UltraCode Goal runs an Epic through six stages, in order. Each stage routes to the next by testable conditions stated in its reference file under [`../skills/ultracode-goal/references/`](../skills/ultracode-goal/references/). This page narrates the stages faithfully, the conditions that move between them, and the headless contract. For the design behind it, see [architecture](architecture.md); for the gate specifically, see the [gate model](gate-model.md).
4
7
 
@@ -13,6 +16,46 @@ UltraCode Goal runs an Epic through six stages, in order. Each stage routes to t
13
16
  | 5 | Gate | the `gate_eval.py` verdict: advance / defer / reloop / escalate |
14
17
  | 6 | Finalize | terminal — report, ledger, memory capture |
15
18
 
19
+ The stages run in order, but the edges are conditional — each one only advances on a testable condition, and two of them loop backward on failure. This shows the real routing, including the preflight remediation loop and the gate re-loop:
20
+
21
+ ```mermaid
22
+ flowchart TD
23
+ S1["Stage 1 Ingest and Scope"]
24
+ NotBmad["STOP — not a BMAD project"]
25
+ S2["Stage 2 Preflight"]
26
+ Remediate["Auto-remediate then re-run check"]
27
+ Blocked["STOP or blocked — RED or budget gt 0"]
28
+ S3["Stage 3 Define Done"]
29
+ S4["Stage 4 Execute"]
30
+ S5["Stage 5 Gate via gate_eval.py"]
31
+ Correct["bmad-correct-course"]
32
+ S6["Stage 6 Finalize"]
33
+
34
+ S1 -->|"config + sprint + epic all absent"| NotBmad
35
+ S1 -->|"one resolved epic id"| S2
36
+ S2 -->|"remediable blocker"| Remediate
37
+ Remediate --> S2
38
+ S2 -->|"RED found or budget gt 0"| Blocked
39
+ S2 -->|"budget == 0 and no RED and ultracode plus Auto Mode on"| S3
40
+ S3 -->|"ATDD hard-halt on vague ACs"| S3
41
+ S3 -->|"every story has red-phase atdd-checklist"| S4
42
+ S4 -->|"every story committed at green"| S5
43
+ S4 -->|"turn-bound escalation"| S5
44
+ S5 -->|"advance or defer"| S6
45
+ S5 -->|"reloop — gate FAIL within budget"| Correct
46
+ Correct --> S4
47
+ S5 -->|"escalate — NOT_EVALUATED or budget exhausted"| S6
48
+
49
+ classDef accent fill:#6366F1,stroke:#4F46E5,color:#fff
50
+ classDef verdict fill:#4F46E5,stroke:#3730A3,color:#fff
51
+ classDef stop fill:#9CA3AF,stroke:#6B7280,color:#fff
52
+ class S5 verdict
53
+ class S2 accent
54
+ class NotBmad,Blocked stop
55
+ ```
56
+
57
+ A `defer` verdict appends non-blocking items to the ledger and advances anyway; an `escalate` ends the run as `blocked` at Stage 6 rather than `complete`. The reloop edge re-runs the story only while turn and token budget remain — once exhausted, a FAIL becomes an escalate.
58
+
16
59
  ### Stage 1 — Ingest & Scope
17
60
 
18
61
  Resolve **which** Epic this run delivers and lock the profile. The operator names the Epic (or the skill picks the obvious in-flight one from `sprint-status.yaml`); the skill locates the Epic/story files, the PRD, and the ADR/architecture, and records the paths to the run's `.decision-log.md`. This is the cheap stage that prevents an expensive run from targeting the wrong Epic.
@@ -41,6 +84,29 @@ Drive each in-scope story from its red-phase tests to a green, committed state.
41
84
 
42
85
  Decide whether a story (or, after the last story, the Epic) advances — by a deterministic artifact read. In production, the skill first backfills the evidence in order — `bmad-testarch-automate`, `bmad-testarch-trace` (which writes the gate decision), `bmad-testarch-nfr` — then runs `gate_eval.py`. The script reads TEA's `gate-decision.json` and returns a verdict the skill executes: `advance` (move to the next story), `defer` (append non-blocking items to the ledger and advance anyway), `reloop` (run `bmad-correct-course`, re-run the story within the remaining budget), or `escalate` (stop). The invariant: **a P0/critical FAIL never defers** — it re-loops within budget or escalates. See the [gate model](gate-model.md) and [`references/gate.md`](../skills/ultracode-goal/references/gate.md).
43
86
 
87
+ This is how the verdict is read deterministically — the conductor never grades the work itself, it runs the script and routes on what comes back:
88
+
89
+ ```mermaid
90
+ sequenceDiagram
91
+ participant C as Conductor
92
+ participant TEA as TEA trace
93
+ participant G as gate_eval.py
94
+ participant F as gate-decision.json
95
+ C->>TEA: bmad-testarch-trace writes gate decision
96
+ C->>G: run gate_eval.py --trace-output DIR
97
+ G->>F: resolve and read slim file
98
+ alt slim file absent
99
+ G->>F: fall back to e2e-trace-summary.json
100
+ end
101
+ F-->>G: gate_status
102
+ Note over G: PASS or WAIVED to advance, CONCERNS to defer, FAIL to reloop, NOT_EVALUATED to escalate
103
+ Note over G: production only — NFR FAIL or review lt 80 or Block downgrades advance to reloop
104
+ G-->>C: verdict + reasons JSON
105
+ C->>C: route the verdict advance / defer / reloop / escalate
106
+ ```
107
+
108
+ The production AND fails closed: a missing or unparseable `nfr-assessment.md` or `test-review.md` is treated as a failing signal, so an otherwise-`advance` story downgrades to `reloop` rather than advancing on evidence the script could not read.
109
+
44
110
  ### Stage 6 — Finalize
45
111
 
46
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`](../skills/ultracode-goal/references/finalize.md).