You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,7 @@
28
28
- Philosophy: "Data as Code", Idempotency, and Immutable Infrastructure are the defaults.
29
29
6.**Long-Term Architecture:** Do NOT use simplified or temporary workarounds. Always adopt sustainable, well-architected solutions.
30
30
7.**Short Object Names Are Canonical:** Always write **short** object names (e.g. `account`, `task`) in user code, examples, queries, REST URLs, formulas, hooks, and lookups. **Never** type FQN (`{namespace}__name`, e.g. `crm__account`) in user-facing code, docs, or AI-generated output. **Never** set `tableName` on an object schema — the field has been removed; the physical table name is always derived from the short name. FQN is an internal-only mechanic used by the registry for cross-package disambiguation, marketplace publishing, and customization `baseName` references.
31
+
8.**One Zod Source per Metadata Type:** Each metadata type (`view`, `dashboard`, `flow`, `agent`, `tool`, `object`, …) has exactly **one** Zod schema in `packages/spec/src/{domain}/`. Do **not** re-declare the same shape as a `*.object.ts` projection table — that pattern is removed (see ADR-0005). Runtime org overlay opt-in lives in **one** place: the `allowOrgOverride` flag on the type's entry in `DEFAULT_METADATA_TYPE_REGISTRY` (`packages/spec/src/kernel/metadata-plugin.zod.ts`); never maintain a parallel whitelist. The overlay validator (`resolveOverlaySchema()` in `packages/objectql/src/protocol.ts`) and Studio editing forms both bind to the canonical Zod schema.
Copy file name to clipboardExpand all lines: CLAUDE.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,6 +64,7 @@ Mission: Build the "Post-SaaS Operating System" — an open-core, local-first ec
64
64
- Philosophy: "Data as Code", Idempotency, and Immutable Infrastructure are the defaults.
65
65
6.**Long-Term Architecture:** Do NOT use simplified or temporary workarounds. Always adopt sustainable, well-architected solutions.
66
66
7.**Object Name = Table Name:** The object `name` is the canonical identifier used everywhere — API paths, ObjectQL queries, REST URLs, SDK calls, and the physical database table. There is no namespace prefix mechanism; if a module needs a prefix, it is embedded directly in the `name` (e.g. `name: 'sys_user'`, `name: 'ai_conversations'`). **Never** set `namespace` on an object schema — the field is deprecated and ignored. **Never** set `tableName` — the physical table name always equals the object `name`.
67
+
8.**One Zod Source per Metadata Type:** Each metadata type (`view`, `dashboard`, `flow`, `agent`, `tool`, `object`, …) has exactly **one** Zod schema in `packages/spec/src/{domain}/`. Do **not** re-declare the same shape as a `*.object.ts` projection table — that pattern is removed (see ADR-0005). Runtime org overlay opt-in lives in **one** place: the `allowOrgOverride` flag on the type's entry in `DEFAULT_METADATA_TYPE_REGISTRY` (`packages/spec/src/kernel/metadata-plugin.zod.ts`); never maintain a parallel whitelist. The overlay validator (`resolveOverlaySchema()` in `packages/objectql/src/protocol.ts`) and Studio editing forms both bind to the canonical Zod schema.
|**Local file** (default) | Dev, single-host servers |`fs.readFile(dist/objectstack.json)` at boot | Process restart / SIGHUP |
395
+
|**HTTP fetch**| Multi-tenant cloud, control-plane–driven rollouts | Boot-time GET against control plane (`GET /api/v1/control/artifact/:project/:version`); ETag cached on disk | Webhook from control plane → SIGHUP / hot-reload |
396
+
|**OCI image layer**| Containerised deploys, GitOps pipelines | Image tag pin → image pull → file mounts at known path → boot reads file | Pod rollout (Kubernetes / Nomad) |
397
+
398
+
All three converge on the same in-memory shape: the parsed artifact is
399
+
loaded into `SchemaRegistry`. The differences are purely about **when** a
400
+
new shape becomes visible and **how** the runtime is told to re-load.
401
+
402
+
### Refresh model (current vs. future)
403
+
404
+
-**Today (Phase 1–6):** Boot-time only. Re-reading the artifact requires
405
+
process restart. Overlay rows in `sys_metadata` are independent and
406
+
outlive restarts; they are merged on every read.
407
+
-**Future (post-ADR-0005):** A `metadataRegistry.reload()` API that:
408
+
1. Re-reads the artifact (file / HTTP / OCI).
409
+
2. Diffs the new artifact against the in-memory baseline.
410
+
3. Drops the metadata cache (and the `DatabaseLoader` LRU) for any
411
+
`(type, name)` whose baseline changed.
412
+
4. Re-validates each affected overlay row against the **new** baseline
413
+
schema (see "Customization validation" below).
414
+
415
+
### Customization validation against artifact upgrades
416
+
417
+
When the artifact upgrades (a new package version of the underlying view /
418
+
dashboard ships), an existing org overlay may reference fields the new
419
+
schema no longer accepts (renamed columns, removed sub-configs, tightened
420
+
enums). The runtime cannot silently merge a stale overlay — it must
421
+
quarantine it and surface a remediation hook.
422
+
423
+
**Strategy:**
424
+
425
+
1. After artifact load, walk all overlay rows for affected `(type, name)`.
426
+
2. Run them through the canonical Zod schema (the same
427
+
`resolveOverlaySchema()` used at write time).
428
+
3. On failure:
429
+
- Set `state = 'conflict'` (existing column on `sys_metadata`).
430
+
- Append a `sys_metadata_history` entry with `actor='system:upgrade'`,
431
+
reason `artifact_schema_drift`, and the Zod issues array.
432
+
- Exclude the row from the read-time merge → effective metadata falls
433
+
back to the artifact baseline (graceful degradation, no broken UI).
434
+
4. Studio surfaces a per-org "Conflicts" inbox listing the quarantined
435
+
rows so an admin can re-edit and re-save (which clears `conflict`).
436
+
437
+
This bounded validation step is cheap (overlays are typically tens of
438
+
rows per org per project) and runs only on artifact upgrade events, not
0 commit comments