@bongos/core 1.20.8 → 1.20.10

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 (74) hide show
  1. package/.bongos-core.json +84 -79
  2. package/.claude/skills/ask-for-help/SKILL.md +6 -0
  3. package/.claude/skills/backlog-review/SKILL.md +6 -0
  4. package/.claude/skills/blocker-review/SKILL.md +6 -0
  5. package/.claude/skills/blocker-solve/SKILL.md +6 -0
  6. package/.claude/skills/bug-triage/SKILL.md +6 -0
  7. package/.claude/skills/builder-backup/SKILL.md +6 -0
  8. package/.claude/skills/builder-claim/SKILL.md +6 -0
  9. package/.claude/skills/builder-cost/SKILL.md +6 -0
  10. package/.claude/skills/builder-end/SKILL.md +6 -0
  11. package/.claude/skills/builder-exit/SKILL.md +6 -0
  12. package/.claude/skills/builder-key/SKILL.md +6 -0
  13. package/.claude/skills/builder-reauth/SKILL.md +6 -0
  14. package/.claude/skills/builder-redteam/SKILL.md +6 -0
  15. package/.claude/skills/builder-release/SKILL.md +6 -0
  16. package/.claude/skills/builder-sequence/SKILL.md +6 -0
  17. package/.claude/skills/builder-setup/SKILL.md +6 -0
  18. package/.claude/skills/builder-ship/SKILL.md +6 -0
  19. package/.claude/skills/builder-stage/SKILL.md +6 -0
  20. package/.claude/skills/builder-start/SKILL.md +6 -0
  21. package/.claude/skills/collab-review/SKILL.md +6 -0
  22. package/.claude/skills/design/SKILL.md +6 -0
  23. package/.claude/skills/design-sync/SKILL.md +6 -0
  24. package/.claude/skills/feedback/SKILL.md +6 -0
  25. package/.claude/skills/figma-design-sync/SKILL.md +6 -0
  26. package/.claude/skills/fix-task/SKILL.md +6 -0
  27. package/.claude/skills/goal-create/SKILL.md +6 -0
  28. package/.claude/skills/goal-review/SKILL.md +6 -0
  29. package/.claude/skills/goal-uat/SKILL.md +6 -0
  30. package/.claude/skills/grade-audit/SKILL.md +6 -0
  31. package/.claude/skills/grade-recover/SKILL.md +6 -0
  32. package/.claude/skills/grader-health/SKILL.md +6 -0
  33. package/.claude/skills/idea-triage/SKILL.md +6 -0
  34. package/.claude/skills/merge-mode/SKILL.md +6 -0
  35. package/.claude/skills/new-project/SKILL.md +6 -0
  36. package/.claude/skills/otb-character-review/SKILL.md +6 -0
  37. package/.claude/skills/otb-design-review/SKILL.md +6 -0
  38. package/.claude/skills/otb-feedback-capture/SKILL.md +6 -0
  39. package/.claude/skills/otb-figma-sync/SKILL.md +6 -0
  40. package/.claude/skills/otb-tile-generate/SKILL.md +6 -0
  41. package/.claude/skills/planning-session/SKILL.md +6 -0
  42. package/.claude/skills/priority-session/SKILL.md +6 -0
  43. package/.claude/skills/read-session-export/SKILL.md +6 -0
  44. package/.claude/skills/recall/SKILL.md +6 -0
  45. package/.claude/skills/scan-before-install/SKILL.md +6 -0
  46. package/.claude/skills/session-handoff/SKILL.md +6 -0
  47. package/.claude/skills/ship-check/SKILL.md +6 -0
  48. package/.claude/skills/status/SKILL.md +6 -0
  49. package/.claude/skills/strand-fix/SKILL.md +6 -0
  50. package/.claude/skills/tweak/SKILL.md +6 -0
  51. package/.claude/skills/worktree-clean/SKILL.md +6 -0
  52. package/docs/module-api-changelog.md +4 -0
  53. package/migrations/core_263_closeness_history_indexes.sql +56 -0
  54. package/modules/lifecycle/closeness.js +7 -7
  55. package/modules/ui-design/skills/brandkit/SKILL.md +6 -0
  56. package/modules/ui-design/skills/design-taste-frontend/SKILL.md +6 -0
  57. package/modules/ui-design/skills/design-taste-frontend-v1/SKILL.md +6 -0
  58. package/modules/ui-design/skills/gpt-taste/SKILL.md +6 -0
  59. package/modules/ui-design/skills/high-end-visual-design/SKILL.md +6 -0
  60. package/modules/ui-design/skills/image-to-code/SKILL.md +6 -0
  61. package/modules/ui-design/skills/imagegen-frontend-mobile/SKILL.md +6 -0
  62. package/modules/ui-design/skills/imagegen-frontend-web/SKILL.md +6 -0
  63. package/modules/ui-design/skills/impeccable/SKILL.md +6 -0
  64. package/modules/ui-design/skills/industrial-brutalist-ui/SKILL.md +6 -0
  65. package/modules/ui-design/skills/minimalist-ui/SKILL.md +6 -0
  66. package/modules/ui-design/skills/redesign-existing-projects/SKILL.md +6 -0
  67. package/modules/ui-design/skills/stitch-design-taste/SKILL.md +6 -0
  68. package/modules/ui-design/skills/style/SKILL.md +6 -0
  69. package/package-lock.json +2 -2
  70. package/package.json +1 -1
  71. package/release-notes.json +12 -0
  72. package/src/module-api.js +1 -1
  73. package/tests/closeness.mjs +18 -3
  74. package/tests/speciality_skills.mjs +42 -0
