@bongos/core 1.19.1008 → 1.19.1010
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 +40 -15
- package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +28 -0
- package/docs/adr/0331-the-sky-is-the-ideators-home.md +103 -0
- package/docs/adr/README.md +1 -0
- package/docs/design/ideator-surface-direction.md +4 -2
- package/docs/module-api-changelog.md +4 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/fixtures/ideator-prefold/README.md +36 -0
- package/tests/fixtures/ideator-prefold/ideas.html.baseline +210 -0
- package/tests/fixtures/ideator-prefold/ideas.js.baseline +962 -0
- package/tests/ideator_one_line_path_proof.mjs +338 -0
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.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.1010",
|
|
6
|
+
"core_contract": "1.19.1010",
|
|
7
|
+
"source_commit": "2e959a08be544446bcbe4a050128862f651337f6",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-24T21:57:10.279Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 523,
|
|
13
13
|
"agent_docs_stubbed": 26,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2420,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2969,
|
|
20
|
+
"tree_sha256": "1ed928f07118e31d83cb36f2f7c9e00fb8eb421f4e0c174d518a6c659944bae6",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -1632,7 +1632,7 @@
|
|
|
1632
1632
|
{
|
|
1633
1633
|
"path": "docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md",
|
|
1634
1634
|
"mode": "0000644",
|
|
1635
|
-
"sha256": "
|
|
1635
|
+
"sha256": "b3b3e724fb4051c9d034df59c7fa675b2be0d71f78305dcbd9d7d43a97aff222"
|
|
1636
1636
|
},
|
|
1637
1637
|
{
|
|
1638
1638
|
"path": "docs/adr/0228-the-reading-room-owes-a-reference-content-rules-not-a-second-archetype.md",
|
|
@@ -2149,10 +2149,15 @@
|
|
|
2149
2149
|
"mode": "0000644",
|
|
2150
2150
|
"sha256": "39f310d52b3de17e8064eb6ada480e8dc00778d655ac40bfe748890b2d0ff713"
|
|
2151
2151
|
},
|
|
2152
|
+
{
|
|
2153
|
+
"path": "docs/adr/0331-the-sky-is-the-ideators-home.md",
|
|
2154
|
+
"mode": "0000644",
|
|
2155
|
+
"sha256": "414a00aeb897b685a01716ec529da5c33feb875eaf50b8f1b652055b5b2fbf8c"
|
|
2156
|
+
},
|
|
2152
2157
|
{
|
|
2153
2158
|
"path": "docs/adr/README.md",
|
|
2154
2159
|
"mode": "0000644",
|
|
2155
|
-
"sha256": "
|
|
2160
|
+
"sha256": "8e45e2918e9dd36572d35758efcd677e7f9d5020c7f2f59d11f303b47b814fdf"
|
|
2156
2161
|
},
|
|
2157
2162
|
{
|
|
2158
2163
|
"path": "docs/api-reference.md",
|
|
@@ -2222,7 +2227,7 @@
|
|
|
2222
2227
|
{
|
|
2223
2228
|
"path": "docs/design/ideator-surface-direction.md",
|
|
2224
2229
|
"mode": "0000644",
|
|
2225
|
-
"sha256": "
|
|
2230
|
+
"sha256": "00e4a4dc36481241bac90c3b46387a3f6d1ed906be75824b3b1dae31dc979403"
|
|
2226
2231
|
},
|
|
2227
2232
|
{
|
|
2228
2233
|
"path": "docs/design/landing-page-direction-v2.md",
|
|
@@ -2722,7 +2727,7 @@
|
|
|
2722
2727
|
{
|
|
2723
2728
|
"path": "docs/module-api-changelog.md",
|
|
2724
2729
|
"mode": "0000644",
|
|
2725
|
-
"sha256": "
|
|
2730
|
+
"sha256": "982c59cdf01c7f07d25fe1593a21659b31366a6b4b0b09b0350a69a23eba2407"
|
|
2726
2731
|
},
|
|
2727
2732
|
{
|
|
2728
2733
|
"path": "docs/modules-contract.md",
|
|
@@ -8217,12 +8222,12 @@
|
|
|
8217
8222
|
{
|
|
8218
8223
|
"path": "package-lock.json",
|
|
8219
8224
|
"mode": "0000644",
|
|
8220
|
-
"sha256": "
|
|
8225
|
+
"sha256": "493838f2051f8f9c9d9878add2840c5f4e18914607147bbcb4bdea1fcb5559fe"
|
|
8221
8226
|
},
|
|
8222
8227
|
{
|
|
8223
8228
|
"path": "package.json",
|
|
8224
8229
|
"mode": "0000644",
|
|
8225
|
-
"sha256": "
|
|
8230
|
+
"sha256": "addc61bbe9d71187f833dcebcb6cfb7136557ba6782d00270395200501ef9f49"
|
|
8226
8231
|
},
|
|
8227
8232
|
{
|
|
8228
8233
|
"path": "public-docs/index.html",
|
|
@@ -10267,7 +10272,7 @@
|
|
|
10267
10272
|
{
|
|
10268
10273
|
"path": "src/module-api.js",
|
|
10269
10274
|
"mode": "0000644",
|
|
10270
|
-
"sha256": "
|
|
10275
|
+
"sha256": "be4a80ffea151ee7dcc548a28cf928376da1bcce570aa521478ea22657475905"
|
|
10271
10276
|
},
|
|
10272
10277
|
{
|
|
10273
10278
|
"path": "src/module-loader/catalog.js",
|
|
@@ -11599,6 +11604,21 @@
|
|
|
11599
11604
|
"mode": "0000644",
|
|
11600
11605
|
"sha256": "8fd3ae3efc2a2c7f47e605925fec881c76dabe1fe8242ca67354b0a6a346e5e6"
|
|
11601
11606
|
},
|
|
11607
|
+
{
|
|
11608
|
+
"path": "tests/fixtures/ideator-prefold/README.md",
|
|
11609
|
+
"mode": "0000644",
|
|
11610
|
+
"sha256": "d7f6de3e72863a605f75f1de7b8e73bdac7e6dce13c1e89afd9cb314a4c2aa66"
|
|
11611
|
+
},
|
|
11612
|
+
{
|
|
11613
|
+
"path": "tests/fixtures/ideator-prefold/ideas.html.baseline",
|
|
11614
|
+
"mode": "0000644",
|
|
11615
|
+
"sha256": "d7a88db7d9c561dc923a6e80b0573ad7d95aec8ab9ff5a7013eb1c946a8a5827"
|
|
11616
|
+
},
|
|
11617
|
+
{
|
|
11618
|
+
"path": "tests/fixtures/ideator-prefold/ideas.js.baseline",
|
|
11619
|
+
"mode": "0000644",
|
|
11620
|
+
"sha256": "2f532cacb06f0f074c15101c16578f3183104042644d6c8aa0d2e80fdb425b2f"
|
|
11621
|
+
},
|
|
11602
11622
|
{
|
|
11603
11623
|
"path": "tests/fixtures/session-506-digest.json",
|
|
11604
11624
|
"mode": "0000644",
|
|
@@ -12554,6 +12574,11 @@
|
|
|
12554
12574
|
"mode": "0000644",
|
|
12555
12575
|
"sha256": "7b13dcdfb215890100a37f7a88722e4dd937b761fe9fa527b1a549de7016b7e8"
|
|
12556
12576
|
},
|
|
12577
|
+
{
|
|
12578
|
+
"path": "tests/ideator_one_line_path_proof.mjs",
|
|
12579
|
+
"mode": "0000644",
|
|
12580
|
+
"sha256": "f1a131105d64c1c0490c814c13e2e6d067e6649c488c33ad60d9c046bb3d29a9"
|
|
12581
|
+
},
|
|
12557
12582
|
{
|
|
12558
12583
|
"path": "tests/ideator_traceable_proof.mjs",
|
|
12559
12584
|
"mode": "0000644",
|
|
@@ -282,3 +282,31 @@ a straight face.
|
|
|
282
282
|
before its numbers are quoted — a field-name mismatch does not fail, it answers zero.* §9
|
|
283
283
|
already conceded this harness over-built for its question; the other half of that lesson is
|
|
284
284
|
that the part it under-built was the twenty lines that touch reality.
|
|
285
|
+
|
|
286
|
+
## 11. Amendment (2026-09-24) — the project sky takes the goal map's page
|
|
287
|
+
|
|
288
|
+
Recorded by [ADR 0331](0331-the-sky-is-the-ideators-home.md); tasks
|
|
289
|
+
[#1004229](https://cloudbongos.com/builders#/task/1004229)–[#1004233](https://cloudbongos.com/builders#/task/1004233).
|
|
290
|
+
The owner adopted an interactive prototype of the **project sky** as is, and it replaces the goal
|
|
291
|
+
map page. This section says what that changes here, and what it does not.
|
|
292
|
+
|
|
293
|
+
**§1's refusal stands.** There is still no whole-corpus task map, at any density. The project sky
|
|
294
|
+
is §1's own shape — the goal graph as the entry point, the per-goal drill-down as the detail —
|
|
295
|
+
drawn as one page instead of two:
|
|
296
|
+
|
|
297
|
+
- **Tasks are drawn only inside one goal, past a zoom threshold.** That is the per-goal forest
|
|
298
|
+
§10.5 measured as readable (worst case 127 tasks at 85.2px pitch, median 9), not the refused
|
|
299
|
+
1,012-node view. Below the threshold, tasks are **dust density on the rings of the goals beneath
|
|
300
|
+
it, with no identities** — a texture that says how full a goal is, never a disc anybody is asked
|
|
301
|
+
to name. A "show all tasks" toggle remains refused.
|
|
302
|
+
- **The goal map's table survives as the sky's ledger drawer.** §6's table equivalent is kept,
|
|
303
|
+
not dropped; every drawn thing is a row in it, one key away.
|
|
304
|
+
- **The nav slot the goal map was denied is granted to the sky**, under Goals (owner,
|
|
305
|
+
2026-09-24). The goal map page (task 1004105) took no slot on purpose, and a test asserts the
|
|
306
|
+
same; part 4 ([#1004232](https://cloudbongos.com/builders#/task/1004232)) changes the page and
|
|
307
|
+
that test together, with this section as the licence.
|
|
308
|
+
|
|
309
|
+
**Design of record:** [`docs/design/mocks/sky/`](../design/mocks/sky/) — the pixel contract for
|
|
310
|
+
the build. [ADR 0264](0264-the-ten-working-areas.md)'s deletion of the goal *Living project sky*
|
|
311
|
+
([#1000044](https://cloudbongos.com/builders#/goal/1000044)) is superseded by this work, under
|
|
312
|
+
Working area 3.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# 0331 — The sky is the ideator's home, and the project sky takes the goal map's page
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-09-24
|
|
5
|
+
- **Tasks:** [#1004229](https://cloudbongos.com/builders#/task/1004229) (this ADR and the design of record), [#1004230](https://cloudbongos.com/builders#/task/1004230)–[#1004233](https://cloudbongos.com/builders#/task/1004233) (the build)
|
|
6
|
+
- **Goal:** [#1000095](https://cloudbongos.com/builders#/goal/1000095) — criterion `ideator-sky-tells-the-truth`, whose text this ADR rewrites.
|
|
7
|
+
- **Design of record:** [`docs/design/mocks/sky/`](../design/mocks/sky/) — the adopted prototype, and the pixel contract for the build.
|
|
8
|
+
- **Amends:** [ADR 0227](0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md) (§11 there), decision 11 of [`docs/specs/<redacted>.md`](../specs/<redacted>.md).
|
|
9
|
+
|
|
10
|
+
## 1. What happened
|
|
11
|
+
|
|
12
|
+
The owner reviewed an interactive prototype of the **ideator sky** and the **project sky** over
|
|
13
|
+
five rounds on 2026-09-24 and adopted it **as is** — copy, layout, colours, tour text, toggles,
|
|
14
|
+
interactions. That adoption contradicts two things already written down, so this ADR rewrites
|
|
15
|
+
them rather than leaving the build to be graded against a contract nobody meant any more.
|
|
16
|
+
|
|
17
|
+
## 2. The decision
|
|
18
|
+
|
|
19
|
+
**The sky is the ideator's home surface, not a decoration that arrives last.** It replaces
|
|
20
|
+
*Your thinking* for the ideator and it replaces the goal map page for the project.
|
|
21
|
+
|
|
22
|
+
**The rule that survives is the accessibility half, and it is unchanged in force:** the sky is
|
|
23
|
+
never the **only** path to anything it shows. The list drawer — the room — is one key away
|
|
24
|
+
(`L`), and every drawn thing is a row in it. What is dropped is "never load-bearing" and
|
|
25
|
+
"arrives last": those were a sequencing hedge from before there was a design to look at, and
|
|
26
|
+
holding the build to them now would mean shipping the owner's adopted surface as an optional
|
|
27
|
+
extra that nothing routes to.
|
|
28
|
+
|
|
29
|
+
**The five states and the two channels are untouched.** Criterion
|
|
30
|
+
`ideator-sky-tells-the-truth` names a *model* — star, protostar, satellite, remnant, cold body;
|
|
31
|
+
size is what a thought caused and never falls, brightness is how much of that work is still
|
|
32
|
+
alive — and it names it deliberately so the picture may change without the criterion becoming
|
|
33
|
+
unsatisfiable. This amendment changes the picture's standing, not the model.
|
|
34
|
+
|
|
35
|
+
## 3. Why amend ADR 0227 rather than reverse it
|
|
36
|
+
|
|
37
|
+
ADR 0227 refused a **whole-corpus task map** on measured evidence: ~1,357 tasks at 30.2px pitch
|
|
38
|
+
is confetti, and drawing it denser draws forty goals badly while claiming to show a thousand
|
|
39
|
+
tasks. **That refusal stands, and the project sky does not violate it** — it is 0227 §1's own
|
|
40
|
+
prescription, not its refusal:
|
|
41
|
+
|
|
42
|
+
- The entry point is the **goal graph**, as §1 requires.
|
|
43
|
+
- **Tasks are drawn only inside one goal, past a zoom threshold** — the per-goal drill-down §1
|
|
44
|
+
and §10.5 measured as readable (worst case 127 tasks at 85.2px pitch; median 9). Below that
|
|
45
|
+
threshold tasks are **dust density on a goal's rings, with no identities** — a texture that
|
|
46
|
+
says "this goal is full", never a thousand discs nobody can name.
|
|
47
|
+
- The goal map's **table survives as the sky's ledger drawer**, which is 0227 §6's table
|
|
48
|
+
equivalent, kept rather than dropped.
|
|
49
|
+
|
|
50
|
+
The one thing 0227 is genuinely amended on is **placement**: the goal map deliberately took no
|
|
51
|
+
nav slot, and a test asserts that. The owner grants the slot to the project sky, under Goals
|
|
52
|
+
(owner, 2026-09-24). Part 4 changes the page and that test together, with this ADR as the
|
|
53
|
+
licence.
|
|
54
|
+
|
|
55
|
+
Also noted: [ADR 0264](0264-the-ten-working-areas.md) deleted the goal **Living project sky**
|
|
56
|
+
([#1000044](https://cloudbongos.com/builders#/goal/1000044)) in the ten-working-areas cut. That
|
|
57
|
+
deletion is **superseded** — the work is alive again, under Working area 3, as tasks
|
|
58
|
+
[#1004229](https://cloudbongos.com/builders#/task/1004229)–[#1004233](https://cloudbongos.com/builders#/task/1004233).
|
|
59
|
+
|
|
60
|
+
## 4. The two heuristics that must not ship
|
|
61
|
+
|
|
62
|
+
The adopted prototype reads the live ledger for almost everything it draws, but **two things in
|
|
63
|
+
it are guesses**, and the built pages must not present a guess as a ledger fact:
|
|
64
|
+
|
|
65
|
+
1. **An idea's origin** — whether a person or a session filed it — is guessed from the idea's
|
|
66
|
+
text (the `claude layer` toggle).
|
|
67
|
+
2. **"Born of a thought"** — a goal or criterion that came out of an idea — is found by scanning
|
|
68
|
+
text for idea ids.
|
|
69
|
+
|
|
70
|
+
Parts 3 and 4 **hide** both layers. Part 5 replaces them with ledger facts: a `filed_via` column
|
|
71
|
+
and a real born-of-a-thought read. A heuristic drawn in the sky would be indistinguishable from
|
|
72
|
+
the facts beside it, which is the exact failure the criterion exists to prevent.
|
|
73
|
+
|
|
74
|
+
## 5. Consequences
|
|
75
|
+
|
|
76
|
+
- The build (parts 2–5) is graded against `docs/design/mocks/sky/sky.template.html` as a **pixel
|
|
77
|
+
contract**. Any deviation a gate or the file ratchet forces is listed in that part's ship
|
|
78
|
+
notes, so a forced change is a recorded one rather than a quiet drift.
|
|
79
|
+
- The template ships with **no snapshot**: the snapshot script dumps real task, idea and goal
|
|
80
|
+
titles, and this repo is public. `docs/design/mocks/sky/.gitignore` refuses both the snapshot
|
|
81
|
+
and the built page.
|
|
82
|
+
- Criterion 1000384 is already `satisfied` and stays so; its text is rewritten, not its state.
|
|
83
|
+
**This was done on 2026-09-24 under task 1004229, not left for later.** A satisfied
|
|
84
|
+
criterion's prose is frozen (`409 criterion_satisfied`), so the route's own prescription was
|
|
85
|
+
followed: `POST /done-when/1000384/unsatisfy` → `PATCH /done-when/1000384` with the new
|
|
86
|
+
`criterion_md` → `POST /done-when/1000384/satisfy`. The read-back is `satisfied: true`, slug
|
|
87
|
+
`ideator-sky-tells-the-truth`, and the last bullet now reads *"The sky is the ideator's home,
|
|
88
|
+
and it is never the ONLY path to anything it shows. The list drawer — the room — is one key
|
|
89
|
+
away, and every drawn thing is a row in it."* with a dated amendment paragraph after the
|
|
90
|
+
drafting note. The five states / two channels text is byte-for-byte what it was. The full
|
|
91
|
+
before/after is in the session log
|
|
92
|
+
[`docs/session-logs/<redacted>.md`](../session-logs/<redacted>.md).
|
|
93
|
+
|
|
94
|
+
## 6. Alternatives rejected
|
|
95
|
+
|
|
96
|
+
- **Ship the sky as an extra and keep "never load-bearing".** Rejected: it makes the owner's
|
|
97
|
+
adopted home surface unroutable and leaves *Your thinking* and the goal map as the real pages,
|
|
98
|
+
which is the opposite of what was adopted.
|
|
99
|
+
- **Reverse ADR 0227.** Rejected: its refusal is measured and still correct. The project sky
|
|
100
|
+
needs 0227's drill-down shape, not its repeal.
|
|
101
|
+
- **Ship the two heuristics behind a disclaimer.** Rejected: the criterion's whole claim is that
|
|
102
|
+
each state maps to a ledger fact rather than a UI guess. A labelled guess is still a guess in a
|
|
103
|
+
picture whose promise is that it cannot be faked.
|
package/docs/adr/README.md
CHANGED
|
@@ -422,3 +422,4 @@ This keeps the decision history honest and traceable.
|
|
|
422
422
|
| 0328 | [**A hosted project's authority is its membership row, not its owner column** ([task 1003882](https://cloudbongos.com/builders#/task/1003882), goal 1000094 — BONGOS-V2). The owner's decision (2026-09-13): every API action must name its project, and a non-member may only apply. Two "project" concepts exist and answer different questions: `provisioning_instances` (the hub's fleet registry, single `owner_builder_id`, [ADR 0325](0325-the-managed-fleet-control-plane-is-the-hub-we-already-run.md)) and `<redacted>` (`client_id, github_id, membership_kind ∈ {owner,member,visitor,pending}`, already correct, already backing `GET /my-projects`). The composition this needs already exists once, in the opposite direction: `provisioning.projectOwnedBy` is a published port (task 1003580) that `platform-identity/invite-authz.js` already consumes via `resolveOptional` to ask "does this builder own this project" without importing provisioning (ADR 0083). **The gap is that the module which owns the fact does not use it on itself, and has grown three separate local copies of it instead of one** — `instanceAccessDenied` (6 routes), `resolveOwnInstance` (4 routes) and `disconnect.js`'s own inline copy (1 route) all implement "owner OR archon", while 3 routes (`teardown`, `domain`, `github-app`) implement only "owner" with no archon override at all — an existing inconsistency between sibling routes in the same module, not just duplication, and none of the three implementations is visible to `route-rank-check.js`. Decision: (1) project scope stays the existing path segment, resolved through `slug` (the `client_id = slug` join key [ADR 0246](0246-catalog-membership-is-a-projection-not-a-federation-side-effect.md) already establishes); (2) Phase 1 extracts one local `requireProjectOwner` helper replacing all three implementations — a behavior-preserving swap for 11 routes and a stated, intentional archon-override widening for the 3 that lacked it — no new port needed since provisioning already holds the column; Phase 2 adds a new port `platform-identity.projectMembershipKind` and widens the same helper to admit `owner` OR `member`, falling back to the Phase 1 column check when platform-identity isn't installed (ADR 0083's degrade-gracefully contract) — a NEW parallel axis, not a fifth branch on `requirePermission`, mirroring why the ownership axis ([ADR 0151](0151-governance-permissions-as-atom-ranks-as-roles.md) §3, R100) is kept separate; (3) a caller with NO membership row still gets 404 `instance_not_found` (existence-hidden, unchanged), but a `pending`/`visitor` row gets 403 `project_membership_required` naming `POST /my-projects/join` (ADR 0141/0201/0247's existing apply flow) — the "apply to join it" the owner's decision names, routed into the flow that already ships rather than a second one; (4) `route-rank-check.js` gains a `project_scope_missing` finding (blocker on write, concerns on read) for any `/provisioning/instances/:id...` route missing the gate, the same structural read it already gives `requirePermission`; (5) migration order is the 14 evidenced routes only — the task's own "96 write routes" figure is the whole app's census, and the other ~82 act on a single-tenant instance's own Bongos board, which [ADR 0100](0100-two-repo-instance-model.md) §3 already isolates one-database-per-repo and has no project dimension to name. Filed: [task 1004159](https://cloudbongos.com/builders#/task/1004159) (the helper) · [task 1004160](https://cloudbongos.com/builders#/task/1004160) (route-rank-check.js, depends on 1004159) · [task 1004161](https://cloudbongos.com/builders#/task/1004161) (the membership port, depends on 1004159) · [task 1004162](https://cloudbongos.com/builders#/task/1004162) (the 403/404 split, depends on 1004161). Rejected: a second `provisioning_instance_members` table (the membership table already exists and joins on the same key — a second one repeats the mistake ADR 0325 already refused); folding project authority into `requirePermission` as a fifth axis (same reasoning R100 already applied to `.own` keys); migrating all 96 write routes (re-litigates ADR 0100's single-tenant model, not this decision); dropping 404 existence-hiding entirely (a total stranger should learn nothing, exactly as `invite-authz.js` already guarantees).](0328-a-hosted-projects-authority-is-its-membership-row-not-its-owner-column.md) | security / authorization / provisioning |
|
|
423
423
|
| 0329 | [**The rendered fit check is a kit floor and an advisory ship-check row, not a grader worker** ([task 1004203](https://cloudbongos.com/builders#/task/1004203), goal 1000095 — UI quality). Nothing in the pipeline rendered a page, so titles clipped by character count ran past their cards (task 1003480, task 1004204) and a second `.mSec` child would have landed on the first (task 1003078), each found only in a browser. Two new kit floors, `text-fit` (text measured word by word past its box; SVG text past its card rect) and `sibling-overlap` (in-flow, block-level, text-bearing siblings), run in every `render.js` render; `scripts/gds/render-check.js` renders the pages a branch changed at 1280 + 390 and `/ship-check` shows them as an ADVISORY row that never flips its exit (ADR 0162). Not a grader worker: that would put a browser, fixtures and a harness on the grader host for signal the builder already saw; the artist gate (ADR 0241) stays the human look before deploy.](0329-the-rendered-fit-check-is-a-kit-floor-and-an-advisory-ship-check-row.md) | ui-design / kit + ship-check |
|
|
424
424
|
| 0330 | [**An ask is answered where it was asked** ([task 1004216](https://cloudbongos.com/builders#/task/1004216), goal 1000095 — BONGOS-V2), amending [ADR 0187](0187-collab-four-decisions.md) §4a. `lifecycle_004` let a builder ASK for help and let the **asker** mark their own row answered; the person being **asked** had no write at all, so the answer happened somewhere Bongos cannot see and the row sat open until its author remembered it — six asks addressed to the owner had been open between four and thirteen days on 2026-09-23, every one of them answerable. That was not an oversight: §4a deferred conversation to the Agora and a test named *"there is deliberately NO reply thread"* enforced it. **The deferral lost its addressee** — task 1002946 is ABANDONED and goal 1000064 ARCHIVED (verified against the live DB), so the rule had stopped meaning "wait for the Agora" and started meaning "an ask stays unanswerable forever to keep a promise to something that does not exist". **Decisions:** (1) an ask carries a thread of replies, APPEND-ONLY in the SCHEMA rather than by convention — no `updated_at`, `edited_by`, `deleted_at` or `parent_reply_id`, no reactions, no mentions, and a trigger that refuses UPDATE and DELETE outright, because a thing you can edit, nest, react to and address at people is a chat and that is what §4a declined; any builder may reply, since the board read is already project-wide and the good case is somebody you did not ask knowing the answer; (2) the **ADDRESSEE** may close an ask (`answered`), widening an asker-only UPDATE that was coherent only while nothing could be said on the row — but `withdrawn` does NOT widen, since "I no longer need this" is the asker's sentence alone and widening it would be a way to make an ask vanish unanswered; `settled_by` records which of the two closed it, and ADR 0187 §3's consent posture is untouched — closing ends a question, it does not accept work; (3) `/collab-review` posts the reply and **leaves the ask open** (owner decision), since an answer the reader has not read is exactly what an unattended run must halt on. **Consequences:** a reply cannot be taken back, by design; the FK **RESTRICTS rather than cascades** — the first draft cascaded, which reads right and was wrong, because a cascade is a plain DELETE the trigger refuses, so deleting an answered ask failed outright (caught by applying the migration to a real Postgres, not by reading it); the old test was REPLACED, not deleted, so the record that the restraint was deliberate survives; and replies inherit the pull-not-push posture, so nothing still tells an asker they were answered. Rejected: a single `answer` column (cheapest and unambiguously not a chat, but a follow-up would have nowhere to go except a second ask, splitting one conversation across two rows); waiting for the Agora (abandoned — waiting means forever); letting anyone close any ask (an open question is somebody's, and a stranger ending it should not be one click away).](0330-an-ask-is-answered-where-it-was-asked.md) | collab / lifecycle / schema |
|
|
425
|
+
| 0331 | [**The sky is the ideator's home, and the project sky takes the goal map's page** ([task 1004229](https://cloudbongos.com/builders#/task/1004229), goal 1000095 — BONGOS-V2), amending [ADR 0227](0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md) and decision 11 of `docs/specs/<redacted>.md`. The owner reviewed an interactive prototype of the ideator sky and the project sky over five rounds on 2026-09-24 and adopted it AS IS — copy, layout, colours, tour text, toggles, interactions — which contradicts two things already written down, so they are rewritten rather than leaving the build graded against a contract nobody means any more. **Decisions:** (1) the sky is the ideator's HOME surface — it replaces *Your thinking*, and the project sky replaces the goal map page — so "never load-bearing" and "arrives last" are DROPPED as a sequencing hedge from before there was a design to look at; the rule that survives at full force is the accessibility half, that the sky is never the ONLY path to anything it shows (the list drawer — the room — is one key away, and every drawn thing is a row in it); (2) ADR 0227 is AMENDED, not reversed — its measured refusal of a whole-corpus task map stands, and the project sky is §1's own prescription rather than its refusal: the goal graph is the entry point, tasks are drawn only INSIDE one goal past a zoom threshold (the per-goal drill-down §10.5 measured readable at 85.2px pitch worst case), below that they are dust density on the rings with NO identities, and the goal map's table survives as the sky's ledger drawer (§6's table equivalent kept); the nav slot the goal map was deliberately denied is GRANTED to the project sky, under Goals (owner, 2026-09-24), so part 4 changes the page and the test asserting no slot together; (3) the five states and the two channels are UNTOUCHED — criterion `ideator-sky-tells-the-truth` names a model, not a picture, and this amendment changes the picture's standing only; (4) the two HEURISTICS in the prototype — an idea's origin guessed from its text, and "born of a thought" found by scanning text for idea ids — must not ship as ledger facts: parts 3 and 4 hide both layers, part 5 replaces them with a `filed_via` column and a real born-of read. **Consequences:** `docs/design/mocks/sky/sky.template.html` is the PIXEL CONTRACT for parts 2–5, and every deviation a gate or the file ratchet forces is listed in that part's ship notes; no snapshot JSON or built page is ever committed (it carries real task and idea titles and this repo is public); ADR 0264's deleted goal "Living project sky" is superseded by this work under Working area 3. Rejected: shipping the sky as an extra and keeping "never load-bearing" (makes the adopted home surface unroutable); reversing ADR 0227 (its refusal is measured and still correct — the sky needs its drill-down shape, not its repeal); shipping the heuristics behind a disclaimer (a labelled guess is still a guess in a picture whose promise is that it cannot be faked).](0331-the-sky-is-the-ideators-home.md) | design / ideator / sky |
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
> **Status:** agreed 2026-09-19 with the area owner. Planning session meta task 1004076; the decisions live on idea 1001072; the scope is `docs/specs/<redacted>.md`.
|
|
4
4
|
>
|
|
5
5
|
> This file is the **visual** half. The spec is the build; the criteria on goal 1000095 are the done-when. Where this file and the spec disagree about behaviour, the spec wins; where a criterion and either of them disagree, the criterion wins.
|
|
6
|
+
>
|
|
7
|
+
> **Superseded for the sky (2026-09-24).** The Sky artboard in [`mocks/ideator-surface/`](mocks/ideator-surface/) is superseded by the adopted prototype at [`mocks/sky/`](mocks/sky/), which is the design of record and the pixel contract for the build ([ADR 0331](../adr/0331-the-sky-is-the-ideators-home.md)). The direction's rules were kept, not dropped: the **five objects** are the prototype's five states with the same ledger facts behind them; **size and brightness stay two channels** ("size is credits", never falling; brightness is the live share); **gravity** is the goal that lights as you type in the composer, and letting a thought float is still a real answer. What changed is the sky's standing — it is the ideator's home now, so "arrives last" and "never load-bearing" below are amended; the surviving rule is that the sky is never the *only* path, since the room is one key away and every drawn thing is a row in it.
|
|
6
8
|
|
|
7
9
|
## The problem this answers
|
|
8
10
|
|
|
@@ -63,11 +65,11 @@ The mockup sources are committed at [`mocks/ideator-surface/`](mocks/ideator-sur
|
|
|
63
65
|
1. **File** — the fast path. One line, an optional aim, and a receipt that does not evaporate. Filing never gets slower than it is today.
|
|
64
66
|
2. **The room** — the plain, everyday overview: what you filed, what it became, its size and whether it is still burning. This is the page a person opens daily, and it does the real work.
|
|
65
67
|
3. **The descent** — one thought at the top and everything it caused falling away below, through rewrites, splits and merges, including the branches that went out.
|
|
66
|
-
4. **The sky** — the
|
|
68
|
+
4. **The sky** — the ideator's home. It is drawn from numbers the other three already produce, and **it is never the only path to anything it shows**. *(Amended 2026-09-24 — it no longer "arrives last"; see the note at the top and ADR 0331.)*
|
|
67
69
|
|
|
68
70
|
## What this direction refuses
|
|
69
71
|
|
|
70
|
-
- **A galaxy is not trivial, and it
|
|
72
|
+
- **A galaxy is not trivial, and it is never the only path.** Every fact the sky shows is also a row in the room. *(Amended 2026-09-24 from "must never be load-bearing" — ADR 0331.)*
|
|
71
73
|
- **Filing does not get slower to serve the picture.** A spark's whole value is that it costs nothing to have; the sky redraws in the background.
|
|
72
74
|
- **The sky will be dominated by large dead rings in a project that churns.** That is honest, and it is the accepted trade — failure is fine, and a bright sky should be earned.
|
|
73
75
|
- **Brightness never claws back credits.** The ledger is not rewritten when the project changes its mind; only the picture changes.
|
|
@@ -2490,5 +2490,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2490
2490
|
landed since 1.19.1006 with no explicit bump. run 36043267244. (task 1002620)
|
|
2491
2491
|
1.19.1008 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2492
2492
|
landed since 1.19.1007 with no explicit bump. run 36052924171. (task 1002620)
|
|
2493
|
+
1.19.1009 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2494
|
+
landed since 1.19.1008 with no explicit bump. run 36056558236. (task 1002620)
|
|
2495
|
+
1.19.1010 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2496
|
+
landed since 1.19.1009 with no explicit bump. run 36064558803. (task 1002620)
|
|
2493
2497
|
---------------------------------------------------------------------------
|
|
2494
2498
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.1010",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.1010",
|
|
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.19.
|
|
3
|
+
"version": "1.19.1010",
|
|
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",
|
package/src/module-api.js
CHANGED
|
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
71
71
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
72
72
|
// the entry to that file. Look for a version's history there, not here.
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
|
-
const CORE_VERSION = '1.19.
|
|
74
|
+
const CORE_VERSION = '1.19.1010'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
75
75
|
|
|
76
76
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
77
77
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# The pre-fold ideas page — a frozen baseline
|
|
2
|
+
|
|
3
|
+
Byte copies of `modules/hall-ui/public/ideas.html` and `ideas.js` as they stood at commit
|
|
4
|
+
**`f375a1f9`**, the commit immediately before the Full Idea form was folded behind a
|
|
5
|
+
disclosure (task [#1004087](https://cloudbongos.com/builders#/task/1004087), spec R04).
|
|
6
|
+
|
|
7
|
+
They exist so `tests/ideator_one_line_path_proof.mjs` can measure the current filing path
|
|
8
|
+
against **the page that actually existed**, rather than against a description of it. A
|
|
9
|
+
described baseline agrees with the current page because whoever wrote it made it agree;
|
|
10
|
+
these can only agree if the code does.
|
|
11
|
+
|
|
12
|
+
Re-cut them to check they have not drifted:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git show f375a1f9:modules/hall-ui/public/ideas.js > tests/fixtures/ideator-prefold/ideas.js.baseline
|
|
16
|
+
git show f375a1f9:modules/hall-ui/public/ideas.html > tests/fixtures/ideator-prefold/ideas.html.baseline
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Do not edit these, and do not "fix" them
|
|
20
|
+
|
|
21
|
+
They are **evidence, not source**. Every finding in
|
|
22
|
+
[`docs/governance/<redacted>.md`](../../../docs/governance/<redacted>.md)
|
|
23
|
+
is a comparison against them, so editing one silently turns a measurement into a tautology.
|
|
24
|
+
The proof's last claim exists for exactly that: it asserts the baseline still fetches the
|
|
25
|
+
template unconditionally, still knows nothing about a disclosure, and is still a different
|
|
26
|
+
file from the live page — so tidying these into agreement reds the suite instead of passing
|
|
27
|
+
quietly.
|
|
28
|
+
|
|
29
|
+
## Why the `.baseline` extension
|
|
30
|
+
|
|
31
|
+
Not decoration, and not a way around a gate. `scripts/gds/fitness-ratchets.js` measures
|
|
32
|
+
cross-file duplication over `git ls-files '*.js'`, and a frozen copy of a live file is, by
|
|
33
|
+
construction, ~500 duplicate windows against it. That metric exists to find copy/paste a
|
|
34
|
+
maintainer should collapse; collapsing *this* copy would destroy the only thing it is for.
|
|
35
|
+
The extension states what the file is — recorded evidence, never loaded, never edited — and
|
|
36
|
+
keeps the duplication ratchet honest about the code it was written to police.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Ideas — {{worldName}}</title>
|
|
7
|
+
<meta name="description" content="Write a Full Idea: five questions that turn a thought into a baseline scope of work someone else can deliver against, with a live completeness score.">
|
|
8
|
+
<link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
|
|
9
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
12
|
+
<link rel="stylesheet" href="/builders/ideas.css">
|
|
13
|
+
</head>
|
|
14
|
+
<body data-page="ideas" data-page-title="Ideas">
|
|
15
|
+
|
|
16
|
+
<div class="app">
|
|
17
|
+
<aside class="app-sidebar" id="app-sidebar" aria-label="Primary"></aside>
|
|
18
|
+
<div class="app-scrim" id="app-scrim" hidden></div>
|
|
19
|
+
<div class="app-body">
|
|
20
|
+
<header class="app-topbar" id="app-topbar"></header>
|
|
21
|
+
<!-- --railed reserves the room the meter occupies (style.css, "the right
|
|
22
|
+
rail"). This page used to take that room by overriding
|
|
23
|
+
`.app-content > main` from its own sheet, which is a page editing shell
|
|
24
|
+
layout — invisible from the shell, and it hard-coded a topbar height. -->
|
|
25
|
+
<div class="app-content app-content--railed">
|
|
26
|
+
<!-- The page's own name, in the LABEL voice — the display face is saved for
|
|
27
|
+
section headings (the work.html precedent, task 1003304). The page had
|
|
28
|
+
no h1 at all, so it failed one-header-main-h1 on every render. -->
|
|
29
|
+
<div class="page-head page-head--board">
|
|
30
|
+
<h1 class="page-head__h">Ideas</h1>
|
|
31
|
+
<p class="page-head__sub" id="fi-sub">Loading the idea template…</p>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<main id="hall-main">
|
|
35
|
+
<!-- The spark queue (task 1002930 / R154). ABOVE the composer, because
|
|
36
|
+
"what is already waiting" is the thing to scan before starting
|
|
37
|
+
something new — and because a queue nobody sees is not a pickup
|
|
38
|
+
surface. Collapsed to a single line when empty so it never pushes the
|
|
39
|
+
composer down the page for nothing. -->
|
|
40
|
+
<section class="scroll" id="fi-queue-scroll" aria-labelledby="fi-queue-h">
|
|
41
|
+
<h2 id="fi-queue-h" class="scroll__h">Waiting to be developed</h2>
|
|
42
|
+
<p class="scroll__lede">
|
|
43
|
+
Ideas whose author has said "I had the thought but not the full picture".
|
|
44
|
+
Anyone can develop one — the author keeps the credit for having had it,
|
|
45
|
+
and you are recorded as its developer.
|
|
46
|
+
</p>
|
|
47
|
+
<div id="fi-queue"><p class="fi-note">Loading…</p></div>
|
|
48
|
+
</section>
|
|
49
|
+
|
|
50
|
+
<!-- Quick filing (task 1003069 / R08, goal 1000071 "Idea routing") —
|
|
51
|
+
the hall's first bug/idea report, separate from the Full Idea
|
|
52
|
+
composer below: title + kind + optional body + a goal picker fed
|
|
53
|
+
by the R07 suggester. A routed capture must never carry
|
|
54
|
+
grade='full' (routing.js NEVER_ROUTE_GRADE), so this cannot share
|
|
55
|
+
a submit with the form below it. Hidden while developing a spark
|
|
56
|
+
(?develop=<id>) — that surface always turns someone else's
|
|
57
|
+
existing thought into a Full Idea, never a fresh quick report. -->
|
|
58
|
+
<section class="scroll" id="fq-compose-scroll" aria-labelledby="fq-compose-h">
|
|
59
|
+
<h2 id="fq-compose-h" class="scroll__h">File a bug or idea</h2>
|
|
60
|
+
<p class="scroll__lede">
|
|
61
|
+
A quick report — title, what's going on, and where it belongs. Pick a goal
|
|
62
|
+
and it lands there as a task the moment you file; leave it on "no goal" and
|
|
63
|
+
it waits in the inbox for triage.
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<form id="fq-form" novalidate>
|
|
67
|
+
<label class="fi-label" for="fq-title">Title</label>
|
|
68
|
+
<input type="text" id="fq-title" class="fi-input" maxlength="200" autocomplete="off"
|
|
69
|
+
placeholder="what's wrong, or what you'd like to see">
|
|
70
|
+
|
|
71
|
+
<label class="fi-label" for="fq-kind">Kind</label>
|
|
72
|
+
<!-- task 1003453: the options are FILLED from /me.task_kinds at boot
|
|
73
|
+
(ideas.js), not written here. This markup used to spell the whole
|
|
74
|
+
vocabulary and had gone stale against the DB CHECK exactly as the
|
|
75
|
+
two board filters had — a third copy nobody was watching. The one
|
|
76
|
+
option left is the degraded fallback: if the read never lands, a
|
|
77
|
+
bug can still be filed. -->
|
|
78
|
+
<select id="fq-kind" class="fi-input">
|
|
79
|
+
<option value="bug" selected>Bug</option>
|
|
80
|
+
</select>
|
|
81
|
+
|
|
82
|
+
<label class="fi-label" for="fq-body">Details <span class="fi-hint">(optional)</span></label>
|
|
83
|
+
<textarea id="fq-body" class="fi-text" rows="4"
|
|
84
|
+
placeholder="repro steps, context, anything that helps…"></textarea>
|
|
85
|
+
|
|
86
|
+
<label class="fi-label" for="fq-goal">
|
|
87
|
+
Goal
|
|
88
|
+
<span class="fi-hint">Suggested as you type; leave it on "no goal" and it waits for triage.</span>
|
|
89
|
+
</label>
|
|
90
|
+
<select id="fq-goal" class="fi-input"></select>
|
|
91
|
+
|
|
92
|
+
<!-- GRAVITY (task 1004083 / spec R02) — what will actually catch this
|
|
93
|
+
thought, stated before it is released. It sits under the picker
|
|
94
|
+
because it is the picker's consequence, and because the picker's
|
|
95
|
+
own option labels cannot carry it: "No goal (homeless)" is false
|
|
96
|
+
for a bug (ADR 0262 routes it to the maintenance goal), and a
|
|
97
|
+
named goal is false for a judgment kind (routing.js
|
|
98
|
+
NEVER_ROUTE_KINDS). The verdict comes from the server's real
|
|
99
|
+
landing matrix — see POST /inbox/preview-landing — never from a
|
|
100
|
+
second copy of the rules in ideas.js. Hidden until there is
|
|
101
|
+
something true to say. -->
|
|
102
|
+
<p class="fi-gravity" id="fq-gravity" role="status" aria-live="polite" hidden></p>
|
|
103
|
+
|
|
104
|
+
<p class="fi-err" id="fq-err" role="alert"></p>
|
|
105
|
+
<p class="fi-result" id="fq-result" role="status" aria-live="polite"></p>
|
|
106
|
+
|
|
107
|
+
<!-- The receipt that outlives the confirmation above (task 1004082 /
|
|
108
|
+
spec R01). #fq-result is the live announcement for the filing
|
|
109
|
+
just made and dies with the page; this list is the durable
|
|
110
|
+
record of the last few, read back from localStorage on load so
|
|
111
|
+
a thought filed before a reload is still traceable here. -->
|
|
112
|
+
<section class="fi-receipts" id="fq-receipts" aria-labelledby="fq-receipts-h" hidden>
|
|
113
|
+
<h3 class="fi-receipts__h" id="fq-receipts-h">Recent filings</h3>
|
|
114
|
+
<ol class="fi-receipts__list" id="fq-receipts-list"></ol>
|
|
115
|
+
<p class="fi-receipts__note" id="fq-receipts-note" hidden></p>
|
|
116
|
+
</section>
|
|
117
|
+
|
|
118
|
+
<div class="fi-actions">
|
|
119
|
+
<button type="submit" class="btn" id="fq-submit">File it</button>
|
|
120
|
+
</div>
|
|
121
|
+
</form>
|
|
122
|
+
</section>
|
|
123
|
+
|
|
124
|
+
<!-- The composer. The idea detail view lives on its own page (R153). -->
|
|
125
|
+
<section class="scroll" id="fi-compose-scroll" aria-labelledby="fi-compose-h">
|
|
126
|
+
<h2 id="fi-compose-h" class="scroll__h">Write a Full Idea</h2>
|
|
127
|
+
<p class="scroll__lede">
|
|
128
|
+
A Full Idea answers five questions, so that someone else can deliver against it
|
|
129
|
+
without having to interview you first. Open to every role — the score below is
|
|
130
|
+
the only filter, and it counts substance, not who you are.
|
|
131
|
+
</p>
|
|
132
|
+
|
|
133
|
+
<form id="fi-form" novalidate>
|
|
134
|
+
<!-- DEVELOP MODE (R154): when the composer was opened from a spark,
|
|
135
|
+
this block carries the spark's own words and the title becomes a
|
|
136
|
+
read-only fact rather than a field — developing an idea must not
|
|
137
|
+
quietly rename it out from under its author. -->
|
|
138
|
+
<div class="fi-develop" id="fi-develop" hidden>
|
|
139
|
+
<p class="fi-develop__label">Developing a Big Idea Spark</p>
|
|
140
|
+
<p class="fi-develop__title" id="fi-develop-title"></p>
|
|
141
|
+
<p class="fi-develop__body" id="fi-develop-body"></p>
|
|
142
|
+
<p class="fi-develop__who" id="fi-develop-who"></p>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<label class="fi-label" for="fi-title" id="fi-title-label">
|
|
146
|
+
Title
|
|
147
|
+
<span class="fi-hint">One line. This is what the idea is called everywhere else.</span>
|
|
148
|
+
</label>
|
|
149
|
+
<input type="text" id="fi-title" class="fi-input" maxlength="200" autocomplete="off"
|
|
150
|
+
placeholder="what the idea is, in one line">
|
|
151
|
+
|
|
152
|
+
<!-- The five fields are rendered from GET /inbox/template — the R141
|
|
153
|
+
declaration — never hand-written here. A hard-coded form is the
|
|
154
|
+
same "second copy of the rules" defect as a hard-coded scorer,
|
|
155
|
+
one step earlier, and it would silently ignore a per-project
|
|
156
|
+
template (R156). -->
|
|
157
|
+
<div id="fi-fields" class="fi-fields">
|
|
158
|
+
<p class="fi-note">Loading the five questions…</p>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<!-- The scope recommendation (BV2.R13). Rendered from the same
|
|
162
|
+
GET /inbox/template read as the fields above, and for the same
|
|
163
|
+
reason: the two values are a closed vocabulary the database
|
|
164
|
+
enforces, so a hand-written pair of radios here would be a
|
|
165
|
+
second copy of it, free to drift. -->
|
|
166
|
+
<div id="fi-rec" class="fi-rec"></div>
|
|
167
|
+
|
|
168
|
+
<p class="fi-err" id="fi-err" role="alert"></p>
|
|
169
|
+
|
|
170
|
+
<div class="fi-actions">
|
|
171
|
+
<button type="submit" class="btn" id="fi-submit" disabled>File this idea</button>
|
|
172
|
+
<button type="button" class="btn btn--ghost" id="fi-clear">Discard draft</button>
|
|
173
|
+
<span class="fi-draft" id="fi-draft" role="status" aria-live="polite"></span>
|
|
174
|
+
</div>
|
|
175
|
+
</form>
|
|
176
|
+
</section>
|
|
177
|
+
</main>
|
|
178
|
+
|
|
179
|
+
<footer class="app-foot" id="app-foot"></footer>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<!-- The meter rides along beside the form on a wide screen and above it on a
|
|
185
|
+
narrow one (the shell's .app-rail decides). It is a READOUT, never an input:
|
|
186
|
+
every number in it comes from the server's own scorer. -->
|
|
187
|
+
<aside class="fi-meter app-rail" id="fi-meter" aria-labelledby="fi-meter-h" hidden>
|
|
188
|
+
<h2 class="fi-meter__h" id="fi-meter-h">Completeness</h2>
|
|
189
|
+
<div class="fi-gauge">
|
|
190
|
+
<div class="fi-gauge__track"><div class="fi-gauge__fill" id="fi-gauge-fill"></div></div>
|
|
191
|
+
<p class="fi-gauge__n" id="fi-gauge-n" role="status" aria-live="polite">—</p>
|
|
192
|
+
</div>
|
|
193
|
+
<ul class="fi-meter__list" id="fi-meter-list"></ul>
|
|
194
|
+
<p class="fi-meter__note">
|
|
195
|
+
Counted, not judged: each question is worth the same, and earns its share in
|
|
196
|
+
proportion to how much real text it carries. Whitespace and padding score nothing.
|
|
197
|
+
</p>
|
|
198
|
+
</aside>
|
|
199
|
+
|
|
200
|
+
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
201
|
+
|
|
202
|
+
<script src="/builders/shell.js?v=2026-09-22-movefeedback1"></script>
|
|
203
|
+
<script src="/builders/palette.js" defer></script>
|
|
204
|
+
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
205
|
+
<!-- task 1003069 (R08) — the quick-filing form's routed result links a task
|
|
206
|
+
through window.OTBTaskDetail.href(); guarded if this ever loads without it. -->
|
|
207
|
+
<script src="/builders/task-detail.js?v=2026-07-03-taskdetail2" defer></script>
|
|
208
|
+
<script src="/builders/ideas.js?v=2026-08-22-r154"></script>
|
|
209
|
+
</body>
|
|
210
|
+
</html>
|