@bongos/core 1.20.6 → 1.20.8

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/.bongos-core.json CHANGED
@@ -2,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.20.6",
6
- "core_contract": "1.20.6",
7
- "source_commit": "7887b42a9147d4ca749389bca6fbff6120c41766",
5
+ "core_version": "1.20.8",
6
+ "core_contract": "1.20.8",
7
+ "source_commit": "fb1af293583380a02ab4fa8df4a06e31a89c73cc",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-30T04:05:09.203Z",
9
+ "built_at": "2026-09-30T04:32:44.486Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 556,
13
13
  "agent_docs_stubbed": 25,
14
- "functional_verbatim": 2619,
14
+ "functional_verbatim": 2623,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 3201,
20
- "tree_sha256": "e7197c9a0497ef19bdfcd4085f7d6509536dbd1a85e1e52629d416a46530bce2",
19
+ "file_count": 3205,
20
+ "tree_sha256": "4b5867abb42ec4c580d94333e13d9f029d81da62bf68a26c753511d54082f26c",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -1842,7 +1842,7 @@
1842
1842
  {
1843
1843
  "path": "docs/adr/0274-one-kernel-three-role-packs.md",
1844
1844
  "mode": "0000644",
1845
- "sha256": "d37cbce118162e144969efde564d92778bb6175c3af0d4e1502195aea18aa004"
1845
+ "sha256": "4164f1f1fb3cf0317ee19e168420aef85d7c529a5300d3fc46566010f42d9fbf"
1846
1846
  },