@@ -0,0 +1,56 @@
1
+ -- core_263 — index the history the closeness signals join on (task 1003268)
2
+ --
3
+ -- modules/lifecycle/closeness.js builds a builder's "who have I worked near" graph
4
+ -- from three self-joins (task 1003174): overlapping CLAIMS in a shared goal,
5
+ -- SESSION LOGS on a shared goal's tasks, and SHIPS in a shared goal. The grader of
6
+ -- 1003174 flagged that the join keys might be unindexed, which would make each
7
+ -- query scale with the whole table instead of with one builder's goals. Checked
8
+ -- against the tree, key by key:
9
+ --
10
+ -- tasks.goal_id — ALREADY COVERED. The task was filed before core_228 added
11
+ -- idx_tasks_goal ON tasks (goal_id). A second index on the
12
+ -- same column would only cost writes, so none is added.
13
+ -- claims.builder_id — only idx_claims_builder_active (003), partial on
14
+ -- released_at IS NULL. Closeness reads SETTLED claims
15
+ -- (`mine.builder_id = $1 AND mine.claimed_at > now() - …`),
16
+ -- which a partial-on-active index cannot serve. Added below,
17
+ -- with claimed_at second so the time window is a range scan.
18
+ -- claims.task_id — only the partial UNIQUE on active claims (003). The join
19
+ -- `other.task_id = t_other.id` walks every claim, settled
20
+ -- ones included. Added below.
21
+ -- tasks.shipped_by — idx_tasks_needs_rebase (core_193) is partial on
22
+ -- needs_rebase, and idx_tasks_shipped_by_shipped_at
23
+ -- (core_228) is partial on status = 'shipped'. The ship
24
+ -- signal filters `shipped_by = $1 AND goal_id IS NOT NULL`
25
+ -- with no status predicate, so the planner can use neither.
26
+ -- Added below, partial on exactly that query's predicates.
27
+ -- session_logs — covered by idx_session_logs_task / _builder (003).
28
+ --
29
+ -- Not urgent at today's size (a few thousand tasks, fifteen builders); this closes
30
+ -- the gap before it grows rather than after it hurts.
31
+ --
32
+ -- Additive and idempotent: indexes only, no column, no constraint, no data. Safe
33
+ -- to run forward against a live database, and an older release running against it
34
+ -- just has unused indexes. Rollback is DROP INDEX.
35
+ --
36
+ -- NOT a lifecycle_* module migration: `tasks` and `claims` are CORE tables, and a
37
+ -- module migration may only touch its own namespaced tables (fitness.js
38
+ -- checkModuleMigrationsAdditive, ADR 0083 Decision #5). That boundary is why this
39
+ -- was split out of task 1003174 in the first place.
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_claims_builder_history
42
+ ON claims (builder_id, claimed_at);
43
+
44
+ CREATE INDEX IF NOT EXISTS idx_claims_task_all
45
+ ON claims (task_id);
46
+
47
+ CREATE INDEX IF NOT EXISTS idx_tasks_shipped_by_goal
48
+ ON tasks (shipped_by, goal_id)
49
+ WHERE shipped_by IS NOT NULL AND goal_id IS NOT NULL;
50
+
51
+ COMMENT ON INDEX idx_claims_builder_history IS
52
+ 'Closeness (modules/lifecycle/closeness.js): a builder''s settled claims in a time window. idx_claims_builder_active is partial on active claims and cannot serve history.';
53
+ COMMENT ON INDEX idx_claims_task_all IS
54
+ 'Closeness: joins every claim (settled too) on task_id. The 003 unique index covers active claims only.';
55
+ COMMENT ON INDEX idx_tasks_shipped_by_goal IS
56
+ 'Closeness ship signal: shipped_by = $1 AND goal_id IS NOT NULL, no status predicate, so core_228''s status-partial index does not apply.';
@@ -37,13 +37,13 @@
37
37
  // The gate FAILS CLOSED: a consent read that throws or returns null yields the
38
38
  // empty set, and so the empty graph.
39
39
  //
40
- // A KNOWN PERFORMANCE GAP, measured rather than assumed. The signal joins key on
41
- // tasks.goal_id (NO index), claims.builder_id and claims.task_id (indexed only
42
- // partially, on ACTIVE claims — closeness reads history) and tasks.shipped_by
43
- // (partial too). At today's size that is fine; it scales with total table size
44
- // rather than goal size. The indexes belong in a core_ migration, not here — a
45
- // module migration may only touch its own lifecycle_ tables (ADR 0083 §5), and
46
- // the fitness check enforces it. Filed with the SQL as task 1003268.
40
+ // INDEXES. The signal joins key on tasks.goal_id (idx_tasks_goal, core_228),
41
+ // claims.builder_id + claimed_at and claims.task_id over HISTORY, not just active
42
+ // claims, and tasks.shipped_by + goal_id with no status predicate. The last three
43
+ // were unindexed for this shape and are added by migrations/core_263 (from
44
+ // task 1003268). They live in a core_ migration, not here — a module migration may only
45
+ // touch its own lifecycle_ tables (ADR 0083 §5), and the fitness check enforces it.
46
+ // Change a join key or predicate here and re-check that migration still serves it.
47
47
  //
48
48
  // Reaches core only through the doorway (ADR 0083). The core tables it reads
49
49
  // (claims, tasks, session_logs, builders) are read-only here.
@@ -5,6 +5,12 @@ description: >-
5
5
  first, holds the logo standard and the five concept methods, and lands the system as the instance's own
6
6
  materials — the mark as SVG, the colours as the pack, the type as its faces. Triggers on "brand kit",
7
7
  "identity system", "logo system". Never generates a logo, wordmark or UI mockup.
8
+ plain: >-
9
+ Builds the project's visual identity, its logo, colours and typefaces, as the project's own files.
10
+ reach-for: >-
11
+ When the project needs a brand identity, or its identity needs pulling together.
12
+ cost: >-
13
+ Uses your session. It adds brand files to the project and never generates a logo image.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  Says the design read in one line, sets three dials (variance, motion, density), locks one world for the
6
6
  whole page, and ends on a pre-flight the kit measures. Triggers on "design a landing page", "make this not
7
7
  look templated", "taste pass", "anti-slop". Not for dashboards or native mobile.
8
+ plain: >-
9
+ The default way to give a landing page or marketing page a strong, considered look that does not feel like a template.
10
+ reach-for: >-
11
+ When a landing or marketing page looks generic.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  gets exactly this behaviour while the default (design-taste-frontend) evolves separately. A fixed triple of
6
6
  dials, the layout bans, full interaction cycles, and a named vocabulary of premium patterns. Triggers on
7
7
  "design-taste-frontend-v1", "the fixed dials", "the pattern vocabulary".
8
+ plain: >-
9
+ The earlier version of the landing-page style guide, kept so work that asked for it gets exactly the same results.
10
+ reach-for: >-
11
+ Only when a task asks for this older version by name.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  every other one. A written plan block before any markup, derived deterministically from the route; the
6
6
  four-stage attention-interest-desire-action structure; an ultra-wide hero; a dense tile grid with zero empty
7
7
  cells. Triggers on "it looks generic", "award-tier", "anti-default".
8
+ plain: >-
9
+ A stricter style pass for a long, persuasive page that keeps coming out looking like every other one.
10
+ reach-for: >-
11
+ When a scrolling sales or landing page still looks generic after a first try.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  one layout archetype per project, the container anatomy, the pill button, the spatial rhythm, the motion
6
6
  choreography inside the Kill Switch, the mobile collapse, then a pre-output checklist. Triggers on "make it
7
7
  feel premium", "agency-grade", "this looks cheap", "the polish pass".
8
+ plain: >-
9
+ Makes a page look expensive and professionally made, while staying in the project's own style.
10
+ reach-for: >-
11
+ When a page looks cheap or unfinished.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  design source of truth is the owner's reference images and the instance's world, read per image and
6
6
  extracted into a full spec before a line is written. Triggers on "build this from the reference", "implement
7
7
  the mock faithfully". Never generates a section, comp or screen.
8
+ plain: >-
9
+ Builds a page faithfully from reference pictures you provide, studying each one first.
10
+ reach-for: >-
11
+ When you have images of how a page should look and want it built to match.
12
+ cost: >-
13
+ Uses your session. It builds the page and never generates images itself.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  portrait plates and hero objects for the 390 and 320 compositions the kit renders, sized for the fold and
6
6
  clear of what a phone reserves, with a sidecar beside every file. Triggers on "a plate for the mobile hero",
7
7
  "the masthead at 390". Never a screen, a phone mockup or code.
8
+ plain: >-
9
+ Makes the large picture at the top of a page, sized for phones, with no text in it.
10
+ reach-for: >-
11
+ When a page's phone layout needs its main picture.
12
+ cost: >-
13
+ Paid: each image is made on the project's image key. It adds the picture files to the project.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  objects and atmosphere backdrops for the slots a composition already has — never one per section, never a
6
6
  screen, never a UI comp, and no page code. One material, light and camera across the family, landed with a
7
7
  provenance sidecar. Triggers on "make a hero plate", "an atmosphere backdrop".
8
+ plain: >-
9
+ Makes the large background or hero pictures for a web page, with no text in them.
10
+ reach-for: >-
11
+ When a page needs its main picture or a background image.
12
+ cost: >-
13
+ Paid: each image is made on the project's image key. It adds the picture files to the project.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  ("impeccable audit /projects"). Sixteen playbooks — shape, audit, critique, polish, harden, animate,
6
6
  typeset, colorize, layout, adapt, distill, clarify, onboard, optimize, document, extract — one per request.
7
7
  Triggers on "impeccable", "critique this page", "audit the UI". Web surfaces only.
8
+ plain: >-
9
+ A toolbox of design checks and fixes for a web page, such as a review, a polish, better type or better layout, one job at a time.
10
+ reach-for: >-
11
+ When you want a page reviewed or improved in one specific way.
12
+ cost: >-
13
+ Uses your session. A review changes nothing; a fix changes the page.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  per project (Swiss industrial print or dark tactical terminal, never mixed), massive uppercase display
6
6
  against tracked-out mono metadata, strict grid anchoring, zero corner rounding, halftone and scanline
7
7
  degradation inside the Kill Switch. Triggers on "brutalist", "industrial", "make it raw".
8
+ plain: >-
9
+ Gives a page a raw, mechanical look, like a technical document or a control terminal.
10
+ reach-for: >-
11
+ When you want a bold, stark look.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  whitespace first, a capped measure, one display job and one body job, exactly one hairline weight for every
6
6
  border, flat tile cards with no shadow, entry motion inside the Kill Switch. Triggers on "make it minimal",
7
7
  "clean and editorial", "this feels busy". Declines dense surfaces.
8
+ plain: >-
9
+ Gives a page a calm, clean look built from text and white space.
10
+ reach-for: >-
11
+ When a page feels too busy.
12
+ cost: >-
13
+ Uses your session. It changes the page, and you check it on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  breaking it. Three fixed steps — scan the stack, diagnose against a written audit, apply targeted fixes —
6
6
  with the instance's world as the answer key and a fixed impact-per-risk fix order. Triggers on "redesign
7
7
  this", "upgrade the existing page", "audit this UI".
8
+ plain: >-
9
+ Improves the look of an existing site in place, without rebuilding it or breaking what works.
10
+ reach-for: >-
11
+ When an existing page or app needs a visual upgrade.
12
+ cost: >-
13
+ Uses your session. It changes the existing pages, and you check them on a preview.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  platform's own frontmatter shape. Four dials with named bands and stated defaults, then eight fixed sections
6
6
  pairing descriptive language with exact values. The thirteen colours are transcribed from the instance's
7
7
  pack, never invented. Triggers on "a design brief for Stitch".
8
+ plain: >-
9
+ Writes a design brief in the project's style for an outside screen-design tool such as Google Stitch.
10
+ reach-for: >-
11
+ When you want to design screens in Stitch using the project's look.
12
+ cost: >-
13
+ Uses your session. It writes one brief document and changes no pages.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
@@ -5,6 +5,12 @@ description: >-
5
5
  the fifteen-token contract, and proves it clean before it lands. Four steps and no more — SEARCH, CREATE,
6
6
  PROVE, ADOPT. Triggers on "/style", "make a look", "author a style", "I want our own theme", "add a style to
7
7
  the library".
8
+ plain: >-
9
+ A short guided session for creating your own look for the project, checked before it is used.
10
+ reach-for: >-
11
+ When you want the project to have its own theme.
12
+ cost: >-
13
+ Uses your session. The new look is only used once you choose to adopt it.
8
14
  ---
9
15
 
10
16
  <!-- BEGIN PLATFORM PREAMBLE · ui-design module · one block, byte-identical in every skill the module ships (vendored or rebuilt in-house) so an upstream refresh is a three-way merge; the source is modules/ui-design/skills/PREAMBLE.md and tests/ui_design_skills.mjs fails on drift -->
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.20.8",
3
+ "version": "1.20.10",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.20.8",
9
+ "version": "1.20.10",
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.8",
3
+ "version": "1.20.10",
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",
@@ -8100,5 +8100,17 @@
8100
8100
  "id": "1002992",
8101
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
8102
  }
