@nanobpm/nano-workforce 0.138.1 → 0.138.2
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/AGENTS.md +68 -3
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -211,6 +211,42 @@ Two different `nano:dataEnvelope` uses have different rules — don't conflate t
|
|
|
211
211
|
deriving a worker's array inputs from the model this way over a hand-typed
|
|
212
212
|
`interface In`; don't "fix" a modelled `list="true"` array back to a joined
|
|
213
213
|
scalar.
|
|
214
|
+
- **A service-task/worker `dataEnvelope.in` field is read from PROCESS scope, not
|
|
215
|
+
task-local `ioMapping`.** (This applies to service-task/worker job envelopes; a
|
|
216
|
+
`dataEnvelope.in` on a **message subscription** — e.g. `CapsResolved` at
|
|
217
|
+
`plan-fanout.bpmn:12` — is instead populated from the correlated **message
|
|
218
|
+
payload**, so this gotcha does not apply there.) At runtime the engine populates
|
|
219
|
+
each declared `.in` field *by name* from the process variables in scope — a
|
|
220
|
+
`<zeebe:ioMapping>` input that synthesises a **new** name with no backing process
|
|
221
|
+
variable is silently ignored, so the field arrives **blank**. The engine itself
|
|
222
|
+
raises no incident for that *omitted* field (an `.in` name with no backing
|
|
223
|
+
variable resolves to null and blanks) — but this is distinct from a FEEL
|
|
224
|
+
`ioMapping` that **errors**: on the pinned engine (`@nanobpm/engine-wasm` 0.8.1's
|
|
225
|
+
`IO_MAPPING_ERROR` fix — before it, a failed mapping silently blanked, e.g. a
|
|
226
|
+
blocked converge-gate's escalation *question*; see the `e2e/*escalation*.e2e.ts`
|
|
227
|
+
comments) a failed FEEL mapping now raises an **incident** rather than blanking
|
|
228
|
+
through. A consumer that fails fast on the blank value will also incident (e.g.
|
|
229
|
+
`pr.readiness-probe` once read an empty `gateKey`;
|
|
230
|
+
`readGateVars` in `workers/readiness-probe/worker.ts` now *throws* on a blank
|
|
231
|
+
`gateKey`, creating an incident). Tasks like `ensure-base-branch` work only because
|
|
232
|
+
`repo`/`baseBranch` already exist as process variables. Seed any field a task must
|
|
233
|
+
read — **that is not already created in the task's visible process scope** — as a
|
|
234
|
+
real process variable at plan start (e.g. in `startPlan`); don't rely on
|
|
235
|
+
`ioMapping` to synthesise it. (A field already materialised in scope by the
|
|
236
|
+
process — e.g. `ReadinessProbeIn.probe`, seeded per multi-instance child via
|
|
237
|
+
`inputElement="probe"` in `resources/processes/feature.bpmn` — needs no such
|
|
238
|
+
seeding.) A **constant/literal** ioMapping source is different again: a
|
|
239
|
+
`<zeebe:input source="=true" target="lastAttempt"/>` (the readiness-gate
|
|
240
|
+
boundary's last-attempt marker — `readiness-gate.bpmn:125`, `feature.bpmn:105`,
|
|
241
|
+
`plan-fanout.bpmn:198`, and the generated `deliveryGraphCompiler.ts:1011`) is
|
|
242
|
+
*evaluated* and materialised into the job's scope, so it needs **no** backing
|
|
243
|
+
process variable — its value is the literal, not a reference to an (absent)
|
|
244
|
+
variable. The "arrives blank" failure above is specific to a field whose value
|
|
245
|
+
must be *derived from a process variable that isn't in scope* (the `gateKey`
|
|
246
|
+
case). Do **not** "fix" a working literal marker like `lastAttempt` by seeding
|
|
247
|
+
it as a process variable: besides being unnecessary, seeding a var an
|
|
248
|
+
in-subprocess gateway reads re-introduces the multi-instance `=null`-shadow
|
|
249
|
+
gotcha above.
|
|
214
250
|
|
|
215
251
|
## Urban page runtime: rendering primitives are not JS-truthy
|
|
216
252
|
|
|
@@ -235,6 +271,21 @@ silently — cheap to avoid, annoying to debug after the fact.
|
|
|
235
271
|
`showWhenField` is hidden for `0`/`null`/`""` alike — so a `0`-or-`NULL` flag
|
|
236
272
|
correctly hides it either way. (This is why the same flag can need `NULL` for a
|
|
237
273
|
badge yet work as `0` for a `showWhenField` button.)
|
|
274
|
+
- **Renderer kinds are a version-pinned set — verify against the installed
|
|
275
|
+
package, not an issue reference.** The page renderers are a finite set fixed by
|
|
276
|
+
the pinned `@nanobpm/urban`; a version *range* only guarantees *some* matching
|
|
277
|
+
build is installed. Do **not** assume a primitive exists because an issue,
|
|
278
|
+
changelog, or *Links* section mentions it — `urban check` (a CI gate) rejects
|
|
279
|
+
unknown renderer kinds only *after* you've authored a page around a phantom one
|
|
280
|
+
(epic #254 bounced three review rounds asserting a page-level "stepper" that
|
|
281
|
+
never shipped). Confirm the kind against the installed `RENDERERS` map
|
|
282
|
+
(`node_modules/@nanobpm/urban/dist/runtime/core/modules/pages.js`) and the kinds
|
|
283
|
+
already used across `pages/*.page.json`. Note a **nano-ide issue can ship a data
|
|
284
|
+
read-model, not a page renderer** (nano-ide#254 shipped the lineage projection, a data
|
|
285
|
+
primitive) — read *what kind* of primitive it delivers. Build composite visuals
|
|
286
|
+
as a `dataGrid` column renderer over stored columns (e.g. the `"kind":
|
|
287
|
+
"pipeline"` column in `pages/feature.page.json`), not a page-level primitive,
|
|
288
|
+
unless you've verified that primitive exists in the installed build.
|
|
238
289
|
|
|
239
290
|
### The top nav has a single source of truth — edit `pages/_nav.json`
|
|
240
291
|
|
|
@@ -271,10 +322,24 @@ Migrations live in `db/migrations/*.sql` and are **auto-applied on boot** from
|
|
|
271
322
|
- Number a new migration after the current highest prefix (they apply in order).
|
|
272
323
|
Check `origin/main`, not your branch point — a fan-out epic branch forks at one
|
|
273
324
|
prefix while `main` keeps advancing, so the branch-local "next" number collides
|
|
274
|
-
on merge.
|
|
325
|
+
on merge. **In a *simultaneous* fan-out wave, checking `origin/main` isn't
|
|
326
|
+
enough**: every sibling forks at the same commit, sees the same highest prefix,
|
|
327
|
+
and independently takes the same next number (main hasn't advanced yet), so the
|
|
328
|
+
planner must **pre-assign each slice a disjoint prefix block at decomposition
|
|
329
|
+
time** (e.g. give slice A `NNN`–`NNN+1`, slice B `NNN+2`–`NNN+3`, plus a separate
|
|
330
|
+
cleanup block — start the whole allocation *after* the current highest committed
|
|
331
|
+
prefix, never at fixed literals like `060`, which are long occupied) rather than
|
|
332
|
+
have each
|
|
333
|
+
agent compute "the next free" prefix. (This is the same "coarsen parallel work on
|
|
334
|
+
a shared surface" principle as the one-task-owns-each-`.bpmn` rule above — a
|
|
335
|
+
migration-prefix block is a shared numbering surface just like a `.bpmn`
|
|
336
|
+
diagram.) Two files must never share a prefix; `npm run check:migrations`
|
|
275
337
|
(a CI gate) enforces this and fails the build on any new duplicate. Because a
|
|
276
|
-
prefix collision only exists in the *union* of two branches
|
|
277
|
-
|
|
338
|
+
**merge-skew** prefix collision only exists in the *union* of two branches (a
|
|
339
|
+
single branch that adds two same-prefix files is a self-collision
|
|
340
|
+
`check:migrations` already catches on the PR itself), this gate — like
|
|
341
|
+
`layout:check`, the navigation-index check (`sync:nav:check`), and a catch-all
|
|
342
|
+
committed-artifact backstop (`git diff --exit-code`) — is also re-run on the
|
|
278
343
|
merge queue's **prospective merged commit** and on **push to `main`** by
|
|
279
344
|
`.github/workflows/invariants.yml` (issue #366), so a merge-skew collision is
|
|
280
345
|
blocked at merge time or fails a `main`-scoped build within minutes rather than
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [0.138.2](https://github.com/nanobpm/nano-workforce/compare/v0.138.1...v0.138.2) (2026-08-24)
|
|
2
|
+
|
|
3
|
+
### Documentation
|
|
4
|
+
|
|
5
|
+
* **agents:** consolidate retro feedback ([#268](https://github.com/nanobpm/nano-workforce/issues/268), [#322](https://github.com/nanobpm/nano-workforce/issues/322), [#449](https://github.com/nanobpm/nano-workforce/issues/449)); drop stale [#415](https://github.com/nanobpm/nano-workforce/issues/415) ([#518](https://github.com/nanobpm/nano-workforce/issues/518)) ([3c47cb2](https://github.com/nanobpm/nano-workforce/commit/3c47cb21d079b6b9f5470abacb0190373208d0ca)), closes [#416](https://github.com/nanobpm/nano-workforce/issues/416) [#887](https://github.com/nanobpm/nano-workforce/issues/887) [#254](https://github.com/nanobpm/nano-workforce/issues/254) [#254](https://github.com/nanobpm/nano-workforce/issues/254) [nano-ide#254](https://github.com/nanobpm/nano-ide/issues/254)
|
|
6
|
+
|
|
1
7
|
## [0.138.1](https://github.com/nanobpm/nano-workforce/compare/v0.138.0...v0.138.1) (2026-08-24)
|
|
2
8
|
|
|
3
9
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanobpm/nano-workforce",
|
|
3
|
-
"version": "0.138.
|
|
3
|
+
"version": "0.138.2",
|
|
4
4
|
"description": "Nano Workforce — an Agent Graph Orchestration application for Agentic SDLC: durable BPMN processes that coordinate a graph of AI agents across the software delivery lifecycle.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "main.ts",
|