@nanobpm/nano-workforce 0.26.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 (115) hide show
  1. package/.github/workflows/ci.yml +60 -0
  2. package/.github/workflows/release.yml +58 -0
  3. package/.releaserc.json +17 -0
  4. package/AGENTS.md +168 -0
  5. package/CHANGELOG.md +231 -0
  6. package/LICENSE +202 -0
  7. package/README.md +303 -0
  8. package/SPEC.md +492 -0
  9. package/actions/abandon.test.ts +93 -0
  10. package/actions/abandon.ts +23 -0
  11. package/actions/blackboard.test.ts +195 -0
  12. package/actions/blackboard.ts +76 -0
  13. package/actions/cancel.ts +29 -0
  14. package/actions/feature-answer-hook.ts +44 -0
  15. package/actions/message.ts +49 -0
  16. package/actions/plan-hook.ts +19 -0
  17. package/actions/plan-start.ts +17 -0
  18. package/actions/start.ts +19 -0
  19. package/actions/status.ts +22 -0
  20. package/actions/webhook-submit.ts +21 -0
  21. package/app/abandon.test.ts +97 -0
  22. package/app/abandon.ts +105 -0
  23. package/app/baseGuard.test.ts +35 -0
  24. package/app/baseGuard.ts +62 -0
  25. package/app/blackboard.test.ts +295 -0
  26. package/app/blackboard.ts +301 -0
  27. package/app/github.test.ts +59 -0
  28. package/app/github.ts +647 -0
  29. package/app/mergeExclusion.test.ts +168 -0
  30. package/app/mergeExclusion.ts +211 -0
  31. package/app/mergeProtocol.test.ts +124 -0
  32. package/app/mergeProtocol.ts +193 -0
  33. package/app/mergeRebaseArm.test.ts +72 -0
  34. package/app/mergeTrain.test.ts +91 -0
  35. package/app/mergeTrain.ts +117 -0
  36. package/app/persist-escalation.test.ts +119 -0
  37. package/app/persist-round.test.ts +65 -0
  38. package/app/plan.test.ts +317 -0
  39. package/app/plan.ts +321 -0
  40. package/app/record-plan-review.test.ts +38 -0
  41. package/app/reviewWait.test.ts +70 -0
  42. package/app/reviewWait.ts +59 -0
  43. package/app/rounds.test.ts +74 -0
  44. package/app/rounds.ts +48 -0
  45. package/app/service.test.ts +101 -0
  46. package/app/service.ts +895 -0
  47. package/app/taskDelta.test.ts +144 -0
  48. package/app/taskDelta.ts +175 -0
  49. package/app/trialMerge.test.ts +15 -0
  50. package/app/trialMerge.ts +102 -0
  51. package/app/waves.test.ts +128 -0
  52. package/app/waves.ts +116 -0
  53. package/assets/icon.svg +13 -0
  54. package/components/review-round.json +69 -0
  55. package/db/migrations/001_init.sql +46 -0
  56. package/db/migrations/002_transcript.sql +7 -0
  57. package/db/migrations/003_open_escalation.sql +8 -0
  58. package/db/migrations/004_merge.sql +36 -0
  59. package/db/migrations/004_planning.sql +37 -0
  60. package/db/migrations/005_job_activation.sql +15 -0
  61. package/db/migrations/005_plan_deps.sql +20 -0
  62. package/db/migrations/006_plan_review.sql +22 -0
  63. package/db/migrations/006_task_escalation.sql +52 -0
  64. package/db/migrations/007_plan_review_job_key.sql +14 -0
  65. package/db/migrations/007_wave_gate.sql +16 -0
  66. package/db/migrations/008_review_nudge.sql +9 -0
  67. package/db/migrations/009_plan_blackboard.sql +46 -0
  68. package/db/migrations/010_plan_task_deltas.sql +27 -0
  69. package/db/migrations/011_plan_merge_exclusions.sql +26 -0
  70. package/db/migrations/012_merge_protocol_attempt.sql +4 -0
  71. package/db/migrations/013_merge_train_waiting_lane.sql +6 -0
  72. package/db/migrations/014_plan_trial_merges.sql +21 -0
  73. package/db/migrations/015_pr_abandon_token.sql +9 -0
  74. package/deno.json +24 -0
  75. package/deno.lock +1776 -0
  76. package/main.ts +71 -0
  77. package/nano-ide.ext.json +7 -0
  78. package/nano.app.json +138 -0
  79. package/nanobpm.project.json +20 -0
  80. package/package.json +56 -0
  81. package/pages/epic.page.json +195 -0
  82. package/pages/home.page.json +296 -0
  83. package/prompts/feature.md +132 -0
  84. package/prompts/fix-ci.md +65 -0
  85. package/prompts/plan-review.md +69 -0
  86. package/prompts/plan.md +183 -0
  87. package/prompts/rebase.md +82 -0
  88. package/prompts/review-round.md +171 -0
  89. package/prompts/trial-merge.md +43 -0
  90. package/renovate.json +21 -0
  91. package/resources/processes/convergence-loop.bpmn +399 -0
  92. package/resources/processes/merge-loop.bpmn +585 -0
  93. package/resources/processes/plan-fanout.bpmn +546 -0
  94. package/scripts/check-agent-prompts.test.ts +84 -0
  95. package/scripts/check-agent-prompts.ts +143 -0
  96. package/scripts/layout-bpmn.ts +99 -0
  97. package/scripts/purge-db.ts +57 -0
  98. package/scripts/upgrade-from-pack.ts +334 -0
  99. package/tsconfig.json +51 -0
  100. package/workers/arm-merge/worker.ts +18 -0
  101. package/workers/finalize/worker.ts +89 -0
  102. package/workers/mark-merged/worker.ts +21 -0
  103. package/workers/merge/worker.ts +119 -0
  104. package/workers/persist-escalation/worker.ts +107 -0
  105. package/workers/persist-round/worker.ts +52 -0
  106. package/workers/persist-task-escalation/worker.ts +112 -0
  107. package/workers/record-plan/worker.ts +135 -0
  108. package/workers/record-plan-review/worker.ts +92 -0
  109. package/workers/record-results/worker.ts +30 -0
  110. package/workers/record-trial-merge/worker.test.ts +104 -0
  111. package/workers/record-trial-merge/worker.ts +88 -0
  112. package/workers/record-wave/worker.test.ts +221 -0
  113. package/workers/record-wave/worker.ts +308 -0
  114. package/workers/select-wave/worker.test.ts +130 -0
  115. package/workers/select-wave/worker.ts +84 -0