8103
+ ],
8104
+ "1.20.9": [
8105
+ {
8106
+ "id": "1003268",
8107
+ "text": "Added three database lookups so the 'who have I worked near' view stays fast as the project grows. Nothing changes on screen today."
8108
+ }
8109
+ ],
8110
+ "1.20.10": [
8111
+ {
8112
+ "id": "1004403",
8113
+ "text": "When you adopt a speciality, each skill it offers is now explained in plain words: what it does, when you would use it, and what it costs, including which ones spend money. Before, those explanations were guessed from technica"
8114
+ }
8103
8115
  ]
8104
8116
  }
package/src/module-api.js CHANGED
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
75
75
  // MAJOR (see allowBoxScope below): passes the request through untouched.
76
76
  function deprecatedNoopMiddleware(_req, _res, next) { next(); }
77
77
 
78
- const CORE_VERSION = '1.20.8'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
78
+ const CORE_VERSION = '1.20.10'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
79
79
 
80
80
  // A namespaced logger so a module's log lines are attributable + consistent.
81
81
  // Usage: const log = api.logger('discord'); log.info('mounted');
@@ -434,10 +434,25 @@ test('the index gap the grader raised is ANSWERED, not left open', () => {
434
434
  // and these are core tables. That makes it a core_ migration, which needs a
435
435
  // reserved number and human eyes. Filed as task 1003268 with the SQL.
436
436
  //
437
- // This test pins the REFERENCE so the finding cannot be quietly dropped: if
438
- // someone lands the indexes and deletes the note, they should delete this too.
437
+ // Task 1003268 then landed them as migrations/core_263 — minus a goal_id index,
438
+ // because core_228 had already added idx_tasks_goal. This test now pins that the
439
+ // source still points at the migration and that the migration carries every
440
+ // index the three signals need, so a later edit cannot drop one quietly.
439
441
  assert.match(SRC, /task 1003268/,
440
- 'the closeness source cites the follow-up that carries the indexes');
442
+ 'the closeness source cites the task that carries the indexes');
443
+ assert.match(SRC, /core_263/, 'and names the migration that serves its joins');
444
+ const core = fs.readFileSync(path.join(ROOT, 'migrations', 'core_263_closeness_history_indexes.sql'), 'utf8');
445
+ for (const [name, shape] of [
446
+ ['idx_claims_builder_history', /ON claims \(builder_id, claimed_at\)/],
447
+ ['idx_claims_task_all', /ON claims \(task_id\)/],
448
+ ['idx_tasks_shipped_by_goal', /ON tasks \(shipped_by, goal_id\)/],
449
+ ]) {
450
+ assert.match(core, new RegExp(`CREATE INDEX IF NOT EXISTS ${name}\\b`), `${name} is created`);
451
+ assert.match(core, shape, `${name} has the shape the closeness join needs`);
452
+ }
453
+ const goalIdx = fs.readFileSync(path.join(ROOT, 'migrations', 'core_228_idea_inbox_captured_by_idx.sql'), 'utf8');
454
+ assert.match(goalIdx, /CREATE INDEX IF NOT EXISTS idx_tasks_goal ON tasks \(goal_id\)/,
455
+ 'tasks.goal_id is served by core_228, which is why core_263 does not repeat it');
441
456
  const files = fs.readdirSync(path.join(ROOT, 'modules', 'lifecycle', 'migrations'));
442
457
  assert.ok(!files.some((f) => /closeness/i.test(f)),
443
458
  'and no module migration tries to index a core table again');
@@ -73,6 +73,48 @@ await test('every skill in the real tree reads a real description — none is a
73
73
  assert.deepEqual(bad, [], `these would teach nothing in the walkthrough: ${bad.join(', ')}`);
74
74
  });
