@bongos/core 1.25.14 → 1.25.16

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 (46) hide show
  1. package/.bongos-core.json +101 -41
  2. package/.claude/skills/goal-create/SKILL.md +1 -0
  3. package/.claude/skills/planning-session/SKILL.md +5 -4
  4. package/bin/bongos.js +1 -0
  5. package/clients/bongos-client/README.md +1 -1
  6. package/clients/bongos-client/bongos-client.global.js +20 -0
  7. package/clients/bongos-client/index.cjs +20 -0
  8. package/clients/bongos-client/index.d.ts +24 -0
  9. package/clients/bongos-client/index.mjs +20 -0
  10. package/docs/adr/0408-a-genesis-stage-is-three-doors-onto-one-record.md +61 -0
  11. package/docs/adr/README.md +1 -0
  12. package/docs/api/openapi.json +544 -2
  13. package/docs/api-reference.md +12 -2
  14. package/docs/copy-inventory.md +120 -109
  15. package/docs/copy-registry.json +275 -165
  16. package/docs/file-map.md +1 -0
  17. package/docs/module-api-changelog.md +2 -0
  18. package/docs/page-inventory.json +2 -0
  19. package/docs/page-readings.json +107 -107
  20. package/docs/project-context.template.md +1 -0
  21. package/modules/hall-ui/public/dom-utils.js +5 -0
  22. package/modules/hall-ui/public/genesis-home.js +23 -8
  23. package/modules/hall-ui/public/setup-gate.js +1 -1
  24. package/modules/hall-ui/public/style.css +21 -1
  25. package/modules/lifecycle/kickoff-checklist.js +18 -4
  26. package/modules/lifecycle/kickoff-seed.js +27 -4
  27. package/modules/onboarding/genesis-home.js +11 -2
  28. package/modules/onboarding/genesis-work.js +387 -0
  29. package/modules/onboarding/migrations/onboarding_002_genesis_work.sql +76 -0
  30. package/modules/onboarding/routes/genesis-work.js +85 -0
  31. package/modules/onboarding/routes/onboarding.js +3 -0
  32. package/modules/public-landing/public/assets/guide-scene.css +245 -0
  33. package/modules/public-landing/public/assets/guide-scene.js +566 -0
  34. package/modules/public-landing/public/index.html +62 -2
  35. package/package-lock.json +2 -2
  36. package/package.json +1 -1
  37. package/release-notes.json +18 -0
  38. package/scripts/bongos/genesis.js +180 -0
  39. package/scripts/bongos/run-unit-tests.js +3 -0
  40. package/scripts/gds/genesis.js +7 -0
  41. package/src/module-api.js +1 -1
  42. package/tests/genesis_home.mjs +70 -2
  43. package/tests/genesis_work.mjs +304 -0
  44. package/tests/genesis_work_db.mjs +73 -0
  45. package/tests/genesis_work_routes.mjs +130 -0
  46. package/tests/landing_guide_scene.mjs +504 -0