@@ -0,0 +1,60 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ typecheck:
14
+ name: typecheck (Node + Deno)
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Node.js
21
+ uses: actions/setup-node@v4
22
+ with:
23
+ node-version: "24"
24
+
25
+ - name: Install dependencies
26
+ run: npm ci
27
+
28
+ - name: Typecheck (Node / tsc)
29
+ run: npm run typecheck
30
+
31
+ - name: Validate manifest (urban check)
32
+ run: npm run check
33
+
34
+ # DI-freshness gate: the `.bpmn` semantic model is authoritative and the
35
+ # `bpmndi:BPMNDiagram` is GENERATED (scripts/layout-bpmn.ts → layoutBpmn). This regenerates
36
+ # the DI in memory and fails if any committed diagram is stale — i.e. a flow was changed
37
+ # without re-running `npm run layout`. Keeps the diagram from drifting off the model.
38
+ - name: Check BPMN diagram freshness (layout)
39
+ run: npm run layout:check
40
+
41
+ - name: Setup Deno
42
+ uses: denoland/setup-deno@v2
43
+ with:
44
+ deno-version: v2.x
45
+
46
+ - name: Typecheck (Deno)
47
+ run: deno check main.ts 'workers/**/*.ts' 'actions/**/*.ts'
48
+
49
+ # Deploy-safety gate: every model-authored `{{template}}` agent-prompt header must resolve
50
+ # to a declared, non-blank prompt (and no agent prompt may ship blank). A broken/blank token
51
+ # means a prompt-less agent — the root of the empty escalations on nano-bpm #597/#599.
52
+ - name: Check agent prompt templates
53
+ run: deno run -A scripts/check-agent-prompts.ts
54
+
55
+ # Runs the app/*.test.ts suite (never exercised by the check globs above)
56
+ # AND guards the committed lockfile: --frozen fails the build if deno.lock
57
+ # is out of date for the full graph (incl. tests), so lockfile drift — e.g.
58
+ # a regenerate that drops the jsr:@std/* test deps — can't be merged.
59
+ - name: Test + frozen lockfile guard (Deno)
60
+ run: deno test -A --frozen
@@ -0,0 +1,58 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ # Prevent overlapping releases from racing on the same branch.
8
+ concurrency:
9
+ group: release-${{ github.ref }}
10
+ cancel-in-progress: false
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ release:
17
+ name: semantic-release
18
+ runs-on: ubuntu-latest
19
+ # `[skip ci]` on the release commit already prevents a re-trigger, but guard
20
+ # against loops from any automated release commit as well.
21
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
22
+ permissions:
23
+ contents: write # create tags, GitHub Releases, push CHANGELOG/version bump
24
+ issues: write # comment on released issues
25
+ pull-requests: write # comment on released PRs
26
+ id-token: write # OIDC token for npm Trusted Publishing (no NPM_TOKEN)
27
+ steps:
28
+ - name: Checkout
29
+ uses: actions/checkout@v4
30
+ with:
31
+ fetch-depth: 0 # semantic-release needs full history + tags
32
+ persist-credentials: true # let @semantic-release/git push the release commit
33
+
34
+ - name: Configure git author
35
+ run: |
36
+ git config user.name "github-actions[bot]"
37
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
38
+
39
+ - name: Setup Node.js
40
+ uses: actions/setup-node@v4
41
+ with:
42
+ node-version: "24"
43
+ registry-url: "https://registry.npmjs.org"
44
+
45
+ - name: Ensure npm supports OIDC Trusted Publishing
46
+ # Pinned (not @latest) for reproducible, supply-chain-safe releases.
47
+ # Any version >= 11.5.1 supports npm Trusted Publishing (OIDC).
48
+ run: npm install -g npm@11.12.1
49
+
50
+ - name: Install dependencies
51
+ run: npm ci
52
+
53
+ - name: Release
54
+ env:
55
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56
+ # No NPM_TOKEN / NODE_AUTH_TOKEN: publishing uses OIDC Trusted Publishing.
57
+ NPM_CONFIG_PROVENANCE: "true"
58
+ run: npx semantic-release
@@ -0,0 +1,17 @@
1
+ {
2
+ "branches": ["main"],
3
+ "plugins": [
4
+ "@semantic-release/commit-analyzer",
5
+ "@semantic-release/release-notes-generator",
6
+ "@semantic-release/changelog",
7
+ "@semantic-release/npm",
8
+ "@semantic-release/github",
9
+ [
10
+ "@semantic-release/git",
11
+ {
12
+ "assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
13
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
14
+ }
15
+ ]
16
+ ]
17
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,168 @@
1
+ # AGENTS.md
2
+
3
+ Operational guide for AI coding agents working in this repository. Read this
4
+ before making any change. `SPEC.md` is the behavioural source of truth for the
5
+ processes; `README.md` covers setup, roles, and running.
6
+
7
+ ## What this repo is
8
+
9
+ `nano-workforce` is an [Urban](https://github.com/jwulf/nano-ide) app (ADR 0055)
10
+ — **Agent Graph Orchestration for Agentic SDLC**. It drives GitHub PRs to
11
+ **review convergence** and then **merge**, and can take a whole issue and fan a
12
+ fleet of agents out to implement it. It is a set of
13
+ durable BPMN processes (`resources/processes/*.bpmn`) plus host glue
14
+ (`app/`, `workers/`, `actions/`, `main.ts`) over the Urban runtime seams
15
+ (`DataLayer`, `EngineClient`). The processes are executed by the **nanobpmn
16
+ engine** (`~/workspace/nanobpmn` `engine-core`, embedded in the nano broker the
17
+ app deploys to via the nano SDK).
18
+
19
+ ## Universal engineering principles
20
+
21
+ ### No such thing as "flaky tests"
22
+ Intermittently failing tests must always be root-caused and fixed as either a
23
+ product defect (code) or a production-line defect (test). We do not acknowledge
24
+ the existence of "flaky tests".
25
+
26
+ ### No test retries
27
+ A test must pass or fail deterministically on a single run — no test-runner
28
+ `retry`, no CI re-run-on-failure to coax a green. A test that only passes on a
29
+ later attempt is non-deterministic: root-cause and fix it, never paper over it.
30
+
31
+ ### Red/Green discipline
32
+ Every bug fix must have a test that reproduces the defect **before** modifying
33
+ code. Red first, then green — always.
34
+
35
+ ### Fix the failure mode, don't just squash the bug
36
+ When you find a defect, reason about its whole class and write a guard for the
37
+ class. Prefer securing the surface — including an architectural refactor that
38
+ eliminates the failure mode categorically — over squashing a single instance.
39
+ (Example: a durable wait that can hang forever is a *class* of bug — fix it by
40
+ modelling a bounded race in the process, not by special-casing one PR.)
41
+
42
+ ### Feature test coverage
43
+ New features must carry test coverage over the new surface so regressions are
44
+ caught.
45
+
46
+ ### Derivation over duplication: no drift surfaces
47
+ Eliminate duplicate sources of truth. Everything derivable must be derived from
48
+ one canonical source with one canonical implementation. Do not add a parallel
49
+ implementation of an existing stage (a second poller pass, a second escalation
50
+ path, a second review loop) — extend the canonical one.
51
+
52
+ ### Zero tolerance for warnings, errors, and test failures
53
+ There are no pre-existing failures or warnings, and you will not allow any to
54
+ enter the codebase. `tsc`, `urban check`, `deno check`, and `deno test` must all
55
+ be clean.
56
+
57
+ ### No task without a tracked issue or PR
58
+ Before starting planned work, check for an existing issue or PR. If one is
59
+ already in progress, stop and flag it with a link. Otherwise create and claim an
60
+ issue before writing code.
61
+
62
+ ## BPMN: author the semantic model, generate the diagram
63
+
64
+ **The `.bpmn` files under `resources/processes/` are hand-authored semantic
65
+ models. The diagram interchange (`bpmndi:BPMNDiagram` — shapes and edges) is
66
+ GENERATED, never hand-edited.**
67
+
68
+ - Edit the BPMN semantics (elements, sequence flows, gateways, ioMappings,
69
+ `zeebe:taskHeaders`) by hand in the XML.
70
+ - Regenerate the DI with `npm run layout <path/to/file.bpmn>`
71
+ (`scripts/layout-bpmn.ts` → `@nanobpm/urban`'s `layoutBpmn`, which wraps
72
+ `bpmn-auto-layout`). Re-run it **whenever the flow changes** (new node, new
73
+ flow). Header/ioMapping-only edits don't change shapes and don't need a relayout.
74
+ - Never hand-edit `<bpmndi:…>` — the semantic model is authoritative; a
75
+ hand-tweaked diagram will be clobbered on the next layout and drifts from the
76
+ model in the meantime.
77
+ - **CI enforces DI freshness.** `npm run layout:check` (`scripts/layout-bpmn.ts
78
+ --check`) regenerates every diagram in memory and fails if a committed one is
79
+ stale. It runs in `.github/workflows/ci.yml`, so a flow change that forgets the
80
+ relayout **cannot merge**. Run `npm run layout` and commit the result whenever
81
+ the check flags a model.
82
+
83
+ ## Engine capabilities (Zeebe parity — use them, don't work around them)
84
+
85
+ The nanobpmn engine (`~/workspace/nanobpmn` `engine-core`, deployed via the nano
86
+ broker) already implements, with **Zeebe-parity semantics** and passing tests:
87
+
88
+ - **Event-based gateways** — the deferred-choice race (e.g. wait for a message
89
+ **or** a timer), with correct sibling-withdrawal when one arm wins
90
+ (engine PR #369).
91
+ - **Boundary events** — timer, message, error, and signal, each **interrupting
92
+ and non-interrupting**, attachable to activities.
93
+ - **FEEL-expression timer durations** — `<bpmn:timeDuration>=someVar</…>` is
94
+ evaluated at timer creation, so a timeout can be driven by a process variable
95
+ (not just a static `PT15M`).
96
+
97
+ Model liveness properly in the process. To bound a durable wait, author an
98
+ **event-based gateway** racing the awaited message against a timer catch (or a
99
+ boundary event on an activity) — do **not** invent a poller-side timeout/sentinel
100
+ to force a token off a wait. The engine owns token semantics; the poller only
101
+ reconciles external (GitHub) state.
102
+
103
+ **Caveat — code-first authoring:** the `@nanobpm/workflow` `defineFlow` builder
104
+ cannot yet express event-based gateways or boundary events (its `FlowNode` union
105
+ has no such node). This app authors BPMN as XML, so author those constructs in
106
+ the XML directly; `layoutBpmn` lays them out correctly.
107
+
108
+ ## Data envelopes are scalar-only
109
+
110
+ `nano:dataEnvelope` shapes support only **scalar** `nano:extend` types
111
+ (`string`, `integer`, `datetime`, `boolean`) — **not arrays**. When a message
112
+ must carry a list (e.g. failing check names), join it to a scalar (e.g.
113
+ `\n`-separated) in the publisher before it crosses the envelope, and split it on
114
+ the far side if needed.
115
+
116
+ ## The poller owns liveness/reconciliation
117
+
118
+ `main.ts` runs a **self-scheduling** poll loop (`pollOnce` in `app/service.ts`),
119
+ not `setInterval`, so a slow GitHub call can't overlap passes. Each pass advances
120
+ the review stage, the merge stage, job-activation visibility, and wave gates by
121
+ reading GitHub and correlating engine messages. Any new external-state watch
122
+ belongs here as another idempotent pass. A pass must always make forward
123
+ progress possible — never leave a PR on a status no pass scans (it wedges), and
124
+ never rely on an external actor (e.g. Copilot re-reviewing) that the app doesn't
125
+ itself trigger.
126
+
127
+ ## Database migrations (SQLite, forward-only, expand-and-contract)
128
+
129
+ Migrations live in `db/migrations/*.sql` and are **auto-applied on boot** from
130
+ `nano.app.json` (`data.sources.app.migrations`). They are forward-only.
131
+
132
+ - **Default to additive (expand):** nullable/`DEFAULT`ed `ADD COLUMN`, new
133
+ tables/indexes. Never drop or rename a column/table in the same change that
134
+ stops using it.
135
+ - **Destructive drops are a separate, later contract phase**, shipped only after
136
+ a release stopped reading the old shape.
137
+ - Number a new migration after the current highest prefix (they apply in order).
138
+
139
+ ## Runtime & CI gates
140
+
141
+ Node-hosted (`node --experimental-strip-types`), but the sources are
142
+ **cross-runtime**: workers/actions/`main.ts` also typecheck and run under Deno.
143
+ Match CI locally before pushing:
144
+
145
+ ```bash
146
+ npm run typecheck # tsc --noEmit (Node)
147
+ npm run check # urban check (manifest validation)
148
+ npm run layout:check # BPMN diagram freshness (no drift)
149
+ deno check main.ts 'workers/**/*.ts' 'actions/**/*.ts' # Deno typecheck
150
+ deno test -A # unit tests (run with -A)
151
+ ```
152
+
153
+ CI (`.github/workflows/ci.yml`) gates typecheck, `urban check`, `layout:check`,
154
+ Deno typecheck, and the Deno test suite. Run `npm run layout <file.bpmn>` after
155
+ any BPMN flow change and commit the regenerated diagram — the `layout:check`
156
+ gate fails the build otherwise.
157
+
158
+ ## Repo conventions
159
+
160
+ - **DCO sign-off is enforced.** Every commit needs a `Signed-off-by` trailer —
161
+ use `git commit -s` (or `git rebase --signoff`). A missing sign-off fails the
162
+ DCO check.
163
+ - **Conventional Commits.** `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`,
164
+ `test:`, imperative mood. Review-comment fix-ups are `chore:`, not `fix:`.
165
+ - **Feature work in a worktree** off `origin/main`, one branch per change; open a
166
+ PR and reference the closing issue (`Closes #NN`).
167
+ - **Never `git push --force` on `main`;** use `--force-with-lease` on feature
168
+ branches.
package/CHANGELOG.md ADDED
@@ -0,0 +1,231 @@
1
+ # [0.26.0](https://github.com/jwulf/urban-pr-review/compare/v0.25.0...v0.26.0) (2026-08-08)
2
+
3
+
4
+ ### Features
5
+
6
+ * **cancel:** cooperative abandon check — a cancelled run makes no side effect ([#77](https://github.com/jwulf/urban-pr-review/issues/77)) ([11b0155](https://github.com/jwulf/urban-pr-review/commit/11b0155c0bd1ecadba7ac286317a2c5723a7d475)), closes [#76](https://github.com/jwulf/urban-pr-review/issues/76)
7
+
8
+ # [0.25.0](https://github.com/jwulf/urban-pr-review/compare/v0.24.0...v0.25.0) (2026-08-07)
9
+
10
+
11
+ ### Features
12
+
13
+ * rebrand to "Nano Workforce" with a shipped app icon ([#71](https://github.com/jwulf/urban-pr-review/issues/71)) ([3fb5386](https://github.com/jwulf/urban-pr-review/commit/3fb53863def6e7525401ddb0280a15ab9c81aae6)), closes [#638](https://github.com/jwulf/urban-pr-review/issues/638)
14
+
15
+ # [0.24.0](https://github.com/jwulf/urban-pr-review/compare/v0.23.0...v0.24.0) (2026-08-07)
16
+
17
+
18
+ ### Features
19
+
20
+ * **console:** epic pane — wave state × conflict graph (D10) ([#75](https://github.com/jwulf/urban-pr-review/issues/75)) ([54c9b5b](https://github.com/jwulf/urban-pr-review/commit/54c9b5bfb84ebcce435646191a27f07e78d28b45))
21
+
22
+ # [0.23.0](https://github.com/jwulf/urban-pr-review/compare/v0.22.0...v0.23.0) (2026-08-07)
23
+
24
+
25
+ ### Features
26
+
27
+ * **merge:** trial-merge integration gate for semantic conflicts (D3) ([#70](https://github.com/jwulf/urban-pr-review/issues/70)) ([22b6f99](https://github.com/jwulf/urban-pr-review/commit/22b6f994757c359f9258ce873a6b052f967c9e47))
28
+
29
+ # [0.22.0](https://github.com/jwulf/urban-pr-review/compare/v0.21.0...v0.22.0) (2026-08-07)
30
+
31
+
32
+ ### Features
33
+
34
+ * **merge:** serialize same-lane landings (D6) ([#68](https://github.com/jwulf/urban-pr-review/issues/68)) ([581d402](https://github.com/jwulf/urban-pr-review/commit/581d402c40ee43102a86a09d3e8c085eceb8c199)), closes [#67](https://github.com/jwulf/urban-pr-review/issues/67) [#49](https://github.com/jwulf/urban-pr-review/issues/49)
35
+
36
+ # [0.21.0](https://github.com/jwulf/urban-pr-review/compare/v0.20.0...v0.21.0) (2026-08-07)
37
+
38
+
39
+ ### Features
40
+
41
+ * **coordination:** add waiting-for-lane task state (D7) ([#65](https://github.com/jwulf/urban-pr-review/issues/65)) ([2311b07](https://github.com/jwulf/urban-pr-review/commit/2311b07b1f93793cde801fad5bad7fcc793e52f2))
42
+
43
+ # [0.20.0](https://github.com/jwulf/urban-pr-review/compare/v0.19.0...v0.20.0) (2026-08-07)
44
+
45
+
46
+ ### Features
47
+
48
+ * **merge:** reapply merge protocol on every landing attempt (D9) ([#66](https://github.com/jwulf/urban-pr-review/issues/66)) ([5bb4291](https://github.com/jwulf/urban-pr-review/commit/5bb42914589ad138afc5270b56af155b5ab2f4fb))
49
+
50
+ # [0.19.0](https://github.com/jwulf/urban-pr-review/compare/v0.18.0...v0.19.0) (2026-08-07)
51
+
52
+
53
+ ### Features
54
+
55
+ * **merge:** guard against landing a PR into a dead-end base branch ([#60](https://github.com/jwulf/urban-pr-review/issues/60)) ([#61](https://github.com/jwulf/urban-pr-review/issues/61)) ([e108598](https://github.com/jwulf/urban-pr-review/commit/e108598b1f46b1a0d85c0a4689adb25be301ef2c)), closes [#54](https://github.com/jwulf/urban-pr-review/issues/54)
56
+
57
+ # [0.18.0](https://github.com/jwulf/urban-pr-review/compare/v0.17.0...v0.18.0) (2026-08-07)
58
+
59
+
60
+ ### Features
61
+
62
+ * **coordination:** merge-exclusion graph + file-overlap conflict-scan (D1/D2) ([#59](https://github.com/jwulf/urban-pr-review/issues/59)) ([538ed94](https://github.com/jwulf/urban-pr-review/commit/538ed9448870abd99b5f2d82e14477a6bd299f97))
63
+
64
+ # [0.17.0](https://github.com/jwulf/urban-pr-review/compare/v0.16.0...v0.17.0) (2026-08-07)
65
+
66
+
67
+ ### Features
68
+
69
+ * **coordination:** structured scope/impl-change report from implementers ([#55](https://github.com/jwulf/urban-pr-review/issues/55)) ([#56](https://github.com/jwulf/urban-pr-review/issues/56)) ([13b62c2](https://github.com/jwulf/urban-pr-review/commit/13b62c25052e2132ad677fec337dc7b2ca6997d3)), closes [#49](https://github.com/jwulf/urban-pr-review/issues/49) [nano-bpm#614](https://github.com/nano-bpm/issues/614) [#624](https://github.com/jwulf/urban-pr-review/issues/624) [#54](https://github.com/jwulf/urban-pr-review/issues/54)
70
+
71
+ # [0.16.0](https://github.com/jwulf/urban-pr-review/compare/v0.15.0...v0.16.0) (2026-08-07)
72
+
73
+
74
+ ### Features
75
+
76
+ * **coordination:** epic blackboard — Tier 2 midflight coordination ([#54](https://github.com/jwulf/urban-pr-review/issues/54)) ([c873b63](https://github.com/jwulf/urban-pr-review/commit/c873b6309721d0e66d5be5c87d2a6df9896bf391)), closes [#52](https://github.com/jwulf/urban-pr-review/issues/52) [51/#53](https://github.com/jwulf/urban-pr-review/issues/53) [#42](https://github.com/jwulf/urban-pr-review/issues/42) [#53](https://github.com/jwulf/urban-pr-review/issues/53)
77
+
78
+ # [0.15.0](https://github.com/jwulf/urban-pr-review/compare/v0.14.3...v0.15.0) (2026-08-07)
79
+
80
+
81
+ ### Features
82
+
83
+ * **coordination:** epic blackboard — Tier 1 dispatch/resume channel ([#53](https://github.com/jwulf/urban-pr-review/issues/53)) ([2dcfb8a](https://github.com/jwulf/urban-pr-review/commit/2dcfb8a5e1bd7beb89d174e646d40d610462365a)), closes [#51](https://github.com/jwulf/urban-pr-review/issues/51) [#49](https://github.com/jwulf/urban-pr-review/issues/49) [Magikcraft/nano-bpm#614](https://github.com/Magikcraft/nano-bpm/issues/614) [#52](https://github.com/jwulf/urban-pr-review/issues/52)
84
+
85
+ ## [0.14.3](https://github.com/jwulf/urban-pr-review/compare/v0.14.2...v0.14.3) (2026-08-07)
86
+
87
+
88
+ ### Bug Fixes
89
+
90
+ * **merge-loop:** add senior:rebase remediation arm ([#42](https://github.com/jwulf/urban-pr-review/issues/42)) ([#50](https://github.com/jwulf/urban-pr-review/issues/50)) ([a8195a4](https://github.com/jwulf/urban-pr-review/commit/a8195a49dae77868e1eb31a17aa32e2dfc3bc0a1))
91
+
92
+ ## [0.14.2](https://github.com/jwulf/urban-pr-review/compare/v0.14.1...v0.14.2) (2026-08-06)
93
+
94
+
95
+ ### Bug Fixes
96
+
97
+ * **review-round:** idempotent, non-destructive review re-request (unwedges [#35](https://github.com/jwulf/urban-pr-review/issues/35) class) ([#47](https://github.com/jwulf/urban-pr-review/issues/47)) ([7b9a391](https://github.com/jwulf/urban-pr-review/commit/7b9a391119be748344852ebb562cee39be6da8c9)), closes [#48](https://github.com/jwulf/urban-pr-review/issues/48)
98
+
99
+ ## [0.14.1](https://github.com/jwulf/urban-pr-review/compare/v0.14.0...v0.14.1) (2026-08-06)
100
+
101
+
102
+ ### Bug Fixes
103
+
104
+ * **plan-fanout:** keep template tokens out of XML comments ([#40](https://github.com/jwulf/urban-pr-review/issues/40)) ([46cad5a](https://github.com/jwulf/urban-pr-review/commit/46cad5a97dfb2fec0efbadf1514fe3cc75121775))
105
+ * **review:** give agents the exact Copilot review-request command ([#45](https://github.com/jwulf/urban-pr-review/issues/45)) ([2fda65c](https://github.com/jwulf/urban-pr-review/commit/2fda65c7bf924d8273c1104453f5b5512afb4e05)), closes [Magikcraft/nano-bpm#610](https://github.com/Magikcraft/nano-bpm/issues/610)
106
+
107
+ # [0.14.0](https://github.com/jwulf/urban-pr-review/compare/v0.13.0...v0.14.0) (2026-08-06)
108
+
109
+
110
+ ### Features
111
+
112
+ * **merge:** execute a per-repo merge protocol (fresh head run + [@mergifyio](https://github.com/mergifyio) queue) ([#44](https://github.com/jwulf/urban-pr-review/issues/44)) ([712a0eb](https://github.com/jwulf/urban-pr-review/commit/712a0eb212616152a13a23b2306bebc19349746d)), closes [#43](https://github.com/jwulf/urban-pr-review/issues/43)
113
+
114
+ # [0.13.0](https://github.com/jwulf/urban-pr-review/compare/v0.12.4...v0.13.0) (2026-08-06)
115
+
116
+
117
+ ### Features
118
+
119
+ * **pages:** make the pull-request list collapsible, remembered across sessions ([#41](https://github.com/jwulf/urban-pr-review/issues/41)) ([62e9249](https://github.com/jwulf/urban-pr-review/commit/62e924949b109f14657d103f1b69c9535ce3f205))
120
+
121
+ ## [0.12.4](https://github.com/jwulf/urban-pr-review/compare/v0.12.3...v0.12.4) (2026-08-06)
122
+
123
+
124
+ ### Bug Fixes
125
+
126
+ * **escalation:** make no-result rounds recoverable from the UI ([#38](https://github.com/jwulf/urban-pr-review/issues/38)) ([b7259a0](https://github.com/jwulf/urban-pr-review/commit/b7259a042fddfeee4f6bce90461e171afda5dc9f)), closes [597/#599](https://github.com/jwulf/urban-pr-review/issues/599)
127
+
128
+ ## [0.12.3](https://github.com/jwulf/urban-pr-review/compare/v0.12.2...v0.12.3) (2026-08-06)
129
+
130
+
131
+ ### Bug Fixes
132
+
133
+ * **prompts:** deliver agent base prompts as a variable bridge (unblock review resubmit) ([#37](https://github.com/jwulf/urban-pr-review/issues/37)) ([6ae1c05](https://github.com/jwulf/urban-pr-review/commit/6ae1c057c947b4251d5f390fb3beed4ffa61125f)), closes [#36](https://github.com/jwulf/urban-pr-review/issues/36) [#31](https://github.com/jwulf/urban-pr-review/issues/31) [597/#599](https://github.com/jwulf/urban-pr-review/issues/599) [#36](https://github.com/jwulf/urban-pr-review/issues/36)
134
+
135
+ ## [0.12.2](https://github.com/jwulf/urban-pr-review/compare/v0.12.1...v0.12.2) (2026-08-06)
136
+
137
+
138
+ ### Bug Fixes
139
+
140
+ * adopt urban 0.22 for {{template}} substitution + guard prompt-less agents ([#35](https://github.com/jwulf/urban-pr-review/issues/35)) ([6ad92c1](https://github.com/jwulf/urban-pr-review/commit/6ad92c1d1c73c87e43efc49958a5b9a41debfb13)), closes [#34](https://github.com/jwulf/urban-pr-review/issues/34) [#597](https://github.com/jwulf/urban-pr-review/issues/597) [#599](https://github.com/jwulf/urban-pr-review/issues/599) [#31](https://github.com/jwulf/urban-pr-review/issues/31) [#106](https://github.com/jwulf/urban-pr-review/issues/106) [jwulf/urban-pr-review#34](https://github.com/jwulf/urban-pr-review/issues/34)
141
+
142
+ ## [0.12.1](https://github.com/jwulf/urban-pr-review/compare/v0.12.0...v0.12.1) (2026-08-05)
143
+
144
+
145
+ ### Bug Fixes
146
+
147
+ * adopt @nanobpm/urban 0.21.0 (grid row-detail collapse) + add Renovate ([#33](https://github.com/jwulf/urban-pr-review/issues/33)) ([7d75b46](https://github.com/jwulf/urban-pr-review/commit/7d75b46c443e75477aab78ee576ef94c02d182ce))
148
+
149
+ # [0.12.0](https://github.com/jwulf/urban-pr-review/compare/v0.11.0...v0.12.0) (2026-08-05)
150
+
151
+
152
+ ### Features
153
+
154
+ * harden review-wait against permanent stalls ([#32](https://github.com/jwulf/urban-pr-review/issues/32)) ([8303357](https://github.com/jwulf/urban-pr-review/commit/83033579a382e7d235dc8f248c821150a29ea121))
155
+
156
+ # [0.11.0](https://github.com/jwulf/urban-pr-review/compare/v0.10.0...v0.11.0) (2026-08-05)
157
+
158
+
159
+ ### Features
160
+
161
+ * model-authored template-header prompts + senior:fix-ci auto-fix loop ([#31](https://github.com/jwulf/urban-pr-review/issues/31)) ([761213a](https://github.com/jwulf/urban-pr-review/commit/761213ae65a26e29594bca8ad0e78a48c435d8c0)), closes [nano-ide#106](https://github.com/nano-ide/issues/106) [jwulf/urban-pr-review#29](https://github.com/jwulf/urban-pr-review/issues/29)
162
+
163
+ # [0.10.0](https://github.com/jwulf/urban-pr-review/compare/v0.9.0...v0.10.0) (2026-08-05)
164
+
165
+
166
+ ### Features
167
+
168
+ * gate a wave's implementation on the prior wave merging ([#30](https://github.com/jwulf/urban-pr-review/issues/30)) ([6f07fc4](https://github.com/jwulf/urban-pr-review/commit/6f07fc4771fc797ea5d61cd1c17aafce9f1c2dda))
169
+
170
+ # [0.9.0](https://github.com/jwulf/urban-pr-review/compare/v0.8.0...v0.9.0) (2026-08-05)
171
+
172
+
173
+ ### Features
174
+
175
+ * configurable review-round cap (default 20) + submit-form field ([#27](https://github.com/jwulf/urban-pr-review/issues/27)) ([ee8e314](https://github.com/jwulf/urban-pr-review/commit/ee8e3140b15b02cf0a8a1f268187f539debfe211))
176
+
177
+ # [0.8.0](https://github.com/jwulf/urban-pr-review/compare/v0.7.0...v0.8.0) (2026-08-05)
178
+
179
+
180
+ ### Features
181
+
182
+ * adversarial plan-review gate before fan-out dispatch ([#26](https://github.com/jwulf/urban-pr-review/issues/26)) ([1634c80](https://github.com/jwulf/urban-pr-review/commit/1634c80dfe0953f9a6739b8690ad0c5b7a990c74))
183
+
184
+ # [0.7.0](https://github.com/jwulf/urban-pr-review/compare/v0.6.0...v0.7.0) (2026-08-04)
185
+
186
+
187
+ ### Features
188
+
189
+ * mixed sequential + parallel plan fan-out via dependency waves ([#21](https://github.com/jwulf/urban-pr-review/issues/21)) ([ee67032](https://github.com/jwulf/urban-pr-review/commit/ee6703235e081a8c20f2e8b7d76ebc2282450f51)), closes [#20](https://github.com/jwulf/urban-pr-review/issues/20) [#20](https://github.com/jwulf/urban-pr-review/issues/20)
190
+
191
+ # [0.6.0](https://github.com/jwulf/urban-pr-review/compare/v0.5.0...v0.6.0) (2026-08-04)
192
+
193
+
194
+ ### Features
195
+
196
+ * make PR list entries clickable new-tab links ([#19](https://github.com/jwulf/urban-pr-review/issues/19)) ([cd73a02](https://github.com/jwulf/urban-pr-review/commit/cd73a0276f33ccafdd6e2f28d0d55bd40abc6b90))
197
+
198
+ # [0.5.0](https://github.com/jwulf/urban-pr-review/compare/v0.4.0...v0.5.0) (2026-08-04)
199
+
200
+
201
+ ### Features
202
+
203
+ * plan-fanout — decompose an issue into a fleet of PRs ([#14](https://github.com/jwulf/urban-pr-review/issues/14)) ([#17](https://github.com/jwulf/urban-pr-review/issues/17)) ([462a8d7](https://github.com/jwulf/urban-pr-review/commit/462a8d7fd1360db8a1f5f7ae65dd2ff86dfc8b5a))
204
+
205
+ # [0.4.0](https://github.com/jwulf/urban-pr-review/compare/v0.3.1...v0.4.0) (2026-08-03)
206
+
207
+
208
+ ### Features
209
+
210
+ * GET /app/status + cancel-by-prKey affordances ([#12](https://github.com/jwulf/urban-pr-review/issues/12)) ([9fbe066](https://github.com/jwulf/urban-pr-review/commit/9fbe066992b18529b485324b476ef031b4814565))
211
+
212
+ ## [0.3.1](https://github.com/jwulf/urban-pr-review/compare/v0.3.0...v0.3.1) (2026-08-03)
213
+
214
+
215
+ ### Bug Fixes
216
+
217
+ * **deps:** bump @nanobpm/urban to ^0.17.1 ([#11](https://github.com/jwulf/urban-pr-review/issues/11)) ([00d6a68](https://github.com/jwulf/urban-pr-review/commit/00d6a68e39d01369bd50784c846e97651a0022ac))
218
+
219
+ # [0.3.0](https://github.com/jwulf/urban-pr-review/compare/v0.2.1...v0.3.0) (2026-08-03)
220
+
221
+
222
+ ### Features
223
+
224
+ * **poller:** read GitHub reviews via the host `gh` CLI ([#10](https://github.com/jwulf/urban-pr-review/issues/10)) ([d04c12e](https://github.com/jwulf/urban-pr-review/commit/d04c12e9de30276d2d6cae2405330146f2e9540f))
225
+
226
+ ## [0.2.1](https://github.com/jwulf/urban-pr-review/compare/v0.2.0...v0.2.1) (2026-07-31)
227
+
228
+
229
+ ### Bug Fixes
230
+
231
+ * add license, repository metadata, and marketplace manifest ([3382cfb](https://github.com/jwulf/urban-pr-review/commit/3382cfb404d5a76d8eec2f7cb1abd36cb889ef14))