@mindflight/mindbrain-personal-studio 0.6.1 → 0.6.3

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 (212) hide show
  1. package/README.md +16 -8
  2. package/build/client/_app/immutable/chunks/CIErFlYG.js +1 -0
  3. package/build/client/_app/immutable/chunks/CIErFlYG.js.br +0 -0
  4. package/build/client/_app/immutable/chunks/CIErFlYG.js.gz +0 -0
  5. package/build/client/_app/immutable/entry/{app.CVz6aYsT.js → app.mURYm8o_.js} +2 -2
  6. package/build/client/_app/immutable/entry/app.mURYm8o_.js.br +0 -0
  7. package/build/client/_app/immutable/entry/app.mURYm8o_.js.gz +0 -0
  8. package/build/client/_app/immutable/entry/start.D4M9ZeGO.js +1 -0
  9. package/build/client/_app/immutable/entry/start.D4M9ZeGO.js.br +2 -0
  10. package/build/client/_app/immutable/entry/start.D4M9ZeGO.js.gz +0 -0
  11. package/build/client/_app/immutable/nodes/{1.BBtxY46Q.js → 1.DHKtMeFI.js} +1 -1
  12. package/build/client/_app/immutable/nodes/1.DHKtMeFI.js.br +1 -0
  13. package/build/client/_app/immutable/nodes/1.DHKtMeFI.js.gz +0 -0
  14. package/build/client/_app/version.json +1 -1
  15. package/build/client/_app/version.json.br +0 -0
  16. package/build/client/_app/version.json.gz +0 -0
  17. package/build/handler.js +4 -4
  18. package/build/index.js +4 -4
  19. package/build/server/chunks/chunks/{internal.js-D8EA_he2.js → internal.js-C3tV0XXj.js} +2 -2
  20. package/build/server/chunks/chunks/{internal.js-D8EA_he2.js.map → internal.js-C3tV0XXj.js.map} +1 -1
  21. package/build/server/chunks/entries/endpoints/api/graph/schema-registry/{_server.ts.js-Dyfsc-VA.js → _server.ts.js-CAsXxBRq.js} +7 -2
  22. package/build/server/chunks/entries/endpoints/api/graph/schema-registry/_server.ts.js-CAsXxBRq.js.map +1 -0
  23. package/build/server/chunks/{handler-BjXBCd1c.js → handler-DlaCCnxx.js} +3 -3
  24. package/build/server/chunks/{handler-BjXBCd1c.js.map → handler-DlaCCnxx.js.map} +1 -1
  25. package/build/server/chunks/{index.js-BJYcV8V7.js → index.js-BGfKWHak.js} +2 -2
  26. package/build/server/chunks/{index.js-BJYcV8V7.js.map → index.js-BGfKWHak.js.map} +1 -1
  27. package/build/server/chunks/{manifest.js-Ddaot0P4.js → manifest.js-CnmaNf5D.js} +4 -4
  28. package/build/server/chunks/{manifest.js-Ddaot0P4.js.map → manifest.js-CnmaNf5D.js.map} +1 -1
  29. package/build/server/chunks/nodes/{1.js-BRigw_9J.js → 1.js-BypjwBYB.js} +2 -2
  30. package/build/server/chunks/nodes/{1.js-BRigw_9J.js.map → 1.js-BypjwBYB.js.map} +1 -1
  31. package/examples/immeuble/ACCEPTANCE.yaml +82 -0
  32. package/examples/immeuble/BIM_LITE.md +15 -0
  33. package/examples/immeuble/CHECKLIST.md +128 -0
  34. package/examples/immeuble/README.md +121 -0
  35. package/examples/immeuble/bundle/immeuble.bundle.json +22786 -0
  36. package/examples/immeuble/contracts/answer_artifacts.seed.jsonl +34 -0
  37. package/examples/immeuble/contracts/business_capabilities.seed.jsonl +25 -0
  38. package/examples/immeuble/contracts/consumer_contract.yaml +131 -0
  39. package/examples/immeuble/contracts/immeuble_structured_import_model.json +310 -0
  40. package/examples/immeuble/contracts/mapping_external_to_canonical.json +375 -0
  41. package/examples/immeuble/contracts/mapping_external_to_canonical.yaml +55 -0
  42. package/examples/immeuble/contracts/mapping_external_to_canonical_ws.json +65 -0
  43. package/examples/immeuble/contracts/model_contract.json +943 -0
  44. package/examples/immeuble/contracts/projection_catalog.yaml +366 -0
  45. package/examples/immeuble/contracts/scenarios.yaml +27 -0
  46. package/examples/immeuble/contracts/semantic_proposal.golden.json +1 -0
  47. package/examples/immeuble/contracts/source_profile.yaml +38 -0
  48. package/examples/immeuble/fake_data/DeltaFinding.csv +20 -0
  49. package/examples/immeuble/fake_data/ProjectionResult.csv +13 -0
  50. package/examples/immeuble/fake_data/ag_meeting.csv +4 -0
  51. package/examples/immeuble/fake_data/agenda_item.csv +4 -0
  52. package/examples/immeuble/fake_data/architect.csv +3 -0
  53. package/examples/immeuble/fake_data/architecture_firm.csv +2 -0
  54. package/examples/immeuble/fake_data/bank_account.csv +3 -0
  55. package/examples/immeuble/fake_data/billing_group.csv +41 -0
  56. package/examples/immeuble/fake_data/block.csv +10 -0
  57. package/examples/immeuble/fake_data/budget_line.csv +3 -0
  58. package/examples/immeuble/fake_data/building.csv +6 -0
  59. package/examples/immeuble/fake_data/cellar.csv +41 -0
  60. package/examples/immeuble/fake_data/change_order.csv +2 -0
  61. package/examples/immeuble/fake_data/charge_call.csv +58 -0
  62. package/examples/immeuble/fake_data/claim.csv +4 -0
  63. package/examples/immeuble/fake_data/coda_entry.csv +49 -0
  64. package/examples/immeuble/fake_data/compliance_certificate.csv +10 -0
  65. package/examples/immeuble/fake_data/contractor.csv +4 -0
  66. package/examples/immeuble/fake_data/decision.csv +5 -0
  67. package/examples/immeuble/fake_data/defect_reserve.csv +3 -0
  68. package/examples/immeuble/fake_data/household.csv +41 -0
  69. package/examples/immeuble/fake_data/inspection.csv +3 -0
  70. package/examples/immeuble/fake_data/insurance_policy.csv +4 -0
  71. package/examples/immeuble/fake_data/intervention.csv +13 -0
  72. package/examples/immeuble/fake_data/invoice.csv +3 -0
  73. package/examples/immeuble/fake_data/lease_contract.csv +12 -0
  74. package/examples/immeuble/fake_data/maintenance_ticket.csv +13 -0
  75. package/examples/immeuble/fake_data/meter.csv +4 -0
  76. package/examples/immeuble/fake_data/meter_reading.csv +19 -0
  77. package/examples/immeuble/fake_data/milestone.csv +3 -0
  78. package/examples/immeuble/fake_data/organization.csv +12 -0
  79. package/examples/immeuble/fake_data/parking_space.csv +8 -0
  80. package/examples/immeuble/fake_data/permit.csv +3 -0
  81. package/examples/immeuble/fake_data/person.csv +85 -0
  82. package/examples/immeuble/fake_data/private_garden.csv +7 -0
  83. package/examples/immeuble/fake_data/progress_event.csv +2 -0
  84. package/examples/immeuble/fake_data/quote.csv +3 -0
  85. package/examples/immeuble/fake_data/receipt.csv +2 -0
  86. package/examples/immeuble/fake_data/reminder.csv +11 -0
  87. package/examples/immeuble/fake_data/service_contract.csv +4 -0
  88. package/examples/immeuble/fake_data/shared_equipment.csv +8 -0
  89. package/examples/immeuble/fake_data/shared_space.csv +10 -0
  90. package/examples/immeuble/fake_data/unit.csv +41 -0
  91. package/examples/immeuble/fake_data/work_package.csv +4 -0
  92. package/examples/immeuble/fake_data/worksite_project.csv +3 -0
  93. package/examples/immeuble/gap-rules/L0-patrimoine.json +57 -0
  94. package/examples/immeuble/gap-rules/L1-syndic-naive.json +36 -0
  95. package/examples/immeuble/gap-rules/L1-syndic.json +61 -0
  96. package/examples/immeuble/gap-rules/L2-chantier.json +87 -0
  97. package/examples/immeuble/gap-rules/L2-exploitation.json +87 -0
  98. package/examples/immeuble/gap-rules/L2-finance.json +48 -0
  99. package/examples/immeuble/gap-rules/L2-maintenance.json +107 -0
  100. package/examples/immeuble/gap-rules/L2-syndic-filtered.json +39 -0
  101. package/examples/immeuble/gap-rules/L3-full.json +332 -0
  102. package/examples/immeuble/gap-rules/closed-world-contract.md +76 -0
  103. package/examples/immeuble/gap-rules/demo.json +51 -0
  104. package/examples/immeuble/gap-rules/expected-findings.yaml +100 -0
  105. package/examples/immeuble/gap-rules/gap-scenarios.yaml +79 -0
  106. package/examples/immeuble/gap-rules/motifs.json +38 -0
  107. package/examples/immeuble/gap-rules/syndic.json +40 -0
  108. package/examples/immeuble/import_manifest.yaml +25 -0
  109. package/examples/immeuble/import_ready/graph_edges_import.csv +848 -0
  110. package/examples/immeuble/import_ready/mfo_facets_import.csv +559 -0
  111. package/examples/immeuble/index.md +140 -0
  112. package/examples/immeuble/model/immeuble_model.json +418 -0
  113. package/examples/immeuble/reports/01-model.validation.json +56 -0
  114. package/examples/immeuble/reports/02-mapping.validation.json +9 -0
  115. package/examples/immeuble/reports/acceptance.validation.json +161 -0
  116. package/examples/immeuble/reports/consumer_contract.validation.json +162 -0
  117. package/examples/immeuble/reports/graph_edges.jsonl +847 -0
  118. package/examples/immeuble/reports/graph_nodes.jsonl +558 -0
  119. package/examples/immeuble/reports/hybrid-compare.json +144 -0
  120. package/examples/immeuble/reports/immeuble-import-scenario.json +233 -0
  121. package/examples/immeuble/reports/live-artifacts-refresh.validation.json +51 -0
  122. package/examples/immeuble/reports/pipeline_audit.json +59 -0
  123. package/examples/immeuble/reports/projection_audit.json +69 -0
  124. package/examples/immeuble/reports/projection_audit_immeuble.json +257 -0
  125. package/examples/immeuble/reports/projection_audit_immeuble.md +122 -0
  126. package/examples/immeuble/reports/projection_candidates.json +1596 -0
  127. package/examples/immeuble/reports/projection_candidates.md +117 -0
  128. package/examples/immeuble/reports/projection_model_validation.md +115 -0
  129. package/examples/immeuble/reports/reindex.json +4 -0
  130. package/examples/immeuble/reports/reset-immeuble-workspace.json +32 -0
  131. package/examples/immeuble/reports/schema-id-prefix-check.json +5 -0
  132. package/examples/immeuble/scripts/audit-immeuble-projections.mjs +254 -0
  133. package/examples/immeuble/scripts/build-immeuble-model.mjs +308 -0
  134. package/examples/immeuble/scripts/compare-immeuble-snapshots.sh +227 -0
  135. package/examples/immeuble/scripts/enrich-immeuble-demo.mjs +1135 -0
  136. package/examples/immeuble/scripts/reset-immeuble-workspace.mjs +139 -0
  137. package/examples/immeuble/scripts/run-immeuble-backend.sh +164 -0
  138. package/examples/immeuble/scripts/run-immeuble-import.mjs +232 -0
  139. package/examples/immeuble/scripts/run-immeuble-live-lab.sh +439 -0
  140. package/examples/immeuble/scripts/seed-immeuble-gap-rules.mjs +69 -0
  141. package/examples/immeuble/scripts/start-immeuble-demo.sh +52 -0
  142. package/examples/immeuble/scripts/starterkit/analysis-lenses.mjs +181 -0
  143. package/examples/immeuble/scripts/starterkit/analyze-projection-candidates.mjs +714 -0
  144. package/examples/immeuble/scripts/starterkit/audit-ghostcrab-projections.mjs +674 -0
  145. package/examples/immeuble/scripts/starterkit/facet-prefix.mjs +166 -0
  146. package/examples/immeuble/scripts/starterkit/sqlite-utils.mjs +131 -0
  147. package/examples/immeuble/scripts/verify-immeuble-acceptance.mjs +284 -0
  148. package/examples/immeuble/scripts/verify-immeuble-live-artifacts.mjs +140 -0
  149. package/examples/immeuble/scripts/yaml-lite.mjs +96 -0
  150. package/examples/immeuble/sources/agent-prompts/prompts/00-prerequisites-immo-mcp.md +161 -0
  151. package/examples/immeuble/sources/agent-prompts/prompts/00-prerequisites.md +39 -0
  152. package/examples/immeuble/sources/agent-prompts/prompts/01-discovery-and-model-proposal.md +42 -0
  153. package/examples/immeuble/sources/agent-prompts/prompts/02-ontology-register.md +44 -0
  154. package/examples/immeuble/sources/agent-prompts/prompts/03-gap-rules-design.md +44 -0
  155. package/examples/immeuble/sources/agent-prompts/prompts/04-document-ingest.md +40 -0
  156. package/examples/immeuble/sources/agent-prompts/prompts/05-graph-extraction.md +44 -0
  157. package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare-immo-mcp.md +109 -0
  158. package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare-test-immo-mcp3.md +30 -0
  159. package/examples/immeuble/sources/agent-prompts/prompts/06-validate-and-compare.md +63 -0
  160. package/examples/immeuble/sources/checklists/gap-rules-checklist.md +42 -0
  161. package/examples/immeuble/sources/checklists/ontology-checklist.md +54 -0
  162. package/examples/immeuble/sources/documents/README.md +42 -0
  163. package/examples/immeuble/sources/documents/annexes-caves-garages-jardins.md +8 -0
  164. package/examples/immeuble/sources/documents/annexes-jardins-garages.md +1 -0
  165. package/examples/immeuble/sources/documents/baux-erables.md +1 -0
  166. package/examples/immeuble/sources/documents/baux-locatifs.md +11 -0
  167. package/examples/immeuble/sources/documents/coda-janvier-2026.md +10 -0
  168. package/examples/immeuble/sources/documents/composition-menages.md +1 -0
  169. package/examples/immeuble/sources/documents/composition-occupants.md +18 -0
  170. package/examples/immeuble/sources/documents/expected-coverage.json +70 -0
  171. package/examples/immeuble/sources/documents/extrait-coda-janvier-2026.md +1 -0
  172. package/examples/immeuble/sources/documents/groupes-facturation.md +30 -0
  173. package/examples/immeuble/sources/documents/manifest.json +79 -0
  174. package/examples/immeuble/sources/documents/note-architecte-chantier-erables.md +3 -0
  175. package/examples/immeuble/sources/documents/permis-urbanisme-erables.md +3 -0
  176. package/examples/immeuble/sources/documents/procedures-operationnelles.md +3 -0
  177. package/examples/immeuble/sources/documents/pv-ag-budget-2026.md +1 -0
  178. package/examples/immeuble/sources/documents/pv-reception-reserves-erables.md +3 -0
  179. package/examples/immeuble/sources/documents/registre-coproprietaires.md +24 -0
  180. package/examples/immeuble/sources/documents/reglement-copropriete-tilleuls.md +1 -0
  181. package/examples/immeuble/sources/documents/statuts-erables.md +22 -0
  182. package/examples/immeuble/sources/documents/statuts-tilleuls.md +19 -0
  183. package/examples/immeuble/sources/documents/succession-jean-dupont.md +3 -0
  184. package/examples/immeuble/sources/documents/titre-propriete-tilleuls-a3.md +1 -0
  185. package/examples/immeuble/sources/documents/trous-pedagogiques.md +3 -0
  186. package/examples/immeuble/sources/ontology/README.md +1 -0
  187. package/examples/immeuble/sources/ontology/core.yaml +444 -0
  188. package/examples/immeuble/success-criteria.yaml +35 -0
  189. package/fixtures/immeuble-demo.sqlite +0 -0
  190. package/package.json +16 -3
  191. package/scripts/lib/sqlite-runtime.mjs +1 -1
  192. package/scripts/load-immeuble-demo.sh +103 -0
  193. package/scripts/seed-immeuble-projections.mjs +75 -148
  194. package/scripts/verify-immeuble-demo-sources.mjs +93 -0
  195. package/scripts/verify-immeuble-demo.mjs +69 -0
  196. package/build/client/_app/immutable/chunks/BmeSanva.js +0 -1
  197. package/build/client/_app/immutable/chunks/BmeSanva.js.br +0 -0
  198. package/build/client/_app/immutable/chunks/BmeSanva.js.gz +0 -0
  199. package/build/client/_app/immutable/entry/app.CVz6aYsT.js.br +0 -0
  200. package/build/client/_app/immutable/entry/app.CVz6aYsT.js.gz +0 -0
  201. package/build/client/_app/immutable/entry/start.Bt5tVOz8.js +0 -1
  202. package/build/client/_app/immutable/entry/start.Bt5tVOz8.js.br +0 -2
  203. package/build/client/_app/immutable/entry/start.Bt5tVOz8.js.gz +0 -0
  204. package/build/client/_app/immutable/nodes/1.BBtxY46Q.js.br +0 -0
  205. package/build/client/_app/immutable/nodes/1.BBtxY46Q.js.gz +0 -0
  206. package/build/server/chunks/entries/endpoints/api/graph/schema-registry/_server.ts.js-Dyfsc-VA.js.map +0 -1
  207. package/scripts/build-serenity-v6-concept-review-pack.mjs +0 -493
  208. package/scripts/build-serenity-v6-review-pack.mjs +0 -479
  209. package/scripts/create-serenity-production-v6.mjs +0 -627
  210. package/scripts/export-serenity-v6-backup.mjs +0 -178
  211. package/scripts/import-serenity-v6-user-decisions.mjs +0 -543
  212. package/scripts/materialize-serenity-v6-snapshots.mjs +0 -675