@@ -0,0 +1,61 @@
1
+ # ADR 0408 — A genesis stage is three doors onto one record
2
+
3
+ - **Status:** accepted
4
+ - **Date:** 2026-11-13
5
+ - **Task:** [task 1005116](https://cloudbongos.com/builders#/task/1005116) (goal 1000106, Project creation)
6
+ - **Owner ruling:** 2026-11-07 — one pattern, every stage, scope included
7
+
8
+ ## Context
9
+
10
+ Each genesis stage (scope, strategize, charter, legalize, legislation) is a decision only
11
+ the founder can make. Until now each had exactly one route through it: an AI session
12
+ drafted the stage's answer and the founder read it, so the project's strategy was the
13
+ model's. The owner's rule: **Bongos may structure the thinking and may help with the
14
+ words, but the founder is the author.** The owner ruled the fix is one pattern shared by
15
+ every stage, not a strategize feature that charter then copies.
16
+
17
+ ## Decision
18
+
19
+ 1. **Three doors, guided first.** Every stage offers *guided* (the stage's questions, one
20
+ at a time), *open* (a blank page, with the questions shown beside it as the shape of a
21
+ good answer) and *assisted* (the founder's own AI session works the same questions,
22
+ pushes back and records only what the founder accepts). Plus the existing way: link a
23
+ document the founder already has. Guided is the default because a blank page is how
24
+ toast's scope came back thin.
25
+ 2. **One record per stage, not one per door.** The door is only how the founder is
26
+ working right now (`onboarding_genesis_work.door`). The answers, the free page and the
27
+ link are kept whatever the door, so switching loses nothing.
28
+ 3. **An answer is a row, not prose.** `onboarding_genesis_answers` holds one row per
29
+ answered question with a STATE — `answered`, `not_sure` ("not sure yet", an answer,
30
+ not a gap) or `skipped` — and no row means never touched. Un-answering deletes the
31
+ row, back to empty. Each row carries its ORIGIN (`founder`, `assisted`,
32
+ `carried_over`), so answers brought in from before sign-up (task 1005274) read as
33
+ carried over until the founder makes them theirs. Every change is appended to
34
+ `onboarding_genesis_answer_history`.
35
+ 4. **The questions are code.** `QUESTIONS` in `modules/onboarding/genesis-work.js`; a
36
+ stage adopts the pattern by declaring its questions there. Strategize does now; scope's
37
+ guided door is its project interview (task 1005114); charter, legalize and legislation
38
+ adopt it when next touched. A stage with no questions still takes a page and a link.
39
+ 5. **The founder writes, everyone reads.** Writes are behind `project.settings.manage`,
40
+ like the rest of genesis; reads are any signed-in builder. `GET /founding/context`
41
+ (and `npx bongos genesis context`) is the read path a session planning a goal or task
42
+ uses.
43
+
44
+ ## Rejected
45
+
46
+ - **Answers in `project_settings` JSON**, beside `founding.plan`. One blob per stage
47
+ cannot tell "not sure yet" from empty at the database, loses every earlier wording on
48
+ revision, and makes a carry-over that must never overwrite the founder a
49
+ read-modify-write race.
50
+ - **The answers inside the stage task's description.** That is prose; nothing later can
51
+ read a single answer out of it, which is the problem the owner raised.
52
+ - **A separate store per door.** Three copies of one artifact drift, and switching would
53
+ lose work — the opposite of the ruling.
54
+
55
+ ## Consequences
56
+
57
+ - Presentation is left to the game frame (the founding of the government district) and
58
+ the hall version (task 1005285). Today a founder works a stage through their AI session
59
+ and `npx bongos genesis …`.
60
+ - Task 1005115 renders each stage's record as an editable document from this store.
61
+ - Scope adopted it with the project interview (task 1005114): six questions in three groups. `/goal-create` and `/planning-session` read the answers before planning, through `genesis.js context`.
@@ -521,5 +521,6 @@ These 20 numbers are each shared by exactly two files. They are **accepted histo
521
521
  | 0403 | [**In game mode the visor is the control and the scene is the view** ([task 1005203](https://cloudbongos.com/builders#/task/1005203), goal 1000142; owner 2026-11-11). Every main call to action you can see in game mode lives on the visor (the accent button, the key hints, the Actions sheet); the city, the sky and Home only show the project and can be moved through, never carry buttons of their own. A scene offers its actions to the visor through `OTBVisor.scene`. Found not yet keeping it: the city's decide button and door, the sky's top row and composer, Home's gallery links, the Artist's feedback tab.](0403-in-game-mode-the-visor-is-the-control-and-the-scene-is-the-view.md) | hall / game frame |
522
522
  | 0404 | [**A party is a room, and rooms register as kinds** ([task 1005220](https://cloudbongos.com/builders#/task/1005220), goal 1000148). Any group that talks together is a room: a free-form party (cap 8), a chain party (ADR 0400), a scoping session (cap 40, owned by `lifecycle`) or a decision room (cap 40, `government`). Each owner contributes its kind to the `room.kinds` contribution point (a port is single-provider, so four owners would fail the boot) with `members`/`isMember`/optional `invite`/`accept`, and fires `room.opened`/`room.member.joined`/`room.member.left`/`room.closed`; consumers never read an owner's tables and reconcile against `members()`. Free-form party: one per builder, leader handover to the longest-standing member, disband on last leave. A chain room follows an open `chain_party` row. Unlinked players get everything but voice. V3 polls (3 s, cursor + 304, paused when hidden, per-builder limiter) rather than pushing through `/live`. With discord off, no voice key or voice state; chat still works. A room is never authority. Rejected: one port, a port per kind, a rooms module reading other modules' tables, a second party roster, push via `/live`, speaking indicators.](0404-a-party-is-a-room-and-rooms-register-as-kinds.md) | game frame / modules / Discord |
523
523
  | 0405 | [**Each character has one colour, and the visor wears it** ([task 1005218](https://cloudbongos.com/builders#/task/1005218), goal 1000142; owner 2026-11-12). The Artisan is ember (the accent), the Artist violet, the Patron gold, each mixed from the hall’s tokens and none typed in. In game mode the visor’s lines, name, picture rim and accent are the held character’s colour, and your picture on the glass is your character wearing the visor. The characters are redrawn at 64 by 64 as two-animal aliens, drawn by a script.](0405-each-character-has-one-colour-and-the-visor-wears-it.md) | hall / game frame |
524
+ | 0408 | [**A genesis stage is three doors onto one record** ([task 1005116](https://cloudbongos.com/builders#/task/1005116), goal 1000106; owner 2026-11-07). Every genesis stage offers guided (its questions, the default), open (a blank page with the questions beside it) and assisted (the founder's own AI session works the same questions and records only what the founder accepts), plus linking an existing document. The door is only how the founder is working now: answers, page and link are one record per stage, so switching loses nothing. An answer is a row with a state (answered · not sure yet · skipped; no row = empty) and an origin (founder · assisted · carried over), with append-only history. Founder writes, everyone reads; `GET /founding/context` is the planning read path. Rejected: project_settings JSON, answers inside task prose, a store per door.](0408-a-genesis-stage-is-three-doors-onto-one-record.md) | onboarding / genesis |
524
525
  | 0406 | [**Every project gets a sandbox that follows main, and live moves only when a person promotes** ([task 1005288](https://cloudbongos.com/builders#/task/1005288), goal 1000106; owner 2026-11-13). One repository, no sandbox branch: a second Render web service on the free plan auto-deploys every landing on `main`, and the live service stops auto-deploying and takes only the commit a person promotes (with the Render key typed in for that request). Fake data and test keys by default; lent real keys should be read-only, behind an outbound gate that refuses sends, charges and writes. Render's free database expires in 30 days, so the sandbox gets a second database in the app's paid one. A project with no app gets no hosted sandbox; Cloud Bongos runs the same rule over its release pin.](0406-every-project-gets-a-sandbox-that-follows-main-and-live-moves-only-when-a-person-promotes.md) | provisioning / hosting |
525
526
  | 0407 | [**A hosted project's grant is made by its owner, not witnessed at sign-in** ([task 1004753](https://cloudbongos.com/builders#/task/1004753), goal 1000106; accepted by the owner 2026-11-13). Replaces ADR 0328's suspended Phase 2: no `membership_kind` admits anyone, because sign-in writes `member` for any GitHub user (the device flow included) and check-in is the project's own word. A new `provisioning_project_grants` row, one writer (`grants.js`), created only by the project's owner from their hub session (no archon create; owner, grantee or archon may revoke), read live in `requireProjectOwner` on routes that opt in with `{ grantee: 'operate' }`: the project read, settings read, env-manifest (names only) and restart. Teardown, disconnect, domain, the GitHub/Render/repo-private actions, settings and look writes stay owner-only. Audit actor `api:grantee:<id>`. The sign-in default stays `member`. A visitor or pending applicant gets 403 `project_membership_required` with the join path; a member without a grant gets 403 `project_access_required` (ask the owner); a stranger keeps the 404.](0407-a-project-grant-is-made-by-the-owner-not-witnessed-at-sign-in.md) | provisioning / permissions |
@@ -7671,6 +7671,37 @@
7671
7671
  ]
7672
7672
  }
7673
7673
  },
7674
+ "/founding/context": {
7675
+ "get": {
7676
+ "operationId": "get_founding_context",
7677
+ "tags": [
7678
+ "founding"
7679
+ ],
7680
+ "summary": "GET /founding/context",
7681
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
7682
+ "x-rank": "any-builder",
7683
+ "x-source": "modules/onboarding/routes/genesis-work.js",
7684
+ "responses": {
7685
+ "200": {
7686
+ "description": "Success."
7687
+ },
7688
+ "400": {
7689
+ "$ref": "#/components/responses/BadRequest"
7690
+ },
7691
+ "401": {
7692
+ "$ref": "#/components/responses/Unauthorized"
7693
+ },
7694
+ "403": {
7695
+ "$ref": "#/components/responses/Forbidden"
7696
+ }
7697
+ },
7698
+ "security": [
7699
+ {
7700
+ "builderSession": []
7701
+ }
7702
+ ]
7703
+ }
7704
+ },
7674
7705
  "/founding/enabled": {
7675
7706
  "put": {
7676
7707
  "operationId": "put_founding_enabled",
@@ -7893,6 +7924,466 @@
7893
7924
  ]
7894
7925
  }
7895
7926
  },
7927
+ "/founding/work": {
7928
+ "get": {
7929
+ "operationId": "get_founding_work",
7930
+ "tags": [
7931
+ "founding"
7932
+ ],
7933
+ "summary": "GET /founding/work",
7934
+ "description": "The read path for every door and for AI sessions planning a goal or task.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
7935
+ "x-rank": "any-builder",
7936
+ "x-source": "modules/onboarding/routes/genesis-work.js",
7937
+ "responses": {
7938
+ "200": {
7939
+ "description": "Success."
7940
+ },
7941
+ "400": {
7942
+ "$ref": "#/components/responses/BadRequest"
7943
+ },
7944
+ "401": {
7945
+ "$ref": "#/components/responses/Unauthorized"
7946
+ },
7947
+ "403": {
7948
+ "$ref": "#/components/responses/Forbidden"
7949
+ }
7950
+ },
7951
+ "security": [
7952
+ {
7953
+ "builderSession": []
7954
+ }
7955
+ ]
7956
+ }
7957
+ },
7958
+ "/founding/work/{stage}": {
7959
+ "get": {
7960
+ "operationId": "get_founding_work_stage",
7961
+ "tags": [
7962
+ "founding"
7963
+ ],
7964
+ "summary": "GET /founding/work/:stage",
7965
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
7966
+ "x-rank": "any-builder",
7967
+ "x-source": "modules/onboarding/routes/genesis-work.js",
7968
+ "parameters": [
7969
+ {
7970
+ "name": "stage",
7971
+ "in": "path",
7972
+ "required": true,
7973
+ "schema": {
7974
+ "type": "string"
7975
+ },
7976
+ "description": "Path parameter `stage`."
7977
+ }
7978
+ ],
7979
+ "responses": {
7980
+ "200": {
7981
+ "description": "Success."
7982
+ },
7983
+ "400": {
7984
+ "$ref": "#/components/responses/BadRequest"
7985
+ },
7986
+ "401": {
7987
+ "$ref": "#/components/responses/Unauthorized"
7988
+ },
7989
+ "403": {
7990
+ "$ref": "#/components/responses/Forbidden"
7991
+ },
7992
+ "404": {
7993
+ "$ref": "#/components/responses/NotFound"
7994
+ }
7995
+ },
7996
+ "security": [
7997
+ {
7998
+ "builderSession": []
7999
+ }
8000
+ ]
8001
+ }
8002
+ },
8003
+ "/founding/work/{stage}/answers/{question}": {
8004
+ "put": {
8005
+ "operationId": "put_founding_work_stage_answers_question",
8006
+ "tags": [
8007
+ "founding"
8008
+ ],
8009
+ "summary": "PUT /founding/work/:stage/answers/:question",
8010
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8011
+ "x-rank": "any-builder",
8012
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8013
+ "parameters": [
8014
+ {
8015
+ "name": "stage",
8016
+ "in": "path",
8017
+ "required": true,
8018
+ "schema": {
8019
+ "type": "string"
8020
+ },
8021
+ "description": "Path parameter `stage`."
8022
+ },
8023
+ {
8024
+ "name": "question",
8025
+ "in": "path",
8026
+ "required": true,
8027
+ "schema": {
8028
+ "type": "string"
8029
+ },
8030
+ "description": "Path parameter `question`."
8031
+ }
8032
+ ],
8033
+ "requestBody": {
8034
+ "required": false,
8035
+ "content": {
8036
+ "application/json": {
8037
+ "schema": {
8038
+ "$ref": "#/components/schemas/PutFoundingWorkStageAnswersQuestionRequest"
8039
+ }
8040
+ }
8041
+ },
8042
+ "x-validated": true
8043
+ },
8044
+ "responses": {
8045
+ "200": {
8046
+ "description": "Success."
8047
+ },
8048
+ "400": {
8049
+ "$ref": "#/components/responses/ValidationFailed"
8050
+ },
8051
+ "401": {
8052
+ "$ref": "#/components/responses/Unauthorized"
8053
+ },
8054
+ "403": {
8055
+ "$ref": "#/components/responses/Forbidden"
8056
+ },
8057
+ "404": {
8058
+ "$ref": "#/components/responses/NotFound"
8059
+ }
8060
+ },
8061
+ "security": [
8062
+ {
8063
+ "builderSession": []
8064
+ }
8065
+ ]
8066
+ },
8067
+ "delete": {
8068
+ "operationId": "delete_founding_work_stage_answers_question",
8069
+ "tags": [
8070
+ "founding"
8071
+ ],
8072
+ "summary": "DELETE /founding/work/:stage/answers/:question",
8073
+ "description": "Un-answer: back to empty, which is not the same as skipped.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8074
+ "x-rank": "any-builder",
8075
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8076
+ "parameters": [
8077
+ {
8078
+ "name": "stage",
8079
+ "in": "path",
8080
+ "required": true,
8081
+ "schema": {
8082
+ "type": "string"
8083
+ },
8084
+ "description": "Path parameter `stage`."
8085
+ },
8086
+ {
8087
+ "name": "question",
8088
+ "in": "path",
8089
+ "required": true,
8090
+ "schema": {
8091
+ "type": "string"
8092
+ },
8093
+ "description": "Path parameter `question`."
8094
+ }
8095
+ ],
8096
+ "responses": {
8097
+ "200": {
8098
+ "description": "Success."
8099
+ },
8100
+ "400": {
8101
+ "$ref": "#/components/responses/BadRequest"
8102
+ },
8103
+ "401": {
8104
+ "$ref": "#/components/responses/Unauthorized"
8105
+ },
8106
+ "403": {
8107
+ "$ref": "#/components/responses/Forbidden"
8108
+ },
8109
+ "404": {
8110
+ "$ref": "#/components/responses/NotFound"
8111
+ }
8112
+ },
8113
+ "security": [
8114
+ {
8115
+ "builderSession": []
8116
+ }
8117
+ ]
8118
+ }
8119
+ },
8120
+ "/founding/work/{stage}/answers/{question}/history": {
8121
+ "get": {
8122
+ "operationId": "get_founding_work_stage_answers_question_history",
8123
+ "tags": [
8124
+ "founding"
8125
+ ],
8126
+ "summary": "GET /founding/work/:stage/answers/:question/history",
8127
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8128
+ "x-rank": "any-builder",
8129
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8130
+ "parameters": [
8131
+ {
8132
+ "name": "stage",
8133
+ "in": "path",
8134
+ "required": true,
8135
+ "schema": {
8136
+ "type": "string"
8137
+ },
8138
+ "description": "Path parameter `stage`."
8139
+ },
8140
+ {
8141
+ "name": "question",
8142
+ "in": "path",
8143
+ "required": true,
8144
+ "schema": {
8145
+ "type": "string"
8146
+ },
8147
+ "description": "Path parameter `question`."
8148
+ }
8149
+ ],
8150
+ "responses": {
8151
+ "200": {
8152
+ "description": "Success."
8153
+ },
8154
+ "400": {
8155
+ "$ref": "#/components/responses/BadRequest"
8156
+ },
8157
+ "401": {
8158
+ "$ref": "#/components/responses/Unauthorized"
8159
+ },
8160
+ "403": {
8161
+ "$ref": "#/components/responses/Forbidden"
8162
+ },
8163
+ "404": {
8164
+ "$ref": "#/components/responses/NotFound"
8165
+ }
8166
+ },
8167
+ "security": [
8168
+ {
8169
+ "builderSession": []
8170
+ }
8171
+ ]
8172
+ }
8173
+ },
8174
+ "/founding/work/{stage}/assist": {
8175
+ "get": {
8176
+ "operationId": "get_founding_work_stage_assist",
8177
+ "tags": [
8178
+ "founding"
8179
+ ],
8180
+ "summary": "GET /founding/work/:stage/assist",
8181
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8182
+ "x-rank": "any-builder",
8183
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8184
+ "parameters": [
8185
+ {
8186
+ "name": "stage",
8187
+ "in": "path",
8188
+ "required": true,
8189
+ "schema": {
8190
+ "type": "string"
8191
+ },
8192
+ "description": "Path parameter `stage`."
8193
+ }
8194
+ ],
8195
+ "responses": {
8196
+ "200": {
8197
+ "description": "Success."
8198
+ },
8199
+ "400": {
8200
+ "$ref": "#/components/responses/BadRequest"
8201
+ },
8202
+ "401": {
8203
+ "$ref": "#/components/responses/Unauthorized"
8204
+ },
8205
+ "403": {
8206
+ "$ref": "#/components/responses/Forbidden"
8207
+ },
8208
+ "404": {
8209
+ "$ref": "#/components/responses/NotFound"
8210
+ }
8211
+ },
8212
+ "security": [
8213
+ {
8214
+ "builderSession": []
8215
+ }
8216
+ ]
8217
+ }
8218
+ },
8219
+ "/founding/work/{stage}/door": {
8220
+ "put": {
8221
+ "operationId": "put_founding_work_stage_door",
8222
+ "tags": [
8223
+ "founding"
8224
+ ],
8225
+ "summary": "PUT /founding/work/:stage/door",
8226
+ "description": "The founder's writes.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8227
+ "x-rank": "any-builder",
8228
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8229
+ "parameters": [
8230
+ {
8231
+ "name": "stage",
8232
+ "in": "path",
8233
+ "required": true,
8234
+ "schema": {
8235
+ "type": "string"
8236
+ },
8237
+ "description": "Path parameter `stage`."
8238
+ }
8239
+ ],
8240
+ "requestBody": {
8241
+ "required": true,
8242
+ "content": {
8243
+ "application/json": {
8244
+ "schema": {
8245
+ "$ref": "#/components/schemas/PutFoundingWorkStageDoorRequest"
8246
+ }
8247
+ }
8248
+ },
8249
+ "x-validated": true
8250
+ },
8251
+ "responses": {
8252
+ "200": {
8253
+ "description": "Success."
8254
+ },
8255
+ "400": {
8256
+ "$ref": "#/components/responses/ValidationFailed"
8257
+ },
8258
+ "401": {
8259
+ "$ref": "#/components/responses/Unauthorized"
8260
+ },
8261
+ "403": {
8262
+ "$ref": "#/components/responses/Forbidden"
8263
+ },
8264
+ "404": {
8265
+ "$ref": "#/components/responses/NotFound"
8266
+ }
8267
+ },
8268
+ "security": [
8269
+ {
8270
+ "builderSession": []
8271
+ }
8272
+ ]
8273
+ }
8274
+ },
8275
+ "/founding/work/{stage}/link": {
8276
+ "put": {
8277
+ "operationId": "put_founding_work_stage_link",
8278
+ "tags": [
8279
+ "founding"
8280
+ ],
8281
+ "summary": "PUT /founding/work/:stage/link",
8282
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8283
+ "x-rank": "any-builder",
8284
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8285
+ "parameters": [
8286
+ {
8287
+ "name": "stage",
8288
+ "in": "path",
8289
+ "required": true,
8290
+ "schema": {
8291
+ "type": "string"
8292
+ },
8293
+ "description": "Path parameter `stage`."
8294
+ }
8295
+ ],
8296
+ "requestBody": {
8297
+ "required": false,
8298
+ "content": {
8299
+ "application/json": {
8300
+ "schema": {
8301
+ "$ref": "#/components/schemas/PutFoundingWorkStageLinkRequest"
8302
+ }
8303
+ }
8304
+ },
8305
+ "x-validated": true
8306
+ },
8307
+ "responses": {
8308
+ "200": {
8309
+ "description": "Success."
8310
+ },
8311
+ "400": {
8312
+ "$ref": "#/components/responses/ValidationFailed"
8313
+ },
8314
+ "401": {
8315
+ "$ref": "#/components/responses/Unauthorized"
8316
+ },
8317
+ "403": {
8318
+ "$ref": "#/components/responses/Forbidden"
8319
+ },
8320
+ "404": {
8321
+ "$ref": "#/components/responses/NotFound"
8322
+ }
8323
+ },
8324
+ "security": [
8325
+ {
8326
+ "builderSession": []
8327
+ }
8328
+ ]
8329
+ }
8330
+ },
8331
+ "/founding/work/{stage}/page": {
8332
+ "put": {
8333
+ "operationId": "put_founding_work_stage_page",
8334
+ "tags": [
8335
+ "founding"
8336
+ ],
8337
+ "summary": "PUT /founding/work/:stage/page",
8338
+ "description": "**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
8339
+ "x-rank": "any-builder",
8340
+ "x-source": "modules/onboarding/routes/genesis-work.js",
8341
+ "parameters": [
8342
+ {
8343
+ "name": "stage",
8344
+ "in": "path",
8345
+ "required": true,
8346
+ "schema": {
8347
+ "type": "string"
8348
+ },
8349
+ "description": "Path parameter `stage`."
8350
+ }
8351
+ ],
8352
+ "requestBody": {
8353
+ "required": false,
8354
+ "content": {
8355
+ "application/json": {
8356
+ "schema": {
8357
+ "$ref": "#/components/schemas/PutFoundingWorkStagePageRequest"
8358
+ }
8359
+ }
8360
+ },
8361
+ "x-validated": true
8362
+ },
8363
+ "responses": {
8364
+ "200": {
8365
+ "description": "Success."
8366
+ },
8367
+ "400": {
8368
+ "$ref": "#/components/responses/ValidationFailed"
8369
+ },
8370
+ "401": {
8371
+ "$ref": "#/components/responses/Unauthorized"
8372
+ },
8373
+ "403": {
8374
+ "$ref": "#/components/responses/Forbidden"
8375
+ },
8376
+ "404": {
8377
+ "$ref": "#/components/responses/NotFound"
8378
+ }
8379
+ },
8380
+ "security": [
8381
+ {
8382
+ "builderSession": []
8383
+ }
8384
+ ]
8385
+ }
8386
+ },
7896
8387
  "/front-door-guide/conversations": {
7897
8388
  "post": {
7898
8389
  "operationId": "post_front_door_guide_conversations",
@@ -43958,6 +44449,57 @@
43958
44449
  },
43959
44450
  "additionalProperties": false
43960
44451
  },
44452
+ "PutFoundingWorkStageAnswersQuestionRequest": {
44453
+ "type": "object",
44454
+ "properties": {
44455
+ "state": {
44456
+ "type": "string",
44457
+ "maxLength": 16
44458
+ },
44459
+ "text": {
44460
+ "type": "string"
44461
+ },
44462
+ "origin": {
44463
+ "type": "string",
44464
+ "maxLength": 16
44465
+ },
44466
+ "if_empty": {
44467
+ "type": "boolean"
44468
+ }
44469
+ },
44470
+ "additionalProperties": false
44471
+ },
44472
+ "PutFoundingWorkStageDoorRequest": {
44473
+ "type": "object",
44474
+ "properties": {
44475
+ "door": {
44476
+ "type": "string",
44477
+ "maxLength": 16
44478
+ }
44479
+ },
44480
+ "required": [
44481
+ "door"
44482
+ ],
44483
+ "additionalProperties": false
44484
+ },
44485
+ "PutFoundingWorkStageLinkRequest": {
44486
+ "type": "object",
44487
+ "properties": {
44488
+ "url": {
44489
+ "type": "string"
44490
+ }
44491
+ },
44492
+ "additionalProperties": false
44493
+ },
44494
+ "PutFoundingWorkStagePageRequest": {
44495
+ "type": "object",
44496
+ "properties": {
44497
+ "page": {
44498
+ "type": "string"
44499
+ }
44500
+ },
44501
+ "additionalProperties": false
44502
+ },
43961
44503
  "PutGovernmentAsksMatterIdResponse": {
43962
44504
  "type": "object",
43963
44505
  "properties": {
@@ -44352,8 +44894,8 @@
44352
44894
  "description": "A required dependency/feature is not configured or is temporarily down."
44353
44895
  }
44354
44896
  },
44355
- "x-endpoint-count": 709,
44356
- "x-schema-count": 745,
44897
+ "x-endpoint-count": 719,
44898
+ "x-schema-count": 749,
44357
44899
  "x-undocumented-bodies": 12,
44358
44900
  "x-response-schemas": 468,
44359
44901
  "x-generated-by": "scripts/bongos/gen-api-docs.js"