75
75
 
76
+ // task 1004403: every skill a speciality could offer — every core skill and
77
+ // every module's, enabled here or not — carries its own people-facing lines, so
78
+ // the walkthrough never has to derive them and a new skill cannot arrive without.
79
+ const { JARGON_TERMS } = require('../modules/sessions/accessibility.js');
80
+ // The words task 1004403 named as the ones the derived text leaked, plus the
81
+ // repo nouns a newcomer would not know.
82
+ const SKILL_JARGON = ['DB', 'grep', 'grepping', 'rank-scoped', 'status=', 'residue', 'criterion', 'criteria', 'touches[]', 'branch', 'commit', 'diff', 'SHA', 'CI', 'repo', 'PR'];
83
+ const everySkill = () => skills.installedSkills({ coreRoot: ROOT, isModuleEnabled: () => true });
84
+
85
+ await test('every installable skill carries plain, reach-for and cost — none is derived', () => {
86
+ const all = [...everySkill().values()];
87
+ assert.ok(all.length >= 60, `the whole tree was read (${all.length})`);
88
+ const missing = all.flatMap((s) => ['plain', 'reachFor', 'cost'].filter((k) => !s[k] || s[k].length < 15).map((k) => `${s.name}.${k}`));
89
+ assert.deepEqual(missing, [], 'add plain: / reach-for: / cost: to the SKILL.md frontmatter, written for someone with no engineering background');
90
+ const derived = all.filter((s) => { const d = skills.explainSkill(s).derived; return d.does || d.reachFor || d.cost; }).map((s) => s.name);
91
+ assert.deepEqual(derived, [], 'the walkthrough shows the author\'s own words for every skill');
92
+ });
93
+
94
+ await test('the people-facing lines stay out of the vocabulary they exist to translate', () => {
95
+ const banned = [...JARGON_TERMS, ...SKILL_JARGON];
96
+ const hits = [];
97
+ for (const s of everySkill().values()) {
98
+ for (const k of ['plain', 'reachFor', 'cost']) {
99
+ for (const term of banned) {
100
+ const re = new RegExp(`(^|[^A-Za-z])${term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}([^A-Za-z]|$)`, /^[A-Z+-]+$/.test(term) ? '' : 'i');
101
+ if (re.test(s[k] || '')) hits.push(`${s.name}.${k}: "${term}"`);
102
+ }
103
+ }
104
+ }
105
+ assert.deepEqual(hits, []);
106
+ });
107
+
108
+ await test('a skill with a paid step says so in its cost line', () => {
109
+ // The ones whose run spends money: every hand-in pays for a quality review,
110
+ // and image generation is billed per image. Named, so dropping the word from
111
+ // one of them is caught rather than trusted.
112
+ const paid = ['builder-ship', 'fix-task', 'builder-sequence', 'grade-recover', 'tweak', 'otb-tile-generate', 'imagegen-frontend-web', 'imagegen-frontend-mobile'];
113
+ const all = everySkill();
114
+ const quiet = paid.filter((n) => !/\bpaid\b|costs money/i.test((all.get(n) || {}).cost || ''));
115
+ assert.deepEqual(quiet, []);
116
+ });
117
+
76
118
  await test('explainSkill splits a model-facing description into what it does, when, and what it costs', () => {
77
119
  const e = skills.explainSkill({
78
120
  name: 'goal-review', source: 'core',