1847
1847
  {
1848
1848
  "path": "docs/adr/0275-one-source-for-a-written-role-responsibility.md",
@@ -2762,7 +2762,7 @@
2762
2762
  {
2763
2763
  "path": "docs/file-map.md",
2764
2764
  "mode": "0000644",
2765
- "sha256": "803f616840f604487828796195cdc74a3f834dc5f5117309ef01725b9d13b7aa"
2765
+ "sha256": "fd6ec16a880ab7b3ef0e31674c51ab9733ffda14855043aa6cc5afaddb20c03e"
2766
2766
  },
2767
2767
  {
2768
2768
  "path": "docs/handoff-template.md",
@@ -2772,7 +2772,7 @@
2772
2772
  {
2773
2773
  "path": "docs/module-api-changelog.md",
2774
2774
  "mode": "0000644",
2775
- "sha256": "4604938cde7776d0076401f0a76aea306838b3498cd6c6834bf2ce34e68d84c9"
2775
+ "sha256": "4bcc9fffeff37ae0b087af39c16e3cf8f381a066b2e70019fe8b1f30f49bce3c"
2776
2776
  },
2777
2777
  {
2778
2778
  "path": "docs/modules-contract.md",
@@ -2837,22 +2837,22 @@
2837
2837
  {
2838
2838
  "path": "docs/onboarding/slash-commands.md",
2839
2839
  "mode": "0000644",
2840
- "sha256": "92ce9c4de763330c4ac877a1ba79d0b11d88797c711b3517adebe8604bdf59ea"
2840
+ "sha256": "cc792eb9391d147e443ba646f991f99f88245fbb96adeda7bf96364fa9bc7a85"
2841
2841
  },
2842
2842
  {
2843
2843
  "path": "docs/packs/artist.md",
2844
2844
  "mode": "0000644",
2845
- "sha256": "9d317443b3676bf68b7818473e75448e26a16c6316cad7298de7a4037d73cf5c"
2845
+ "sha256": "d9a0b37fb3e03ab2e0f874abf3db40fed123cae5c0f6443a0e176adcdfc30b1b"
2846
2846
  },
2847
2847
  {
2848
2848
  "path": "docs/packs/engineer.md",
2849
2849
  "mode": "0000644",
2850
- "sha256": "416aa7f4303a0148d52ab5c0e5720a327fa260a034a9558774df125e8876eee2"
2850
+ "sha256": "30e4d2363f1fea52cb347ba8a642277fe5046249f77858e947b4434150ff5746"
2851
2851
  },
2852
2852
  {
2853
2853
  "path": "docs/packs/ideator.md",
2854
2854
  "mode": "0000644",
2855
- "sha256": "bcb98ba4302f46c2001eb7081684300150966a7b05cc43691199fa1573292f90"
2855
+ "sha256": "e09e80d1bd99951f9edde09a743ef4e597b26810fca26c37045c2d1f9dc8b2f6"
2856
2856
  },
2857
2857
  {
2858
2858
  "path": "docs/page-inventory.json",
@@ -6567,7 +6567,7 @@
6567
6567
  {
6568
6568
  "path": "modules/lifecycle/ship-card.js",
6569
6569
  "mode": "0000644",
6570
- "sha256": "a055854c667a30b46465db35e8d88dd92b0d6438a5609281e1c49e1ae66f3a7f"
6570
+ "sha256": "1935e6f0a3fb9089c2aacd9bbdf1ff1296487065c8c5a25beaf96306d88a9f5b"
6571
6571
  },
6572
6572
  {
6573
6573
  "path": "modules/lifecycle/ship-files.js",
@@ -8852,12 +8852,12 @@
8852
8852
  {
8853
8853
  "path": "package-lock.json",
8854
8854
  "mode": "0000644",
8855
- "sha256": "d445839a2e943ee2d1f3309b1366f72132d11925c29aa19a46891ce7925ad116"
8855
+ "sha256": "3a10ecd6f93e42f1792e7edb0a406edaefb3377506afb359cde35e3fdd901296"
8856
8856
  },
8857
8857
  {
8858
8858
  "path": "package.json",
8859
8859
  "mode": "0000644",
8860
- "sha256": "d5d908e1d217603998e494d6c8343087d61dacc1b8fe894983a56cc4d809b819"
8860
+ "sha256": "065257986765387a5b632092aab054e6a9d8299b9c27473a9b0e306dec3d73cc"
8861
8861
  },
8862
8862
  {
8863
8863
  "path": "public-docs/index.html",
@@ -8877,7 +8877,7 @@
8877
8877
  {
8878
8878
  "path": "release-notes.json",
8879
8879
  "mode": "0000644",
8880
- "sha256": "0836c84d2d1fbda2104f75831bcc05bd10fa3e05d29db763c250d8d4416769b3"
8880
+ "sha256": "3c69418a8c305f1aa08dd13193ee4489ac818f9723147c218e8f5745dfae1e8b"
8881
8881
  },
8882
8882
  {
8883
8883
  "path": "scripts/bongos-mcp.js",
@@ -9172,7 +9172,7 @@
9172
9172
  {
9173
9173
  "path": "scripts/gds/claim.js",
9174
9174
  "mode": "0000644",
9175
- "sha256": "7c1917a46bad730419a57047cc34ab21ff9fb2268d4c090a18effa0625e9678a"
9175
+ "sha256": "78a7e407218051892c1aa0934474084deec94768fdd28fe2c3fa447fe48905fd"
9176
9176
  },
9177
9177
  {
9178
9178
  "path": "scripts/gds/classify-discipline.js",
@@ -9327,7 +9327,7 @@
9327
9327
  {
9328
9328
  "path": "scripts/gds/discipline-modes.json",
9329
9329
  "mode": "0000644",
9330
- "sha256": "a62a714209198f02ca4f964ecfd1211dd3712b946f049843a7ec921b5907f1d0"
9330
+ "sha256": "467b66fbb778b9f8eeb03989b18fc085e4c4ccb6b397ca2777cdd82360675c42"
9331
9331
  },
9332
9332
  {
9333
9333
  "path": "scripts/gds/discord-channels.js",
@@ -9394,6 +9394,11 @@
9394
9394
  "mode": "0000644",
9395
9395
  "sha256": "b8b1a7ed1d8dd217b24757a3ec9f4b3aa58b26a3e2a7b2cef9de217792e5ea43"
9396
9396
  },
9397
+ {
9398
+ "path": "scripts/gds/find-untested.js",
9399
+ "mode": "0000644",
9400
+ "sha256": "6788cb8ea36250fe84236f1a1f1a216f5627a1772d9dad5399b700cd3f984d74"
9401
+ },
9397
9402
  {
9398
9403
  "path": "scripts/gds/fitness-checks-error-envelope.js",
9399
9404
  "mode": "0000644",
@@ -9727,7 +9732,7 @@
9727
9732
  {
9728
9733
  "path": "scripts/gds/newcomer-floor.templates.json",
9729
9734
  "mode": "0000644",
9730
- "sha256": "0b5cf03a0c3fd84da5f22064cbf6b6c8d73d30cbeb6a09803da6ef3e9f2809b6"
9735
+ "sha256": "0623cc216ae3d20def01ac6d1aaedb4cf25d25fe9a94201cee86b8ff07673c0a"
9731
9736
  },
9732
9737
  {
9733
9738
  "path": "scripts/gds/newcomer-floor.test.js",
@@ -10012,7 +10017,7 @@
10012
10017
  {
10013
10018
  "path": "scripts/gds/role-pack-guard.js",
10014
10019
  "mode": "0000644",
10015
- "sha256": "7ac55428d01852cd169bd5cb319af306a8f7798489fa89780921f4119c2f552f"
10020
+ "sha256": "34edfb2553f3441387b8bca2f0608b95b089f9d3efd7cd370e83fd9bc3652296"
10016
10021
  },
10017
10022
  {
10018
10023
  "path": "scripts/gds/route-shadow-guard.js",
@@ -10694,6 +10699,11 @@
10694
10699
  "mode": "0000644",
10695
10700
  "sha256": "27630af327d56e6eea77eb7e402086ec695f9fd02f419e48af463ed1adbfab8c"
10696
10701
  },
10702
+ {
10703
+ "path": "src/bongos/craft-mode.js",
10704
+ "mode": "0000644",
10705
+ "sha256": "6df8bd98fbd15d3be903465390ab8f300aa029b1847c42cbe0e10c7af2e62a74"
10706
+ },
10697
10707
  {
10698
10708
  "path": "src/bongos/db-kernel.js",
10699
10709
  "mode": "0000644",
@@ -10907,7 +10917,7 @@
10907
10917
  {
10908
10918
  "path": "src/bongos/routes/me.js",
10909
10919
  "mode": "0000644",
10910
- "sha256": "375859169dde72844541a62a1ff0e97b97321faeed058a287ad7b9c31cdc3a82"
10920
+ "sha256": "989cb7aeb70d956dcd6e93f9fea3acf27fca85f17c5fd2f185b6a99541ede0ae"
10911
10921
  },
10912
10922
  {
10913
10923
  "path": "src/bongos/routes/modules.js",
@@ -10982,7 +10992,7 @@
10982
10992
  {
10983
10993
  "path": "src/module-api.js",
10984
10994
  "mode": "0000644",
10985
- "sha256": "b76b3ccf9bc56f911703cf59e4e02652ab73076407ab164ef746f1177b7f72aa"
10995
+ "sha256": "fdb2e5eb052bbdc4698fdb5cde2da471036c90c52f7f105cd8b057ae330ee8c1"
10986
10996
  },
10987
10997
  {
10988
10998
  "path": "src/module-loader/catalog.js",
@@ -11802,7 +11812,7 @@
11802
11812
  {
11803
11813
  "path": "tests/conductor_main_e2e.mjs",
11804
11814
  "mode": "0000644",
11805
- "sha256": "c3b01032ebd3d2c4093bfc1101c2a445c93c52ff520341d6f39a5f582a1e2b97"
11815
+ "sha256": "b81e385b1c1cc3a7b6981b7c3ee4cbe169d24384404fd0e9681560e85a6cf9a1"
11806
11816
  },
11807
11817
  {
11808
11818
  "path": "tests/confirm_attribution.mjs",
@@ -11954,6 +11964,11 @@
11954
11964
  "mode": "0000644",
11955
11965
  "sha256": "50f195ef2060df92016b58f541a28e7492dd95ad4da8bd0781bdc07007193338"
11956
11966
  },
11967
+ {
11968
+ "path": "tests/craft_mode.mjs",
11969
+ "mode": "0000644",
11970
+ "sha256": "26e499e01ee9ec71094e5d2b3b0a0cf367513b9f25a54d1bd716b0d8e318f91d"
11971
+ },
11957
11972
  {
11958
11973
  "path": "tests/credential_presence.mjs",
11959
11974
  "mode": "0000644",
@@ -12324,6 +12339,11 @@
12324
12339
  "mode": "0000644",
12325
12340
  "sha256": "815f2fa2ffd6e7a721507852d43b0490115a0b15393670f6035626bdf000e99c"
12326
12341
  },
12342
+ {
12343
+ "path": "tests/find_untested.mjs",
12344
+ "mode": "0000644",
12345
+ "sha256": "1a4b0eeee9212776a1a1f159053cd48d5af3041dc0a45c3b32cf0e7706600422"
12346
+ },
12327
12347
  {
12328
12348
  "path": "tests/first_admin_bootstrap.mjs",
12329
12349
  "mode": "0000644",
@@ -15937,7 +15957,7 @@
15937
15957
  {
15938
15958
  "path": "tests/visual_review.mjs",
15939
15959
  "mode": "0000644",
15940
- "sha256": "102e80ed4c6c61583d9dfeca23db321be9b871cab3d8f47e4594674b7ecd3cf5"
15960
+ "sha256": "c6f6846bfcfd73ec9e7c47062d26a4ff0c38b6bf5ade1eab6293f458011de8c9"
15941
15961
  },
15942
15962
  {
15943
15963
  "path": "tests/wandering_prefs.mjs",
@@ -22,7 +22,7 @@ Meanwhile the craft-specific material that *did* exist lived in three slash-comm
22
22
 
23
23
  3. **`/dev`, `/ideate` and `/paint` are deleted.** The skill listing drops to 25,624 chars and 17 over-length descriptions.
24
24
 
25
- 4. **`scripts/gds/discipline-modes.json` becomes the role registry.** A core craft names a `pack` (a file to *read*); a module-contributed discipline may still name a `skill` (a command to *invoke*), which is how `ui` → `/design` survives unchanged, as ADR 0272 requires. `claim.js` prints whichever the entry carries, with the right verb.
25
+ 4. **`scripts/gds/discipline-modes.json` becomes the role registry.** A core craft names a `pack` (a file to *read*); a module-contributed discipline may still name a `skill` (a command to *invoke*), which is how `ui` → `/design` survives unchanged, as ADR 0272 requires. `claim.js` prints whichever the entry carries, with the right verb. *(Since task 1002992 the full pointer is injected by the Conductor from GET /me and `claim.js` prints only the one role line.)*
26
26
 
27
27
  5. **`scripts/gds/role-pack-guard.js` hard-fails CI** when an entry names a pack that is not in the tree, when an entry names neither pointer, when fewer than three crafts carry a pack, or when a pack exceeds its character budget (16,000 hard / 13,000 target, ratcheted just above the packs as authored).
28
28
 
package/docs/file-map.md CHANGED
@@ -143,7 +143,7 @@
143
143
  │ ├── discord-channels.js ← Archon CLI: plan/apply the Discord channel layout via the API (ADR 0036, #727)
144
144
  │ ├── setup.js ← one-time GitHub Device Flow → ~/.config/otb/gds-session.json
145
145
  │ ├── start.js ← list claimable tasks + active claims (`/builder-start`)
146
- │ ├── claim.js ← atomic POST /api/bongos/claims (`/builder-claim`); runs the worktree-per-claim guard (worktree-claim-guard.js) BEFORE the session check and the POST; prints the claim-time context pack incl. next-free ADR/migration numbers (V4.R26); printDisciplineMode() reads discipline-modes.json to route a claimed task to its playbook skill
146
+ │ ├── claim.js ← atomic POST /api/bongos/claims (`/builder-claim`); runs the worktree-per-claim guard (worktree-claim-guard.js) BEFORE the session check and the POST; prints the claim-time context pack incl. next-free ADR/migration numbers (V4.R26); printRoleLine() prints the claimed craft's one role line from discipline-modes.json and lands a ui claim's module-owned skills (the full pack pointer is injected by the Conductor from GET /me, task 1002992)
147
147
  │ ├── discipline-modes.json ← the ROLE REGISTRY read by claim.js: engineer/artist/ideator → their role pack under docs/packs/, module-contributed ui → the /design skill; absence of an entry = the default build-and-ship loop, fail-open at claim time — but scripts/gds/role-pack-guard.js hard-fails CI if an entry names a pack that is not in the tree ([#1267](https://example.com/builders#/task/1267))
148
148
  │ ├── next-number.js ← deterministic next-free ADR + migration number from origin/main ∪ local working tree; supersedes the drift-prone claim-time DB counter (V4.R26, [#964](https://example.com/builders#/task/964)). `node scripts/gds/next-number.js [--json]`
149
149
  │ ├── gen-repo-map.js ← Path B (ADR 0063, [#1224](https://example.com/builders#/task/1224)): zero-dep, deterministic symbol-skeleton generator → docs/repo-map.md + the generated factual block in each nested CLAUDE.md; ranks exported symbols by reference frequency. `--check` = CI gate; regenerated on deploy by ship.js regenerateRepoMap()
@@ -2669,5 +2669,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
2669
2669
  landed since 1.20.4 with no explicit bump. run 36666171516. (task 1002620)
2670
2670
  1.20.6 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2671
2671
  landed since 1.20.5 with no explicit bump. run 36667238912. (task 1002620)
2672
+ 1.20.7 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2673
+ landed since 1.20.6 with no explicit bump. run 36668328505. (task 1002620)
2674
+ 1.20.8 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2675
+ landed since 1.20.7 with no explicit bump. run 36669272909. (task 1002620)
2672
2676
  ---------------------------------------------------------------------------
2673
2677
  ```
@@ -60,7 +60,7 @@ Every one of these talks to the build system. They're grouped by when you'd reac
60
60
 
61
61
  ### Discipline modes — not slash commands any more
62
62
 
63
- The three core crafts no longer have a slash command. `/dev`, `/paint` and `/ideate` were **deleted** when the root instructions split into a role-neutral kernel (`CLAUDE.md`) plus one **role pack** per craft: `docs/packs/engineer.md`, `docs/packs/artist.md`, `docs/packs/ideator.md`. A claimed task's discipline routes you to your pack — `claim.js` prints its path — and you read it. A module-contributed discipline can still ship a skill, which is how `ui` → `/design` below works.
63
+ The three core crafts no longer have a slash command. `/dev`, `/paint` and `/ideate` were **deleted** when the root instructions split into a role-neutral kernel (`CLAUDE.md`) plus one **role pack** per craft: `docs/packs/engineer.md`, `docs/packs/artist.md`, `docs/packs/ideator.md`. A claimed task's discipline routes you to your pack — the Conductor injects its path into your session on the next prompt, and `claim.js` prints a one-line reminder — and you read it. A module-contributed discipline can still ship a skill, which is how `ui` → `/design` below works.
64
64
 
65
65
  ### Design and art pipeline
66
66
 
@@ -1,6 +1,6 @@
1
1
  # Artist pack
2
2
 
3
- > **The role pack for `discipline = artist`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for artists. Read the whole thing before acting — it changes how you *communicate* for the rest of the session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json), which `claim.js` prints on a claim.
3
+ > **The role pack for `discipline = artist`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for artists. Read the whole thing before acting — it changes how you *communicate* for the rest of the session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json); the Conductor injects this pointer into a session holding a claim of this craft (task 1002992).
4
4
 
5
5
  An art session is not the engineer's text-heavy build loop. The artist's subject is how the project **looks and reads** — its visuals, its copy, its voice, the feeling of the thing. A craft is an identity, not a toolchain ([ADR 0272](../adr/0272-a-craft-is-an-identity-not-a-toolchain.md)): an instance has artists whether or not it ships an art pipeline.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Engineer pack
2
2
 
3
- > **The role pack for `discipline = engineer`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for engineers. Read it once at the top of an engineering session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json), which `claim.js` prints on a claim.
3
+ > **The role pack for `discipline = engineer`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for engineers. Read it once at the top of an engineering session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json); the Conductor injects this pointer into a session holding a claim of this craft (task 1002992).
4
4
 
5
5
  Engineering is the project's **default loop**, so this pack introduces no new dynamic — its job is to make the standard explicit and keep you on it. Lean on it hardest when you are new here or running autonomously. (The Ideator pack flips *who drives*; the Artist pack flips *the medium*. This one is the baseline they invert from.)
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Ideator pack
2
2
 
3
- > **The role pack for `discipline = ideator`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for ideators. Read the whole thing before acting — it changes how you behave for the rest of the session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json), which `claim.js` prints on a claim.
3
+ > **The role pack for `discipline = ideator`.** The kernel ([`CLAUDE.md`](../../CLAUDE.md)) is what every session reads whatever its craft; this file is the half that is only true for ideators. Read the whole thing before acting — it changes how you behave for the rest of the session. Registered in [`scripts/gds/discipline-modes.json`](../../scripts/gds/discipline-modes.json); the Conductor injects this pointer into a session holding a claim of this craft (task 1002992).
4
4
 
5
5
  An ideation session is not the build-and-ship loop, and **it needs no claim**. "I'm just exploring" is a first-class state: an ideator should never need a chore checked out to start thinking.
6
6
 
@@ -198,7 +198,7 @@ function fmtMins(n) {
198
198
  return m ? `~${h}h${m}m` : `~${h}h`;
199
199
  }
200
200
 
201
- // Mirrors scripts/gds/discipline-modes.json, which is what claim.js prints. 'ui'
201
+ // Mirrors scripts/gds/discipline-modes.json, which routes a claim to its playbook. 'ui'
202
202
  // was missing here, so a UI task's card sent the builder to /dev while the claim
203
203
  // had just sent them to /design (task 1003487).
204
204
  //
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.20.6",
3
+ "version": "1.20.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.20.6",
9
+ "version": "1.20.8",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.20.6",
3
+ "version": "1.20.8",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -8088,5 +8088,17 @@
8088
8088
  "id": "1004392",
8089
8089
  "text": "A goal's checklist item no longer ticks itself off just because some linked work shipped. Once the work is done it now shows \"Awaiting UAT\", and it closes only when someone who did not build it tries it on the live site and up"
8090
8090
  }
8091
+ ],
8092
+ "1.20.7": [
8093
+ {
8094
+ "id": "1002458",
8095
+ "text": "The starter task that asks a new builder to add a test now finds its own targets from the current code, so it no longer goes out of date every time someone completes it."
8096
+ }
8097
+ ],
8098
+ "1.20.8": [
8099
+ {
8100
+ "id": "1002992",
8101
+ "text": "When you claim a task, your assistant is now told on its own which playbook to work from: engineer, artist, ideator or UI. Before, the instructions only reached it if someone read the claim output. Each workspace gets only its"
8102
+ }
8091
8103
  ]
8092
8104
  }
@@ -8,7 +8,6 @@
8
8
  // builder knows the parallel-safety boundary they're working within.
9
9
 
10
10
  const { execSync } = require('node:child_process');
11
- const fs = require('node:fs');
12
11
  const path = require('node:path');
13
12
  const { cliClient, requireSession, fmtTouches, printOnboardingNudge, rewardPolicy, costPlusOnlyNote, detectWorktreeName, cliExit } = require('./cli-lib');
14
13
  const { nextNumbers, padAdr, padMig } = require('./next-number');
@@ -60,40 +59,30 @@ async function printRelevantLearnings(task) {
60
59
  }
61
60
  }
62
61
 
63
- // Discipline-fork at claim (task 1267; pack-aware since task 1002990). If the
64
- // claimed task's `discipline` has an entry in the role registry
65
- // (discipline-modes.json), print a directive so the session opens that craft's
66
- // playbook instead of working the task the default way. Since the kernel/pack
67
- // split a CORE craft names a `pack` — a markdown role pack under docs/packs/
68
- // carrying what the role-neutral root CLAUDE.md deliberately leaves out — while a
69
- // module-contributed discipline may still name a `skill` slash-command (`ui` ->
70
- // /design). This IS the whole fork — one data lookup on the claim the builder
71
- // already runs; no hook, the Conductor untouched. `discipline` is already a
72
- // column, so there is no classification step here. Fail-open in every branch: a
73
- // missing or invalid map, or a discipline with no entry, prints nothing and never
74
- // breaks a successful claim. (The registry itself is NOT trusted to be intact by
75
- // luck: fitness.js hard-fails CI when an entry names a pack that is not in the
76
- // tree, so this fail-open path cannot silently swallow a broken registry.)
77
- function printDisciplineMode(task) {
62
+ // The claimed task's craft (task 1267; pack-aware since 1002990; INJECTED since
63
+ // 1002992). The directive itself — which role pack or skill this craft works
64
+ // from — no longer prints here: GET /me carries it on the active claim and the
65
+ // Conductor relays it on the session's next prompt (src/bongos/craft-mode.js), so
66
+ // it reaches the session whether or not anyone read the claim output. What stays
67
+ // is ONE role indicator line, and the side effect that must happen where the claim
68
+ // happens: landing the mode's module-owned skills (materializeModeSkills below).
69
+ //
70
+ // Reads the registry beside this CLI (the file fitness.js hard-fails on when a
71
+ // pack is missing), through the same helper the server uses. Fail-open in every
72
+ // branch: a missing or invalid map, or a discipline with no entry, prints nothing
73
+ // and never breaks a successful claim.
74
+ function printRoleLine(task) {
78
75
  let mode = null;
79
76
  try {
80
77
  const discipline = task && task.discipline;
81
78
  if (!discipline) return;
82
- const raw = fs.readFileSync(path.join(__dirname, 'discipline-modes.json'), 'utf8');
83
- const modes = (JSON.parse(raw) || {}).modes || {};
84
- mode = modes[discipline];
79
+ const { readModes, roleLine } = require('../../src/bongos/craft-mode');
80
+ mode = readModes(path.join(__dirname, 'discipline-modes.json'))[discipline] || null;
85
81
  if (!mode || !mode.directive) return;
86
- // The pointer a session actually follows. A pack is a file to READ (there is no
87
- // slash command behind it any more); a skill is one to INVOKE. Naming the wrong
88
- // verb sends the session hunting for a command that was deleted, so the two
89
- // shapes print differently and an entry with neither prints only the label.
90
- const opener = mode.pack ? `read ${mode.pack}` : (mode.skill ? `/${mode.skill}` : null);
91
82
  console.log('');
92
- console.log(`▶ ${mode.label || 'Working mode'}${opener ? ` — ${opener}` : ''}`);
93
- console.log(` ${mode.directive}`);
94
- if (mode.pack) console.log(` Your pack: ${mode.pack} (the kernel is CLAUDE.md; this is the half that is only true for your craft)`);
83
+ console.log(roleLine(mode));
95
84
  } catch (_) {
96
- // never let the mode hint break a successful claim
85
+ // never let the role line break a successful claim
97
86
  return;
98
87
  }
99
88
  materializeModeSkills(mode);
@@ -719,10 +708,10 @@ async function main() {
719
708
  console.log('');
720
709
  console.log(task.description);
721
710
  }
722
- // Discipline-fork: route ideator (and any future discipline with a mapped
723
- // playbook) into its skill. Printed right after the description so it's the
724
- // last thing the builder reads before deciding how to work — task 1267.
725
- printDisciplineMode(task);
711
+ // The craft's role line (and, for a mode that opts in, its module-owned
712
+ // skills). The full directive reaches the session through the Conductor —
713
+ // task 1002992.
714
+ printRoleLine(task);
726
715
  // task 1004202: a task that changes a page is told to use /design and get its
727
716
  // human's OK on the before/after. A nudge, never a gate: gating on that OK would
728
717
  // put a person's approval in the land path, which ADR 0162 retired.
@@ -782,4 +771,4 @@ if (require.main === module) {
782
771
  });
783
772
  }
784
773
 
785
- module.exports = { formatClaimFailure, claimErrorInfo, goalMembershipOfferPlan, materializeModeSkills, worktreeDetectionNote };
774
+ module.exports = { formatClaimFailure, claimErrorInfo, goalMembershipOfferPlan, materializeModeSkills, printRoleLine, worktreeDetectionNote };
@@ -1,5 +1,5 @@
1
1
  {
2
- "_doc": "The ROLE REGISTRY: discipline -> the operating playbook that craft works from (task 1267; reshaped by task 1002990). Since the kernel/pack split, a CORE craft names a `pack` — a markdown role pack under docs/packs/ that carries everything the root CLAUDE.md kernel deliberately does not, because it is true for one craft only. A module-contributed discipline may instead name a `skill` (a slash-command playbook under .claude/skills/), which is how `ui` -> /design still works (ADR 0272 keeps ui-design's contribution unchanged). An entry may carry both; it must carry at least one. claim.js reads this after a successful claim and prints the entry's `directive` plus its pack path, so the session opens the right playbook. There is NO classification step at claim time — `discipline` is already a column on the task. One carrier (the claim the builder already runs), one data lookup, no hooks, the Conductor untouched. A missing or invalid version of this file must never break a claim (claim.js fails open) — but fitness.js DOES hard-fail CI when an entry names a pack that is not in the tree, so the fail-open runtime cannot hide a broken registry from the build. GOVERNOR IS DEFERRED: three packs, not four, until the owner decides (criterion wa6-kernel-and-packs). A mode entry may also set \"materializeModuleSkills\": true to have the claim land that mode's module-owned skills into this checkout's .claude/skills/ (task 1003486) — opt-in per discipline, core-checkout only, and fail-open like the hint itself.",
2
+ "_doc": "The ROLE REGISTRY: discipline -> the operating playbook that craft works from (task 1267; reshaped by task 1002990). Since the kernel/pack split, a CORE craft names a `pack` — a markdown role pack under docs/packs/ that carries everything the root CLAUDE.md kernel deliberately does not, because it is true for one craft only. A module-contributed discipline may instead name a `skill` (a slash-command playbook under .claude/skills/), which is how `ui` -> /design still works (ADR 0272 keeps ui-design's contribution unchanged). An entry may carry both; it must carry at least one. GET /me reads this (src/bongos/craft-mode.js) and puts each active claim's entry — `directive` plus pack path — on the claim as `craft_mode`; the Conductor hook injects the one for the claim bound to the session's worktree, so the session opens the right playbook without anyone reading terminal output (task 1002992). claim.js reads it too, printing only the one role line and running `materializeModuleSkills`. There is NO classification step — `discipline` is already a column on the task. One registry, never a server-side copy. A missing or invalid version of this file must never break a claim (claim.js fails open) — but fitness.js DOES hard-fail CI when an entry names a pack that is not in the tree, so the fail-open runtime cannot hide a broken registry from the build. GOVERNOR IS DEFERRED: three packs, not four, until the owner decides (criterion wa6-kernel-and-packs). A mode entry may also set \"materializeModuleSkills\": true to have the claim land that mode's module-owned skills into this checkout's .claude/skills/ (task 1003486) — opt-in per discipline, core-checkout only, and fail-open like the hint itself.",
3
3
  "modes": {
4
4
  "engineer": {
5
5
  "pack": "docs/packs/engineer.md",