@@ -0,0 +1,439 @@
1
+ #!/usr/bin/env bash
2
+ # Run a complete Immeuble pipeline against a fresh SQLite DB with a managed backend.
3
+ # Backend launch is standalone (`ghostcrab-backend`), and gcp steps talk to its HTTP
4
+ # endpoint via `GHOSTCRAB_MINDBRAIN_URL`.
5
+ set -eu
6
+
7
+ REPO_ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)"
8
+ IMMEUBLE_ROOT="$REPO_ROOT/examples/immeuble"
9
+ BACKEND_SCRIPT="$IMMEUBLE_ROOT/scripts/run-immeuble-backend.sh"
10
+ NODE_BIN="${NODE:-node}"
11
+ BACKEND_BIN="${GHOSTCRAB_BACKEND_BIN:-$REPO_ROOT/cmd/backend/zig-out/bin/ghostcrab-backend}"
12
+ BACKEND_ADDR="${GHOSTCRAB_BACKEND_ADDR:-:8091}"
13
+ BACKEND_HOST="127.0.0.1"
14
+ BACKEND_PORT="${BACKEND_ADDR##*:}"
15
+ BACKEND_URL="http://$BACKEND_HOST:${BACKEND_PORT}"
16
+ DB_PATH="$REPO_ROOT/data/immeuble-lab.sqlite"
17
+ WORKSPACE_ID="immeuble"
18
+ ENGINE="legacy"
19
+ REPORTS_DIR="$IMMEUBLE_ROOT/reports"
20
+ BACKUP_DIR="$REPO_ROOT/data/immeuble-lab-backups"
21
+ RUN_BUNDLE=0
22
+ RUN_ARTIFACT_SEED=0
23
+ RUN_BUSINESS_CAPABILITIES=0
24
+ RUN_LIVE_VERIFY=0
25
+ RUN_PROJECTION_PLAN=0
26
+ RUN_LEGACY_AUDIT=0
27
+ PROJECTION_STRICT=0
28
+ AUTO_ARTIFACT_SEED=0
29
+ STOP_AFTER=""
30
+ SKIP_PREFLIGHT=1
31
+ SKIP_PROVENANCE=1
32
+ SKIP_IF_NO_DB=0
33
+ REQUIRE_HYBRID=0
34
+
35
+ usage() {
36
+ cat <<EOF
37
+ Usage: examples/immeuble/scripts/run-immeuble-live-lab.sh [options]
38
+
39
+ Run the Immeuble pipeline and snapshot the SQLite DB after each executed stage.
40
+
41
+ Options:
42
+ --db <path> SQLite file to use (default: $DB_PATH)
43
+ --workspace-id <id> Workspace id (default: immeuble)
44
+ --engine <legacy|both> Import engine for structured import (default: legacy)
45
+ --backend-bin <path> ghostcrab-backend binary path
46
+ --backend-addr <:port> backend listen address (default: :8091)
47
+ --backup-dir <path> directory where sqlite snapshots are stored
48
+ --with-bundle-load load examples/immeuble/bundle/immeuble.bundle.json after import
49
+ --with-artifact-seed load answer artifact seed after import
50
+ --with-business-capabilities load business capability seed after import
51
+ --with-live-verify run live refresh verification (requires running backend, and enables answer artifact seed)
52
+ --with-projection-plan run StarterKit projection candidate analysis before import
53
+ --with-legacy-audit run legacy audit-immeuble-projections.mjs smoke (optional)
54
+ --projection-strict fail on projection plan/audit gaps (facets, edges, schemas, missing scopes)
55
+ --stop-after <stage> stop after one stage: build|projection_plan|import|verify|bundle|artifact_seed|audit|live_verify
56
+ --preflight force preflight checks during import
57
+ --validate-provenance force provenance validation during import
58
+ --require-hybrid require hybrid deltas to be 0 after import
59
+ --keep-existing-db keep existing DB file (do not delete before run)
60
+ -h, --help show this help
61
+
62
+ Note:
63
+ The script starts a local MindBrain backend process (standalone HTTP server, default 127.0.0.1:8091)
64
+ and runs commands through gcp and other Immeuble scripts.
65
+ EOF
66
+ }
67
+
68
+ for arg in "$@"; do
69
+ case "$arg" in
70
+ -h|--help)
71
+ usage
72
+ exit 0
73
+ ;;
74
+ esac
75
+ done
76
+
77
+ while [[ $# -gt 0 ]]; do
78
+ case "$1" in
79
+ --db)
80
+ DB_PATH="${2:?--db requires a value}"
81
+ shift 2
82
+ ;;
83
+ --workspace-id)
84
+ WORKSPACE_ID="${2:?--workspace-id requires a value}"
85
+ shift 2
86
+ ;;
87
+ --engine)
88
+ ENGINE="${2:?--engine requires a value}"
89
+ if [[ "$ENGINE" != "legacy" && "$ENGINE" != "both" ]]; then
90
+ echo "[immeuble-lab] --engine must be legacy or both" >&2
91
+ exit 1
92
+ fi
93
+ shift 2
94
+ ;;
95
+ --backend-bin)
96
+ BACKEND_BIN="${2:?--backend-bin requires a value}"
97
+ shift 2
98
+ ;;
99
+ --backend-addr)
100
+ BACKEND_ADDR="${2:?--backend-addr requires a value}"
101
+ BACKEND_PORT="${BACKEND_ADDR##*:}"
102
+ BACKEND_URL="http://$BACKEND_HOST:${BACKEND_PORT}"
103
+ shift 2
104
+ ;;
105
+ --backup-dir)
106
+ BACKUP_DIR="${2:?--backup-dir requires a value}"
107
+ shift 2
108
+ ;;
109
+ --with-bundle-load)
110
+ RUN_BUNDLE=1
111
+ shift
112
+ ;;
113
+ --with-artifact-seed)
114
+ RUN_ARTIFACT_SEED=1
115
+ shift
116
+ ;;
117
+ --with-business-capabilities)
118
+ RUN_BUSINESS_CAPABILITIES=1
119
+ shift
120
+ ;;
121
+ --with-live-verify)
122
+ RUN_LIVE_VERIFY=1
123
+ shift
124
+ ;;
125
+ --with-projection-plan)
126
+ RUN_PROJECTION_PLAN=1
127
+ shift
128
+ ;;
129
+ --with-legacy-audit)
130
+ RUN_LEGACY_AUDIT=1
131
+ shift
132
+ ;;
133
+ --projection-strict)
134
+ PROJECTION_STRICT=1
135
+ shift
136
+ ;;
137
+ --stop-after)
138
+ STOP_AFTER="${2:?--stop-after requires a stage}"
139
+ case "$STOP_AFTER" in
140
+ build|projection_plan|import|verify|bundle|artifact_seed|business_capability_seed|audit|live_verify)
141
+ ;;
142
+ *)
143
+ echo "[immeuble-lab] invalid stage for --stop-after: $STOP_AFTER" >&2
144
+ exit 1
145
+ ;;
146
+ esac
147
+ shift 2
148
+ ;;
149
+ --preflight)
150
+ SKIP_PREFLIGHT=0
151
+ shift
152
+ ;;
153
+ --validate-provenance)
154
+ SKIP_PROVENANCE=0
155
+ shift
156
+ ;;
157
+ --require-hybrid)
158
+ REQUIRE_HYBRID=1
159
+ shift
160
+ ;;
161
+ --keep-existing-db)
162
+ SKIP_IF_NO_DB=1
163
+ shift
164
+ ;;
165
+ *)
166
+ echo "[immeuble-lab] unknown argument: $1" >&2
167
+ usage
168
+ exit 1
169
+ ;;
170
+ esac
171
+ done
172
+
173
+ if (( RUN_LIVE_VERIFY == 1 && RUN_ARTIFACT_SEED == 0 )); then
174
+ AUTO_ARTIFACT_SEED=1
175
+ RUN_ARTIFACT_SEED=1
176
+ echo "[immeuble-lab] auto-enabling artifact seed because --with-live-verify was requested"
177
+ fi
178
+
179
+ mkdir -p "$BACKUP_DIR"
180
+ mkdir -p "$REPORTS_DIR"
181
+ mkdir -p "$(dirname "$DB_PATH")"
182
+
183
+ if (( SKIP_IF_NO_DB == 0 )); then
184
+ rm -f "$DB_PATH" "$DB_PATH-wal" "$DB_PATH-shm"
185
+ fi
186
+
187
+ if [[ ! -x "$BACKEND_BIN" ]]; then
188
+ echo "[immeuble-lab] backend binary not found: $BACKEND_BIN" >&2
189
+ echo " build it with: ZIG=zig-0.16 pnpm run backend:build" >&2
190
+ exit 1
191
+ fi
192
+
193
+ if [[ ! -x "$BACKEND_SCRIPT" ]]; then
194
+ echo "[immeuble-lab] backend wrapper not found: $BACKEND_SCRIPT" >&2
195
+ exit 1
196
+ fi
197
+
198
+ BACKEND_PID=""
199
+ BACKEND_LOG_FILE="${BACKEND_LOG_FILE:-$IMMEUBLE_ROOT/.tmp-backend-lab.log}"
200
+
201
+ cleanup() {
202
+ if [[ -n "$BACKEND_PID" ]]; then
203
+ kill "$BACKEND_PID" 2>/dev/null || true
204
+ wait "$BACKEND_PID" 2>/dev/null || true
205
+ BACKEND_PID=""
206
+ fi
207
+ }
208
+ trap cleanup EXIT
209
+
210
+ backend_flags=(
211
+ --db "$DB_PATH"
212
+ --backend-bin "$BACKEND_BIN"
213
+ --backend-addr "$BACKEND_ADDR"
214
+ --workspace-name "$WORKSPACE_ID"
215
+ --log-file "$BACKEND_LOG_FILE"
216
+ --ready-timeout 30
217
+ )
218
+
219
+ echo "[immeuble-lab] starting backend via $BACKEND_SCRIPT"
220
+ backend_output="$("$BACKEND_SCRIPT" "${backend_flags[@]}")" || {
221
+ echo "[immeuble-lab] backend wrapper failed" >&2
222
+ exit 1
223
+ }
224
+
225
+ BACKEND_PID="$(printf '%s\n' "$backend_output" | sed -n 's/^\[immeuble-backend\] BACKEND_PID=//p' | tail -1)"
226
+ parsed_backend_url="$(printf '%s\n' "$backend_output" | sed -n 's/^\[immeuble-backend\] BACKEND_URL=//p' | tail -1)"
227
+
228
+ if [[ -z "$BACKEND_PID" ]]; then
229
+ echo "[immeuble-lab] could not parse BACKEND_PID from backend wrapper output" >&2
230
+ printf '%s\n' "$backend_output" >&2
231
+ exit 1
232
+ fi
233
+
234
+ if [[ -n "$parsed_backend_url" ]]; then
235
+ BACKEND_URL="$parsed_backend_url"
236
+ fi
237
+
238
+ echo "[immeuble-lab] backend pid=$BACKEND_PID log=$BACKEND_LOG_FILE url=$BACKEND_URL"
239
+
240
+ export GHOSTCRAB_MINDBRAIN_URL="$BACKEND_URL"
241
+ export GHOSTCRAB_MINDBRAIN_HTTP_TIMEOUT_MS="${GHOSTCRAB_MINDBRAIN_HTTP_TIMEOUT_MS:-30000}"
242
+
243
+ run_step() {
244
+ local name="$1"
245
+ shift
246
+
247
+ echo "[immeuble-lab] step: $name"
248
+ if ! "$@"; then
249
+ echo "[immeuble-lab] step failed: $name" >&2
250
+ return 1
251
+ fi
252
+ take_snapshot "$name"
253
+ if [[ -n "$STOP_AFTER" && "$STOP_AFTER" == "$name" ]]; then
254
+ echo "[immeuble-lab] stopping after $name (requested by --stop-after)"
255
+ exit 0
256
+ fi
257
+ }
258
+
259
+ take_snapshot() {
260
+ local stage="$1"
261
+ local ts
262
+ ts="$(date +%Y%m%d-%H%M%S)"
263
+ local suffix="${ts}-${stage}.sqlite"
264
+ local dst="$BACKUP_DIR/$suffix"
265
+
266
+ if [[ ! -f "$DB_PATH" ]]; then
267
+ echo "[immeuble-lab] snapshot skipped (missing db): $dst"
268
+ return 0
269
+ fi
270
+
271
+ if command -v sqlite3 >/dev/null 2>&1; then
272
+ if ! sqlite3 "$DB_PATH" ".backup '$dst'"; then
273
+ echo "[immeuble-lab] sqlite backup failed with sqlite3, fallback to cp: $dst" >&2
274
+ cp -f "$DB_PATH" "$dst"
275
+ fi
276
+ else
277
+ cp -f "$DB_PATH" "$dst"
278
+ fi
279
+ for suffix_ext in -wal -shm; do
280
+ if [[ -f "$DB_PATH$suffix_ext" ]]; then
281
+ cp -f "$DB_PATH$suffix_ext" "$dst$suffix_ext"
282
+ fi
283
+ done
284
+
285
+ echo "[immeuble-lab] snapshot: $dst"
286
+ }
287
+
288
+ build_step() {
289
+ "$NODE_BIN" "$IMMEUBLE_ROOT/scripts/build-immeuble-model.mjs"
290
+ }
291
+
292
+ import_step() {
293
+ local flags=(
294
+ "--apply"
295
+ "--workspace-id" "$WORKSPACE_ID"
296
+ "--db" "$DB_PATH"
297
+ "--engine" "$ENGINE"
298
+ )
299
+
300
+ if [[ "$SKIP_PREFLIGHT" -eq 1 ]]; then
301
+ flags+=("--skip-preflight")
302
+ fi
303
+ if [[ "$SKIP_PROVENANCE" -eq 1 ]]; then
304
+ flags+=("--skip-provenance-validation")
305
+ fi
306
+ if [[ "$ENGINE" == "both" ]]; then
307
+ flags+=(
308
+ "--compare-output" "$REPORTS_DIR/hybrid-compare.json"
309
+ )
310
+ fi
311
+ flags+=("--force")
312
+ "$NODE_BIN" "$IMMEUBLE_ROOT/scripts/run-immeuble-import.mjs" "${flags[@]}"
313
+ }
314
+
315
+ verify_step() {
316
+ local flags=("--db" "$DB_PATH")
317
+ if [[ "$REQUIRE_HYBRID" -eq 1 ]]; then
318
+ flags+=("--require-hybrid")
319
+ fi
320
+ if [[ "$PROJECTION_STRICT" -eq 1 ]]; then
321
+ flags+=("--projection-strict")
322
+ fi
323
+ if [[ "$RUN_BUSINESS_CAPABILITIES" -eq 1 ]]; then
324
+ flags+=("--require-business-capabilities")
325
+ fi
326
+ "$NODE_BIN" "$IMMEUBLE_ROOT/scripts/verify-immeuble-acceptance.mjs" "${flags[@]}"
327
+ }
328
+
329
+ artifact_seed_step() {
330
+ "$NODE_BIN" "$REPO_ROOT/bin/gcp.mjs" \
331
+ load "$IMMEUBLE_ROOT/contracts/answer_artifacts.seed.jsonl" \
332
+ --workspace "$WORKSPACE_ID"
333
+ }
334
+
335
+ business_capability_seed_step() {
336
+ "$NODE_BIN" "$REPO_ROOT/bin/gcp.mjs" \
337
+ load "$IMMEUBLE_ROOT/contracts/business_capabilities.seed.jsonl" \
338
+ --workspace "$WORKSPACE_ID"
339
+ }
340
+
341
+ bundle_step() {
342
+ "$NODE_BIN" "$REPO_ROOT/bin/gcp.mjs" \
343
+ load "$IMMEUBLE_ROOT/bundle/immeuble.bundle.json" \
344
+ --workspace "$WORKSPACE_ID" \
345
+ --reindex all \
346
+ --force
347
+ }
348
+
349
+ STARTERKIT_DIR="$IMMEUBLE_ROOT/scripts/starterkit"
350
+ MODEL_CONTRACT="$IMMEUBLE_ROOT/contracts/model_contract.json"
351
+ PROJECTION_CATALOG="$IMMEUBLE_ROOT/contracts/projection_catalog.yaml"
352
+ ARTIFACT_SEED="$IMMEUBLE_ROOT/contracts/answer_artifacts.seed.jsonl"
353
+
354
+ projection_plan_step() {
355
+ local flags=(
356
+ "--db" "$DB_PATH"
357
+ "--workspace" "$WORKSPACE_ID"
358
+ "--projection-catalog" "$PROJECTION_CATALOG"
359
+ "--model-contract" "$MODEL_CONTRACT"
360
+ "--output-dir" "$REPORTS_DIR"
361
+ "--include-blind-spots"
362
+ "--include-jtbd"
363
+ )
364
+ if [[ "$PROJECTION_STRICT" -eq 1 ]]; then
365
+ flags+=("--strict")
366
+ fi
367
+ "$NODE_BIN" "$STARTERKIT_DIR/analyze-projection-candidates.mjs" "${flags[@]}"
368
+ }
369
+
370
+ audit_step() {
371
+ local flags=(
372
+ "--db" "$DB_PATH"
373
+ "--workspace" "$WORKSPACE_ID"
374
+ "--model" "$MODEL_CONTRACT"
375
+ "--answer-artifacts-seed" "$ARTIFACT_SEED"
376
+ "--output-dir" "$REPORTS_DIR"
377
+ )
378
+ if [[ "$PROJECTION_STRICT" -eq 1 ]]; then
379
+ flags+=("--strict")
380
+ fi
381
+ "$NODE_BIN" "$STARTERKIT_DIR/audit-ghostcrab-projections.mjs" "${flags[@]}"
382
+ }
383
+
384
+ legacy_audit_step() {
385
+ "$NODE_BIN" "$IMMEUBLE_ROOT/scripts/audit-immeuble-projections.mjs" \
386
+ --workspace-id "$WORKSPACE_ID"
387
+ }
388
+
389
+ live_verify_step() {
390
+ "$NODE_BIN" "$IMMEUBLE_ROOT/scripts/verify-immeuble-live-artifacts.mjs" \
391
+ --workspace-id "$WORKSPACE_ID" \
392
+ --url "$BACKEND_URL"
393
+ }
394
+
395
+ # Snapshot before first step.
396
+ take_snapshot "00-start"
397
+
398
+ run_step "build" build_step
399
+
400
+ if [[ "$RUN_PROJECTION_PLAN" -eq 1 ]]; then
401
+ run_step "projection_plan" projection_plan_step
402
+ fi
403
+
404
+ run_step "import" import_step
405
+
406
+ if [[ "$RUN_ARTIFACT_SEED" -eq 1 ]]; then
407
+ if (( AUTO_ARTIFACT_SEED == 1 )); then
408
+ echo "[immeuble-lab] loading artifact seed for live verification preconditions"
409
+ fi
410
+ run_step "artifact_seed" artifact_seed_step
411
+ fi
412
+
413
+ if [[ "$RUN_BUSINESS_CAPABILITIES" -eq 1 ]]; then
414
+ run_step "business_capability_seed" business_capability_seed_step
415
+ fi
416
+
417
+ if [[ "$RUN_BUNDLE" -eq 1 ]]; then
418
+ run_step "bundle" bundle_step
419
+ fi
420
+
421
+ run_step "audit" audit_step
422
+ run_step "verify" verify_step
423
+
424
+ if [[ "$RUN_LEGACY_AUDIT" -eq 1 ]]; then
425
+ echo "[immeuble-lab] running legacy projection smoke audit"
426
+ legacy_audit_step || {
427
+ if [[ "$PROJECTION_STRICT" -eq 1 ]]; then
428
+ echo "[immeuble-lab] legacy audit failed in strict mode" >&2
429
+ exit 1
430
+ fi
431
+ echo "[immeuble-lab] legacy audit failed (informational, non-blocking)"
432
+ }
433
+ fi
434
+
435
+ if [[ "$RUN_LIVE_VERIFY" -eq 1 ]]; then
436
+ run_step "live_verify" live_verify_step
437
+ fi
438
+
439
+ echo "[immeuble-lab] completed"
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { spawnSync } from "node:child_process";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
8
+ const args = process.argv.slice(2);
9
+ const db = resolve(parseFlag(args, "--db", process.env.GHOSTCRAB_SQLITE_PATH ?? "fixtures/immeuble-demo.sqlite"));
10
+ const rulesPath = resolve(parseFlag(args, "--rules", join(root, "gap-rules", "L3-full.json")));
11
+
12
+ if (!existsSync(db)) fail(`SQLite not found: ${db}`);
13
+ if (!existsSync(rulesPath)) fail(`rules file not found: ${rulesPath}`);
14
+
15
+ const payload = JSON.parse(readFileSync(rulesPath, "utf8"));
16
+ const rules = Array.isArray(payload.rules) ? payload.rules : [];
17
+ if (!rules.length) fail(`no rules in ${rulesPath}`);
18
+
19
+ sql(`DELETE FROM graph_gap_rules WHERE workspace_id=${quote(payload.workspace_id)} AND ontology_id=${quote(payload.ontology_id)};`);
20
+ for (const rule of rules) {
21
+ sql(`
22
+ INSERT INTO graph_gap_rules (
23
+ rule_id, ontology_id, workspace_id, entity_type, relation_type, direction,
24
+ target_entity_type, min_count, max_count, severity, label, enabled, metadata_json
25
+ ) VALUES (
26
+ ${quote(rule.rule_id)},
27
+ ${quote(payload.ontology_id)},
28
+ ${quote(payload.workspace_id)},
29
+ ${quote(rule.entity_type)},
30
+ ${quote(rule.relation_type)},
31
+ ${quote(rule.direction)},
32
+ ${rule.target_entity_type == null ? "NULL" : quote(rule.target_entity_type)},
33
+ ${Number(rule.min_count ?? 1)},
34
+ ${rule.max_count == null ? "NULL" : Number(rule.max_count)},
35
+ ${quote(rule.severity ?? "warning")},
36
+ ${quote(rule.label ?? rule.rule_id)},
37
+ ${rule.enabled === false ? 0 : 1},
38
+ ${quote(rule.metadata_json ?? "{}")}
39
+ );
40
+ `);
41
+ }
42
+
43
+ console.log(JSON.stringify({
44
+ ok: true,
45
+ db,
46
+ rules: rules.length,
47
+ workspace_id: payload.workspace_id,
48
+ ontology_id: payload.ontology_id
49
+ }, null, 2));
50
+
51
+ function sql(query) {
52
+ const res = spawnSync("sqlite3", [db, query], { encoding: "utf8" });
53
+ if (res.status !== 0) fail(res.stderr || res.stdout || "sqlite3 failed");
54
+ return res.stdout.trim();
55
+ }
56
+
57
+ function quote(value) {
58
+ return `'${String(value).replace(/'/g, "''")}'`;
59
+ }
60
+
61
+ function parseFlag(argv, name, defaultValue) {
62
+ const index = argv.indexOf(name);
63
+ return index === -1 ? defaultValue : argv[index + 1] ?? defaultValue;
64
+ }
65
+
66
+ function fail(message) {
67
+ console.error(`error: ${message}`);
68
+ process.exit(1);
69
+ }
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bash
2
+ # Start the Immeuble demo pipeline end-to-end.
3
+ set -eu
4
+
5
+ REPO_ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd)"
6
+ IMMEUBLE_ROOT="$REPO_ROOT/examples/immeuble"
7
+ LIVE_LAB_SCRIPT="$IMMEUBLE_ROOT/scripts/run-immeuble-live-lab.sh"
8
+
9
+ usage() {
10
+ cat <<EOF
11
+ Usage: examples/immeuble/scripts/start-immeuble-demo.sh [run-immeuble-live-lab args...]
12
+
13
+ Start the Immeuble backend and run the full live lab flow.
14
+
15
+ If --with-live-verify is not provided, this wrapper enables it automatically so
16
+ the run includes artifact seed + live verification by default.
17
+
18
+ Examples:
19
+ ./examples/immeuble/scripts/start-immeuble-demo.sh --db /tmp/immeuble-lab-complete.sqlite --engine both
20
+ ./examples/immeuble/scripts/start-immeuble-demo.sh --db /tmp/immeuble-lab-complete.sqlite --engine both --stop-after live_verify
21
+ ./examples/immeuble/scripts/start-immeuble-demo.sh --help
22
+ EOF
23
+ }
24
+
25
+ if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
26
+ usage
27
+ exit 0
28
+ fi
29
+
30
+ if [[ ! -x "$LIVE_LAB_SCRIPT" ]]; then
31
+ echo "[immeuble-demo] unable to run live-lab script: $LIVE_LAB_SCRIPT" >&2
32
+ exit 1
33
+ fi
34
+
35
+ LIVE_ARGS=()
36
+ HAS_LIVE_VERIFY=0
37
+
38
+ for arg in "$@"; do
39
+ if [[ "$arg" == "--with-live-verify" ]]; then
40
+ HAS_LIVE_VERIFY=1
41
+ break
42
+ fi
43
+ done
44
+
45
+ if (( HAS_LIVE_VERIFY == 0 )); then
46
+ LIVE_ARGS+=("--with-live-verify")
47
+ fi
48
+
49
+ LIVE_ARGS+=("$@")
50
+
51
+ echo "[immeuble-demo] running: $LIVE_LAB_SCRIPT ${LIVE_ARGS[*]}"
52
+ exec "$LIVE_LAB_SCRIPT" "${LIVE_ARGS[@]}"