From a1865320ed8dde53594c13605e35657ae23a140b Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:02:53 +0000 Subject: [PATCH 1/4] docs(adr): rewrite 27 moved/mis-spelled path citations to their current paths Citation hygiene only -- no decision text is touched. Each rewritten path was verified against full git history (the shared clone was shallow; deepened first, because a shallow clone reports every pre-cutoff deletion as "never existed"). Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --- docs/adr/0005-metadata-customization-overlay.md | 16 ++++++++-------- .../0008-metadata-repository-and-change-log.md | 2 +- docs/adr/0014-record-form-field-type.md | 2 +- .../0016-studio-package-authoring-and-publish.md | 2 +- docs/adr/0017-object-has-many-view.md | 2 +- ...nership-and-platform-objects-decomposition.md | 6 +++--- ...ditive-materialization-and-visibility-gate.md | 2 +- .../adr/0058-expression-and-predicate-surface.md | 2 +- docs/adr/0062-external-datasource-runtime.md | 2 +- ...mmit-history-and-rollback-for-ai-authoring.md | 2 +- ...ring-surface-boundary-hook-flow-validation.md | 2 +- .../0082-react-component-contract-governance.md | 6 +++--- .../0087-metadata-protocol-upgrade-contract.md | 2 +- .../0104-field-runtime-value-shape-contract.md | 2 +- ...vocabulary-and-null-safe-tenant-uniqueness.md | 2 +- 15 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/adr/0005-metadata-customization-overlay.md b/docs/adr/0005-metadata-customization-overlay.md index 32f1c13cd6..2573465983 100644 --- a/docs/adr/0005-metadata-customization-overlay.md +++ b/docs/adr/0005-metadata-customization-overlay.md @@ -25,7 +25,7 @@ Project concept entirely. As a consequence: `branch`. The column physically named `project_id` on `sys_metadata` is treated as a legacy alias and will be renamed/dropped in the ADR-0008 PR-10 migration. -- All references to `this.projectId` in `packages/objectql/src/protocol.ts` +- All references to `this.projectId` in `packages/metadata-protocol/src/protocol.ts` are deprecated. New code must consult `organization_id` (and, in M1, the branch ref) only. - The `(type, name, project_id)` UNIQUE index is superseded by @@ -143,7 +143,7 @@ Three different things were tangled into one place: ### Storage shape -`sys_metadata` schema (`packages/platform-objects/src/metadata/sys-metadata.object.ts`) is the storage substrate. No schema changes needed in Phase 1: +`sys_metadata` schema (`packages/metadata-core/src/objects/sys-metadata.object.ts`) is the storage substrate. No schema changes needed in Phase 1: | column | role | |---|---| @@ -231,7 +231,7 @@ Five files in `packages/platform-objects/src/metadata/` duplicate a Zod schema t ## References -- `packages/objectql/src/protocol.ts` — `getMetaItem`, `saveMetaItem`, `deleteMetaItem`, `loadMetaFromDb` (this ADR's primary site) +- `packages/metadata-protocol/src/protocol.ts` — `getMetaItem`, `saveMetaItem`, `deleteMetaItem`, `loadMetaFromDb` (this ADR's primary site) - `packages/rest/src/rest-server.ts` — `PUT/GET/DELETE /api/v1/meta/:type/:name` routes - `packages/spec/src/api/protocol.zod.ts` — `ObjectStackProtocol` interface (`deleteMetaItem` added) - `packages/spec/src/kernel/metadata-plugin.zod.ts` — `MetadataTypeRegistryEntrySchema.supportsOverlay` (future hook for the whitelist) @@ -247,7 +247,7 @@ Two implementation issues were discovered during browser E2E verification with t ### 1. List endpoint did not include overlay rows in project kernels -`getMetaItems(type)` in `packages/objectql/src/protocol.ts` was gated by +`getMetaItems(type)` in `packages/metadata-protocol/src/protocol.ts` was gated by `if (this.projectId === undefined)` before consulting `sys_metadata`. Project kernels — which are precisely where overlays live — therefore returned only artifact entries. `GET /api/v1/meta/view` listed 16 artifact items and zero @@ -315,7 +315,7 @@ change, any JSON shape was accepted and stored verbatim, surfacing as runtime errors only at read time when the merged effective metadata was fed into the UI engine. -Implementation (`packages/objectql/src/protocol.ts`): +Implementation (`packages/metadata-protocol/src/protocol.ts`): - `resolveOverlaySchema(type, item)` dispatches by metadata type: - `view` → `ListViewSchema` or `FormViewSchema` (picked by the `type` @@ -359,7 +359,7 @@ types fall through, plural type strings normalize correctly. ### Registry-driven opt-in (was: hard-coded whitelist) -`packages/objectql/src/protocol.ts` previously gated `PUT/DELETE +`packages/metadata-protocol/src/protocol.ts` previously gated `PUT/DELETE /api/v1/meta/:type/:name` against a **hard-coded** `Set` of allowed types (`OVERLAY_ALLOWED_TYPES = new Set(['view', 'dashboard'])`). Any new metadata type that wanted to participate in the overlay system had to find and edit @@ -453,7 +453,7 @@ idempotent migration is provided and run automatically by > place: the `allowOrgOverride` boolean on its > `DEFAULT_METADATA_TYPE_REGISTRY` entry. > 3. The **overlay validator** lives in exactly one place: -> `resolveOverlaySchema()` in `packages/objectql/src/protocol.ts`. +> `resolveOverlaySchema()` in `packages/metadata-protocol/src/protocol.ts`. > > Do **not** re-declare the same shape as a `*.object.ts` (the > projection-table pattern is removed; see Addendum 2026-05-16 (b)). @@ -745,7 +745,7 @@ form from being re-imposed over it. ### Anchors -Both files above are registered in `scripts/adr-anchors.json` against ADR-0005, so +Both files above are registered in `scripts/adr-anchors/` against ADR-0005, so the next author to edit either one is told which decision they are standing on. That is the recurrence guard Prime Directive #13 names and the one thing this amendment adds beyond prose: the producer that was deleted had no anchor, and diff --git a/docs/adr/0008-metadata-repository-and-change-log.md b/docs/adr/0008-metadata-repository-and-change-log.md index c5f4584abf..879c5e5a24 100644 --- a/docs/adr/0008-metadata-repository-and-change-log.md +++ b/docs/adr/0008-metadata-repository-and-change-log.md @@ -482,7 +482,7 @@ The plan is intentionally staged so each milestone is **independently shippable* - [ ] All existing tests pass; new contract suite passes for both `InMemoryRepository` and `FileSystemRepository` - [ ] Cold start of the [HotCRM reference app](https://github.com/objectstack-ai/hotcrm) is ≤ current baseline (no eager full-load) - [ ] `MetadataEvent` stream visible in `apps/studio/Logs` panel -- [ ] No code in `packages/objectql/src/protocol.ts` reads files or imports from `@objectstack/metadata-fs` +- [ ] No code in `packages/metadata-protocol/src/protocol.ts` reads files or imports from `@objectstack/metadata-fs` **Out of scope for M0** diff --git a/docs/adr/0014-record-form-field-type.md b/docs/adr/0014-record-form-field-type.md index 150870f50c..48a05bd537 100644 --- a/docs/adr/0014-record-form-field-type.md +++ b/docs/adr/0014-record-form-field-type.md @@ -16,7 +16,7 @@ internal `name` mirrors the key. The Studio metadata editor, however, treated `fields` as an **array** all the way down: -1. Hand-crafted JSON Schema in `packages/objectql/src/protocol.ts` +1. Hand-crafted JSON Schema in `packages/metadata-protocol/src/protocol.ts` declared `{ type: 'array', items: { … } }`. 2. The form spec in `packages/spec/src/data/object.form.ts` declared `{ type: 'repeater', widget: 'grid' }`. diff --git a/docs/adr/0016-studio-package-authoring-and-publish.md b/docs/adr/0016-studio-package-authoring-and-publish.md index c28e0530c2..031db2caf3 100644 --- a/docs/adr/0016-studio-package-authoring-and-publish.md +++ b/docs/adr/0016-studio-package-authoring-and-publish.md @@ -455,7 +455,7 @@ enabled), so disable state would otherwise be lost. Persistence is local-first: - `packages/runtime/src/http-dispatcher.ts` — `assemblePackageManifest` + `GET /packages/:id/export` (§9.2) - `packages/runtime/src/cloud/marketplace-install-local-plugin.ts` — inline-manifest import + register-before-persist (§9.2–9.3) - `packages/objectql/src/registry.ts` — `isPackageDisabled` + `listItems` disabled-package filter (§9.5); `setInitialDisabledPackageIds` + `installPackage` disable seeding (§9.7) -- `packages/objectql/src/protocol.ts` — `getMetaItems` final-merge disabled-package filter (§9.5) +- `packages/metadata-protocol/src/protocol.ts` — `getMetaItems` final-merge disabled-package filter (§9.5) - `packages/objectql/src/engine.ts` — `registerApp` consumes `tools` / `skills` (§9.6) - `packages/spec/src/shared/metadata-collection.zod.ts` — `PLURAL_TO_SINGULAR` gains `tools` / `skills` (§9.6) - `packages/spec/src/stack.zod.ts` — top-level `tools` on `ObjectStackDefinition` (§9.6) diff --git a/docs/adr/0017-object-has-many-view.md b/docs/adr/0017-object-has-many-view.md index 88e96df83a..d2a2be6d5c 100644 --- a/docs/adr/0017-object-has-many-view.md +++ b/docs/adr/0017-object-has-many-view.md @@ -116,7 +116,7 @@ lists `view`, keeps `v.viewKind && v.object === object`, sorts by rows on top. ### 3.4 Runtime storage — `sys_view_definition` -`packages/platform-objects/src/metadata/sys-view-definition.object.ts` — +`packages/metadata-core/src/objects/sys-view-definition.object.ts` — a `sys_`-prefixed **system object** (auto-provisioned). Columns: `name`, `object`, `view_kind`, `label`, `is_default`, `view_order`, `scope` (`shared`|`personal`), `owner`, `hidden`, `config` (JSON), diff --git a/docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md b/docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md index 5516d832b6..9a503be95f 100644 --- a/docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md +++ b/docs/adr/0029-kernel-object-ownership-and-platform-objects-decomposition.md @@ -189,7 +189,7 @@ contributions follow ADR-0028's naming model (`sys.audit_log`, etc.). A kernel object is more than its schema: it has **localized labels, field help, and list-view names**. Today these live in `platform-objects` as generated bundles (`src/apps/translations/*.objects.generated.ts`, produced by -`os i18n extract` against `scripts/i18n-extract.config.ts`, loaded at runtime by +`os i18n extract` against `packages/platform-objects/scripts/i18n-extract.config.ts`, loaded at runtime by the `platform-objects` plugin). The generated entries are keyed by **object name** (`sys_webhook: {...}`) and loaded globally, so they keep working at runtime regardless of which package owns the object — but their **source of @@ -202,7 +202,7 @@ Therefore object migration must carry the i18n resources, not just the schema: bundle(s), and contributes them at runtime (e.g. via `i18n.loadTranslations` or `manifest.translations`), exactly as `platform-objects` does today. - When an object leaves `platform-objects`, it is removed from - `scripts/i18n-extract.config.ts`; **regenerating before the plugin owns its + `packages/platform-objects/scripts/i18n-extract.config.ts`; **regenerating before the plugin owns its extraction would silently drop locales** — so the plugin-side i18n extraction must land in the same step (or the object stays in the extract set transitionally, explicitly tracked). @@ -783,7 +783,7 @@ does to it: ### 8. Anchors `packages/objectql/src/registry.ts` is registered against ADR-0029 in -`scripts/adr-anchors.json` by this change. It was **unanchored**, which is the +`scripts/adr-anchors/` by this change. It was **unanchored**, which is the recurrence shape Prime Directive #13 names and the same one #6825's amendment found for ADR-0005: the file that implements D3 (the `own` splice at `packages/objectql/src/registry.ts`, `assertSingleOwnerPerObject` at `#assertSingleOwnerPerObject`, the extender guard at) never said diff --git a/docs/adr/0045-additive-materialization-and-visibility-gate.md b/docs/adr/0045-additive-materialization-and-visibility-gate.md index a6f58dacff..956221d6cb 100644 --- a/docs/adr/0045-additive-materialization-and-visibility-gate.md +++ b/docs/adr/0045-additive-materialization-and-visibility-gate.md @@ -206,4 +206,4 @@ Stored `sys_metadata` app rows carrying `hidden: true` were written under the ol ### Anchors -The two load-bearing implementation sites are pinned in `scripts/adr-anchors.json` — `packages/rest/src/rest-server.ts` (the gate) and `packages/runtime/src/domains/packages.ts` (the flip). Neither carried an anchor before, which is the recurrence shape Prime Directive #13 names: the files that implemented this ADR's §3 never said which decision they were standing on, so the next author could not have known that changing them was changing a decision. +The two load-bearing implementation sites are pinned in `scripts/adr-anchors/` — `packages/rest/src/rest-server.ts` (the gate) and `packages/runtime/src/domains/packages.ts` (the flip). Neither carried an anchor before, which is the recurrence shape Prime Directive #13 names: the files that implemented this ADR's §3 never said which decision they were standing on, so the next author could not have known that changing them was changing a decision. diff --git a/docs/adr/0058-expression-and-predicate-surface.md b/docs/adr/0058-expression-and-predicate-surface.md index 60c54e1013..7b614b6973 100644 --- a/docs/adr/0058-expression-and-predicate-surface.md +++ b/docs/adr/0058-expression-and-predicate-surface.md @@ -290,7 +290,7 @@ > appendix will not presume the answer. The engine half and #5846 settle it > together, in one edit to one ordering, and record it as an amendment. > **→ Settled in Amendment II.1 below.** -> - **`scripts/adr-anchors.json`'s `hook-wrappers.ts` invariant still describes +> - **`scripts/adr-anchors/`'s `hook-wrappers.ts` invariant still describes > the batch dispatch.** It is TRUE today and must move with the engine half, > not before it. **→ Moved with #5574's engine half.** diff --git a/docs/adr/0062-external-datasource-runtime.md b/docs/adr/0062-external-datasource-runtime.md index 1a55705fe9..99533a32c7 100644 --- a/docs/adr/0062-external-datasource-runtime.md +++ b/docs/adr/0062-external-datasource-runtime.md @@ -35,7 +35,7 @@ This ADR defines the **complete external-datasource runtime contract** and the d ### The structural gap, precisely (R2) -`os dev` (standalone) connects exactly **one** driver — the `default` library (`.objectstack/data/standalone.db`), built in `packages/runtime/src/standalone-stack.ts` by detecting the driver kind from the DB URL. A `defineStack({ datasources: [...] })` entry is only registered as metadata by `packages/runtime/src/app-plugin.ts` (`registerInMemory('datasource', …)`). ObjectQL routes queries by **driver name** (`engine.getDriver(object) → this.drivers.get(object.datasource)`) and throws `Datasource 'x' is not registered` when absent. So the only way to make a federated object queryable today is the app's `onEnable` hook calling `ctx.drivers.register(driver)` (= `engine.registerDriver`) — see `examples/app-showcase/src/datasources/external-fixture.ts`. That bridge is framework plumbing leaking into every federation app. +`os dev` (standalone) connects exactly **one** driver — the `default` library (`.objectstack/data/standalone.db`), built in `packages/runtime/src/standalone-stack.ts` by detecting the driver kind from the DB URL. A `defineStack({ datasources: [...] })` entry is only registered as metadata by `packages/runtime/src/app-plugin.ts` (`registerInMemory('datasource', …)`). ObjectQL routes queries by **driver name** (`engine.getDriver(object) → this.drivers.get(object.datasource)`) and throws `Datasource 'x' is not registered` when absent. So the only way to make a federated object queryable today is the app's `onEnable` hook calling `ctx.drivers.register(driver)` (= `engine.registerDriver`) — see `examples/app-showcase/src/system/datasources/external-fixture.ts`. That bridge is framework plumbing leaking into every federation app. ### Why one consolidating ADR (not N small PRs) diff --git a/docs/adr/0067-commit-history-and-rollback-for-ai-authoring.md b/docs/adr/0067-commit-history-and-rollback-for-ai-authoring.md index 5afae61270..628ac4b6a9 100644 --- a/docs/adr/0067-commit-history-and-rollback-for-ai-authoring.md +++ b/docs/adr/0067-commit-history-and-rollback-for-ai-authoring.md @@ -31,7 +31,7 @@ A commit-history model usually means "build a versioning system." Here, most of | Capability | Where | Note | |---|---|---| | Per-item version history, **full body per version** | `sys_metadata_history` (`packages/metadata-core/src/objects/sys-metadata-history.object.ts`) | append-only; `operation_type ∈ {create,update,publish,revert,delete}`; `event_seq` (per-org monotonic, orders *all* changes); `version` (per-item monotonic); `recorded_by` (incl. `ai:claude`) | -| Read a prior version / **single-item revert** | `SysMetadataRepository.history()` / `restoreVersion(ref, targetVersion)` (`packages/objectql/src/sys-metadata-repository.ts`) | revert already lands as a forward `operation_type='revert'` event | +| Read a prior version / **single-item revert** | `SysMetadataRepository.history()` / `restoreVersion(ref, targetVersion)` (`packages/metadata-protocol/src/sys-metadata-repository.ts`) | revert already lands as a forward `operation_type='revert'` event | | Per-write ACID (metadata row + history row atomic) | `withTxn()` / `engine.transaction()` (same file + `engine.ts`) | exists **per item**; not across items | | Full-bundle package snapshot + atomic rollback-by-install | `sys_package_version` + `snapshotBundleAsManifest()` + install pointer swap (cloud `service-tenant` / `service-cloud`) | downgrade already detected ("Rolled back v2→v1") | | Soft vs hard delete | `keepData` / `dropStorage` flags (`engine.ts` teardown) | **default keeps data**; hard drop is opt-in — soft-drop is already the default posture | diff --git a/docs/adr/0077-authoring-surface-boundary-hook-flow-validation.md b/docs/adr/0077-authoring-surface-boundary-hook-flow-validation.md index 87bb41fdd7..3b334593d8 100644 --- a/docs/adr/0077-authoring-surface-boundary-hook-flow-validation.md +++ b/docs/adr/0077-authoring-surface-boundary-hook-flow-validation.md @@ -89,7 +89,7 @@ The genuine overlap is `after-*` side effects (write succeeded → notify / audi ### 4. Loud-not-silent — the two new `os build` lints (the only code in v1) -Authored alongside the existing flow lints in `packages/cli/src/utils/lint-flow-patterns.ts` (which already ships `flow-runas-unscoped`, `flow-double-brace-interpolation`, etc.): +Authored alongside the existing flow lints in `packages/lint/src/lint-flow-patterns.ts` (which already ships `flow-runas-unscoped`, `flow-double-brace-interpolation`, etc.): - **`flow-record-before-cannot-mutate`** — *error*. A flow bound to `record-before-*` that contains a `create_record`/`update_record` node targeting the **triggering object/record**, or otherwise reads as expecting to change the in-flight record. Message points to **hook** (rewrite) or **validation rule** (veto). - **`flow-record-before-cannot-veto`** — *error*. A `record-before-*` flow whose shape implies it intends to stop the write (e.g. a decision branch ending in an error/`end` node presented as rejection). Message: *"record-change flows cannot abort the triggering write — its errors are isolated by design; use a validation rule to reject, or a hook to throw."* diff --git a/docs/adr/0082-react-component-contract-governance.md b/docs/adr/0082-react-component-contract-governance.md index 8eb3871518..7b100532c3 100644 --- a/docs/adr/0082-react-component-contract-governance.md +++ b/docs/adr/0082-react-component-contract-governance.md @@ -3,7 +3,7 @@ **Status**: Accepted (2026-06-30) **Deciders**: ObjectStack Protocol Architects **Builds on**: [ADR-0080](./0080-ai-authored-ui-jsx-source.md) (AI authors UI; the component registry `inputs` are the contract; **capability ≠ contract** — curate a small public surface, not the full capability set), [ADR-0081](./0081-trusted-react-page-tier.md) (the `kind:'react'` tier executes real React; its safety boundary is **trust + review**, and its prop ceiling is the **injected scope**), [ADR-0033](./0033-ai-assisted-metadata-authoring.md) (AI writes metadata via draft-gated review), [ADR-0054](./0054-runtime-proof-for-authorable-surface.md) (ratchet a snapshot; flag regressions, not the accepted baseline), [ADR-0078](./0078-no-silently-inert-metadata.md) (no silently-inert metadata — a prop the author writes must be honored or rejected, never silently dropped). -**Consumers**: `@objectstack/spec` (`packages/spec/src/ui/react-blocks.ts` — the block→schema index + React overlay; `scripts/build-react-blocks-contract.ts` — the generator; `scripts/check-react-blocks-declaration-parity.ts` + `react-declaration-parity.baseline.json` — the ratchet), `@objectstack/lint` (`validate-react-page-props.ts` — the authoring prop gate), `@objectstack/cli` (`os validate` wires the gate), `scripts/gen-sdui-manifest.sh` (`pnpm sdui:manifest` — dumps the manifest and runs the ratchet; **this is the producer**, corrected here in #5960: the ratchet moved out of `scripts/build-console.sh` in #4472 and this row still named the old file), `../objectui` (the component registry `inputs` are the projected surface the ratchet checks against). +**Consumers**: `@objectstack/spec` (`packages/spec/src/ui/react-blocks.ts` — the block→schema index + React overlay; `packages/spec/scripts/build-react-blocks-contract.ts` — the generator; `packages/spec/scripts/check-react-blocks-declaration-parity.ts` + `react-declaration-parity.baseline.json` — the ratchet), `@objectstack/lint` (`validate-react-page-props.ts` — the authoring prop gate), `@objectstack/cli` (`os validate` wires the gate), `scripts/gen-sdui-manifest.sh` (`pnpm sdui:manifest` — dumps the manifest and runs the ratchet; **this is the producer**, corrected here in #5960: the ratchet moved out of `scripts/build-console.sh` in #4472 and this row still named the old file), `../objectui` (the component registry `inputs` are the projected surface the ratchet checks against). **Premise**: ADR-0081 gave authors (and AI) a `kind:'react'` page tier whose blocks are the curated public data components (``, ``, charts, record:* panels). For AI to author those blocks *correctly* it must know each block's props — and for that knowledge to be trustworthy, the props must come from an authoritative, machine-readable, **non-drifting** source. The problem: **there is no single such source.** Three prop surfaces exist for the same components, and nothing keeps them in lockstep: @@ -36,7 +36,7 @@ They drift silently: a component can accept a prop the spec never declared (an u `packages/spec/src/ui/react-blocks.ts` is a **block→schema index**: each curated public block (`` → `FormViewSchema`, `` → `ListViewSchema`, `` → `RecordDetailsProps`, `` → `ChartConfigSchema`, …) names its spec schema, plus a per-block `dataProps` allowlist that curates *which* schema props to surface (ADR-0080: capability ≠ contract — `ListView` has 45 schema props; the contract surfaces ~10 high-signal ones). -`scripts/build-react-blocks-contract.ts` generates the AI-facing contract (`skills/objectstack-ui/contracts/react-blocks.contract.json` + `references/react-blocks.md`) by reading the spec schemas (`z.toJSONSchema`, with `OS_EAGER_SCHEMAS=1` to resolve lazy schemas), taking each prop's spec-authored `.describe()`, and merging the React overlay. **Hand-authoring is rejected** — a hand-written contract drifts into fiction; a generated one is zero-drift by construction. +`packages/spec/scripts/build-react-blocks-contract.ts` generates the AI-facing contract (`skills/objectstack-ui/contracts/react-blocks.contract.json` + `references/react-blocks.md`) by reading the spec schemas (`z.toJSONSchema`, with `OS_EAGER_SCHEMAS=1` to resolve lazy schemas), taking each prop's spec-authored `.describe()`, and merging the React overlay. **Hand-authoring is rejected** — a hand-written contract drifts into fiction; a generated one is zero-drift by construction. ### 2. Registry `inputs` are a projection, not the protocol @@ -61,7 +61,7 @@ These are declared in the `react-blocks.ts` overlay with a `kind` of `binding`/` > > **Corrected by #5960 — see addendum 2.** This section shipped saying the ratchet runs *inside `build-console.sh`*. That was true when it was written and stopped being true at #4472, which moved it into `scripts/gen-sdui-manifest.sh`; the file names below are corrected in place, because a reader who followed this ADR opened the wrong file. #5960 also answers the question this decision left open — "not every PR" never said *when*, and the answer is **at the objectui pin bump**. -`scripts/check-react-blocks-declaration-parity.ts` compares the spec props (per block, via `z.toJSONSchema`) against the registry-inputs manifest (`sdui.manifest.json`). The manifest **only exists once a real browser has enumerated the built console registry** — the registry is a browser app pulling browser-only deps, so a framework PR has no manifest to check against. Running it on every PR is therefore not worth it. +`packages/spec/scripts/check-react-blocks-declaration-parity.ts` compares the spec props (per block, via `z.toJSONSchema`) against the registry-inputs manifest (`sdui.manifest.json`). The manifest **only exists once a real browser has enumerated the built console registry** — the registry is a browser app pulling browser-only deps, so a framework PR has no manifest to check against. Running it on every PR is therefore not worth it. Instead, it runs **inside `scripts/gen-sdui-manifest.sh`** (`pnpm sdui:manifest`), immediately after that script dumps the manifest (near-zero marginal cost *there*, because the browser is already open), as a **baseline ratchet** modeled on ADR-0054: diff --git a/docs/adr/0087-metadata-protocol-upgrade-contract.md b/docs/adr/0087-metadata-protocol-upgrade-contract.md index bacf5365bd..eeeac7dc81 100644 --- a/docs/adr/0087-metadata-protocol-upgrade-contract.md +++ b/docs/adr/0087-metadata-protocol-upgrade-contract.md @@ -57,7 +57,7 @@ concrete gaps, then the assumption that reshapes the solution: loader, installer, or CLI command reads it. Under ADR-0078, an authorable field the runtime ignores is a bug class of its own: enforce it or remove it. -2. **Change information is human-readable only.** `packages/spec/api-surface.json` +2. **Change information is human-readable only.** `packages/spec/api-surface/` records the full export surface and its diff gates every PR — then the diff is thrown away. Releases ship a prose CHANGELOG and (for 11) a hand-written upgrade guide. Nothing machine-consumable maps version N → N+1. diff --git a/docs/adr/0104-field-runtime-value-shape-contract.md b/docs/adr/0104-field-runtime-value-shape-contract.md index 38309b0d3c..408d1c5872 100644 --- a/docs/adr/0104-field-runtime-value-shape-contract.md +++ b/docs/adr/0104-field-runtime-value-shape-contract.md @@ -161,7 +161,7 @@ type lists): - `driver-sql` derives `JSON_COLUMN_TYPES` / `NUMERIC_SCALAR_TYPES` membership from the spec classes (DDL column choice remains the driver's decision; the *classification* moves to the spec). -- `packages/verify/read-coercion.ts` grows from a 3-type probe to asserting +- `packages/verify/src/read-coercion.ts` grows from a 3-type probe to asserting the full matrix: for every field type, a stored-form write round-trips to a stored-form read on every driver. diff --git a/docs/adr/0120-unique-scope-vocabulary-and-null-safe-tenant-uniqueness.md b/docs/adr/0120-unique-scope-vocabulary-and-null-safe-tenant-uniqueness.md index bfa93dc865..24191df938 100644 --- a/docs/adr/0120-unique-scope-vocabulary-and-null-safe-tenant-uniqueness.md +++ b/docs/adr/0120-unique-scope-vocabulary-and-null-safe-tenant-uniqueness.md @@ -443,7 +443,7 @@ split this ADR exists to close (PD #10): enforcement — the #5030 probe graduates into this suite), and for D2 (nine-key inventory unchanged). The *"`'global'` is a synonym of `true`"* pin retires at 18 together with bare `true`. -7. ADR anchors: `scripts/adr-anchors.json` entries for `normalizeDeclaredIndex`, +7. ADR anchors: `scripts/adr-anchors/` entries for `normalizeDeclaredIndex`, `uniqueIndexesFromFields`, the conversion entry, and R10/R-new (PD #13 corollary — leave the id in the code). From c78a3a1e3d8dc9edb365e17a4c60bcb655835001 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:10:38 +0000 Subject: [PATCH 2/4] docs(adr): date the remaining stale path citations, and name the sibling repo Annotates every full-path citation in docs/adr/** that does not resolve and was not already annotated: deleted / renamed / never-shipped paths keep their historical spelling and gain a dated Path note carrying the evidence commit; paths that live in the sibling objectui repo take the corpus's cross-repo `objectui:` anchor form. No decision text is changed. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --- docs/adr/0002-environment-database-isolation.md | 4 ++++ docs/adr/0003-package-as-first-class-citizen.md | 1 + docs/adr/0004-cloud-multi-kernel.md | 4 ++++ docs/adr/0005-metadata-customization-overlay.md | 8 +++++--- docs/adr/0006-project-environment-split.md | 2 ++ docs/adr/0006-project-environment-split.v2.md | 2 ++ docs/adr/0006-project-environment-split.v4.md | 6 ++++-- docs/adr/0007-settings-manifest-and-kv-store.md | 1 + docs/adr/0010-nl-to-flow-authoring.md | 4 ++++ docs/adr/0011-actions-as-ai-tools.md | 2 ++ docs/adr/0013-bidirectional-messaging.md | 5 +++++ docs/adr/0015-external-datasource-federation.md | 10 ++++++++++ docs/adr/0016-studio-package-authoring-and-publish.md | 1 + docs/adr/0017-object-has-many-view.md | 4 ++-- docs/adr/0025-plugin-package-distribution.md | 4 ++++ ...uthorization-core-business-units-and-scope-depth.md | 6 ++++++ docs/adr/0071-dataset-semantic-layer-depth.md | 4 ++-- docs/adr/0080-ai-authored-ui-jsx-source.md | 2 +- .../0107-withdrawn-hook-body-write-set-static-gap.md | 3 ++- docs/adr/0126-packaged-metadata-customization-model.md | 4 +++- 20 files changed, 65 insertions(+), 12 deletions(-) diff --git a/docs/adr/0002-environment-database-isolation.md b/docs/adr/0002-environment-database-isolation.md index 237278c747..83e246f78d 100644 --- a/docs/adr/0002-environment-database-isolation.md +++ b/docs/adr/0002-environment-database-isolation.md @@ -123,6 +123,10 @@ The migration is **non-destructive** and **idempotent**: each legacy org's datab ## References +> **Path note (2026-09):** the three `packages/services/service-tenant/…` paths below are historical +> and deliberately unlinked — the `packages/services/service-tenant/` package left this repository with the control-plane split to `objectstack-ai/cloud` (`473fce590`, 2026-05-21). +> They are kept as written because they record where this decision landed at the time. + - `packages/spec/src/cloud/environment.zod.ts` — protocol schemas - `packages/services/service-tenant/src/objects/sys-environment.object.ts` — merged control-plane environment object (includes DB addressing) - `packages/services/service-tenant/src/environment-provisioning.ts` — provisioning service diff --git a/docs/adr/0003-package-as-first-class-citizen.md b/docs/adr/0003-package-as-first-class-citizen.md index 1b0c568dc1..18c2a9b9ab 100644 --- a/docs/adr/0003-package-as-first-class-citizen.md +++ b/docs/adr/0003-package-as-first-class-citizen.md @@ -191,6 +191,7 @@ The migration is non-destructive and idempotent. Steps 1–4 ship in v4.x as an - `packages/spec/src/cloud/environment-package.zod.ts` — current installation schema (to be updated) - `packages/services/service-tenant/src/objects/sys-package-installation.object.ts` — DB object (to be updated) + *(Path note, 2026-09: historical and deliberately unlinked — the `packages/services/service-tenant/` package left this repository with the control-plane split to `objectstack-ai/cloud` (`473fce590`, 2026-05-21).)* - ADR-0002: `docs/adr/0002-environment-database-isolation.md` — Control Plane / Data Plane split - Salesforce Unlocked Packages: - Power Platform Solution Layers: diff --git a/docs/adr/0004-cloud-multi-kernel.md b/docs/adr/0004-cloud-multi-kernel.md index 42c3e99ea9..7a334271ac 100644 --- a/docs/adr/0004-cloud-multi-kernel.md +++ b/docs/adr/0004-cloud-multi-kernel.md @@ -134,4 +134,8 @@ Custom domains and multi-hostname binding (ACME certificates, `sys_domain` table - Plan: `apps-server-sleepy-newell` (the plan this ADR crystallizes). - Code: `packages/runtime/src/kernel-manager.ts`, `packages/runtime/src/project-kernel-factory.ts`, `packages/runtime/src/http-dispatcher.ts`, `apps/objectos/server/bootstrap.ts`, `apps/cloud/objectstack.config.ts`. + *(Path note, 2026-09: four of these five are historical and deliberately unlinked — the two runtime + paths for the reason the Path note in §2 gives (`packages/runtime/src/cloud/` was removed by #1600, + `60fc50186`), and `apps/objectos/` and `apps/cloud/` because both split out to `objectstack-ai/cloud` + on 2026-05-21 (`617016428` / `2a1fc869a`). `http-dispatcher.ts` is the only one still in this repository.)* - Related guide: [Cloud vs Self-Hosted deployment](../../content/docs/deployment/index.mdx). diff --git a/docs/adr/0005-metadata-customization-overlay.md b/docs/adr/0005-metadata-customization-overlay.md index 2573465983..74d55877c7 100644 --- a/docs/adr/0005-metadata-customization-overlay.md +++ b/docs/adr/0005-metadata-customization-overlay.md @@ -194,7 +194,9 @@ Five files in `packages/platform-objects/src/metadata/` duplicate a Zod schema t `sys-metadata.object.ts` and `sys-metadata-history.object.ts` are retained — they are the storage substrate, not duplicates of any metadata type. -`MetadataProjector` (`packages/metadata/src/projection/metadata-projector.ts`) becomes dead code under this ADR. It is left in place for one release as a no-op safety net, and removed in the next major along with the deprecated objects. +`MetadataProjector` (`packages/metadata/src/projection/metadata-projector.ts` — *Path note, 2026-09: +the module was deleted in `516f48ca9`, the same change that implemented this ADR; the name survives +only in `packages/metadata/src/migrations/drop-projection-tables.ts`*) becomes dead code under this ADR. It is left in place for one release as a no-op safety net, and removed in the next major along with the deprecated objects. ## Consequences @@ -652,7 +654,7 @@ coverage: ### Admin UX: field-level Code-vs-Effective diff -The Layers tab in the metadata editor (`packages/app-shell/.../LayeredDiff.tsx` +The Layers tab in the metadata editor (`objectui:packages/app-shell/src/views/metadata-admin/LayeredDiff.tsx` in `objectui`) now defaults to a **Diff** view that compares `layered.code` (artifact baseline) against `layered.effective` (merged) field-by-field. Each top-level key renders as a row with a colour-coded @@ -680,7 +682,7 @@ the present), so this section is where the present tense lives. | Addendum (d) says | Today | Superseded by | |:---|:---|:---| -| "`addSysMetadataOverlayIndex(driver)` — exported from `@objectstack/metadata/migrations`" | **Deleted.** The export and its module are gone; `packages/metadata/src/migrations/index.ts` carries a tombstone in their place that records the measurement and forbids re-introducing a producer for `idx_sys_metadata_overlay_active` in that package. | #6771 (PR #6824, merged 2026-08-08); `.changeset/overlay-index-single-producer.md` | +| "`addSysMetadataOverlayIndex(driver)` — exported from `@objectstack/metadata/migrations`" | **Deleted.** The export and its module are gone; `packages/metadata/src/migrations/index.ts` carries a tombstone in their place that records the measurement and forbids re-introducing a producer for `idx_sys_metadata_overlay_active` in that package. | #6771 (PR #6824, merged 2026-08-08); `.changeset/overlay-index-single-producer.md` (since consumed by the release, `24c1b91e4`) | | "a new idempotent migration is provided and run automatically by `DatabaseLoader.ensureSchema()`" | **No overlay-index DDL is issued from that method at all**, on either of its two paths — both call sites went with the export. What `ensureSchema()` still runs is the `project_id` → `environment_id` forward migration, which is a different concern. | #6771 (PR #6824) | | "Drivers ignore `indexes` declarations on synced tables today" | **False** — and this one is *not* a consequence of #6771. `SqlDriver.syncDeclaredIndexes` materializes every declared index, through knex's `table.unique(fields, { indexName })` / `table.index(fields, name)`, skipping by name for idempotence. | The driver itself. The spec records the same fact where the `IDataDriver` capability bit `indexes` was retired for having no reader: "Declared indexes are materialised by the driver itself during schema sync (`SqlDriver.syncDeclaredIndexes`)". | diff --git a/docs/adr/0006-project-environment-split.md b/docs/adr/0006-project-environment-split.md index 2fb00459b1..a695f415d5 100644 --- a/docs/adr/0006-project-environment-split.md +++ b/docs/adr/0006-project-environment-split.md @@ -177,6 +177,8 @@ The toggle is sticky per user; once on, it stays on across sessions. later (different semantics) when Builder UX ships. SDK consumers (none in production yet) must rename calls. 3. **`apps/cloud/server/index.ts` and `worker.ts` change** their hostname + *(Path note, 2026-09: historical and deliberately unlinked — `apps/cloud/` split out to + `objectstack-ai/cloud` on 2026-05-21, `2a1fc869a`.)* resolution from `sys_project` to `sys_environment`. ### Neutral diff --git a/docs/adr/0006-project-environment-split.v2.md b/docs/adr/0006-project-environment-split.v2.md index ca09495d9a..46b20c1a03 100644 --- a/docs/adr/0006-project-environment-split.v2.md +++ b/docs/adr/0006-project-environment-split.v2.md @@ -219,5 +219,7 @@ Each phase is independently shippable behind a feature flag §12.3 — original three-layer-model recommendation - `packages/services/service-tenant/src/objects/sys-project.object.ts` — current single-table model; relabelled in Phase 0 + *(Path note, 2026-09: historical and deliberately unlinked — the object was renamed to + `sys-environment.object.ts` by `0ee839c53`, and then the `packages/services/service-tenant/` package left this repository with the control-plane split to `objectstack-ai/cloud` (`473fce590`, 2026-05-21).)* diff --git a/docs/adr/0006-project-environment-split.v4.md b/docs/adr/0006-project-environment-split.v4.md index c9ccab7e21..4ea2a89bd0 100644 --- a/docs/adr/0006-project-environment-split.v4.md +++ b/docs/adr/0006-project-environment-split.v4.md @@ -189,7 +189,9 @@ installed where" goes through Packages → version history → installations. 1. `sys_package_version.published_from_project_id` (introduced in v3) is removed as a field — provenance lives in `sys_package_version.metadata` if needed. -2. `ProjectArtifactSchema` (`packages/spec/src/cloud/project-artifact.zod.ts`) +2. `ProjectArtifactSchema` (`packages/spec/src/cloud/project-artifact.zod.ts` — *Path note, 2026-09: + the follow-up rename this paragraph anticipates happened; the file is + `packages/spec/src/cloud/environment-artifact.zod.ts` today, renamed by `944f18758`, 2026-05-24*) is the envelope returned by `GET /cloud/projects/:id/artifact`. The route name is kept for BC; the response shape continues to wrap the compiled `ObjectStackDefinitionSchema`. The "Project" in the schema @@ -202,7 +204,7 @@ installed where" goes through Packages → version history → installations. | Phase | Scope | Status | |:---|:---|:---| -| **A — Drop Project from the protocol** | Remove `packages/spec/src/cloud/project.zod.ts`; update `index.ts`; trim Project tests from `environment.test.ts`; mark `sys_environment_revision` as `@deprecated transitional` | ✅ This commit | +| **A — Drop Project from the protocol** | Remove `packages/spec/src/cloud/project.zod.ts` (since removed, as this phase prescribes — `d4eed33ab`); update `index.ts`; trim Project tests from `environment.test.ts`; mark `sys_environment_revision` as `@deprecated transitional` | ✅ This commit | | **B — Rewire CLI publish onto Package** | `objectstack publish` resolves implicit `sys_package`; calls `POST /cloud/packages/:id/versions`; upserts `sys_package_installation`. Old `/cloud/projects/:envId/metadata` becomes a thin BC shim that internally walks the new path. | Next | | **C — Split CLI commands** | `objectstack push` (version only) + `objectstack deploy` (installation upsert) + `objectstack promote` + `objectstack rollback`. `publish` stays as a `push && deploy` alias. | Next+1 | | **D — Remove transitional revision table** | After Phase B is shipping and verified: drop `sys_environment_revision` schema, delete `_DEPRECATED` route handlers, wipe table from any seeded control planes. | After C | diff --git a/docs/adr/0007-settings-manifest-and-kv-store.md b/docs/adr/0007-settings-manifest-and-kv-store.md index b2d9c0d96a..0089ff3842 100644 --- a/docs/adr/0007-settings-manifest-and-kv-store.md +++ b/docs/adr/0007-settings-manifest-and-kv-store.md @@ -446,6 +446,7 @@ Review existing `sys_oauth_application`, `sys_webhook`, `sys_two_factor` — kee - `packages/platform-objects/src/identity/sys-user-preference.object.ts` — original config-resolution comment - `packages/services/service-tenant/src/objects/sys-environment-credential.object.ts` — encrypted-creds reference impl + *(Path note, 2026-09: historical and deliberately unlinked — the `packages/services/service-tenant/` package left this repository with the control-plane split to `objectstack-ai/cloud` (`473fce590`, 2026-05-21).)* - `packages/spec/src/data/field.zod.ts` — existing field type catalogue - `packages/platform-objects/src/apps/setup.app.ts` — Setup app shell - Apple "Implementing an iOS Settings Bundle" — https://developer.apple.com/documentation/foundation/userdefaults/implementing_an_ios_settings_bundle diff --git a/docs/adr/0010-nl-to-flow-authoring.md b/docs/adr/0010-nl-to-flow-authoring.md index 6b6d35ff5f..092c3e8b73 100644 --- a/docs/adr/0010-nl-to-flow-authoring.md +++ b/docs/adr/0010-nl-to-flow-authoring.md @@ -139,6 +139,8 @@ HotCRM has a placeholder `live_data` skill that grounds Copilot answers in the l 1. Add `'flow_author'` to `sales_copilot.skills[]`. 2. Drop the explicit cut we made when removing the in-CRM `flow_designer` draft (commit retained in branch `feat/wow-2-flow-designer-draft`). 3. Update `content/docs/ai-copilot/live-schema.mdx` with a Wow #2 sibling page. + *(Path note, 2026-09: this is a HotCRM path, not a path in this repository — no file has ever + existed at `content/docs/ai-copilot/` here. It is kept as the record of the planned edit.)* No CRM data model changes. @@ -154,3 +156,5 @@ Pending platform review. HotCRM v1 launch (W9) will ship without Wow #2 unless t * ADR-0003 — package-as-first-class-citizen (target for `register_flow`). * ADR-0008 — metadata repository + change log (provides idempotency + audit). * HotCRM `content/docs/ai-copilot/live-schema.mdx` — Wow #1 marketing copy that sets up Wow #2. + *(Path note, 2026-09: a HotCRM path, not a path in this repository — no file has ever existed at + `content/docs/ai-copilot/` here.)* diff --git a/docs/adr/0011-actions-as-ai-tools.md b/docs/adr/0011-actions-as-ai-tools.md index d29631108a..a7c6e781c8 100644 --- a/docs/adr/0011-actions-as-ai-tools.md +++ b/docs/adr/0011-actions-as-ai-tools.md @@ -314,3 +314,5 @@ ships next. * `packages/spec/src/ui/action.zod.ts` — `ActionSchema` + `ActionAiSchema` * `packages/spec/src/contracts/ai-service.ts` — `AIToolDefinition` * `packages/services/service-ai/src/tools/action-tools.ts` — the bridge + *(Path note, 2026-09: historical and deliberately unlinked — `service-ai` was removed whole under + ADR-0025 S2, `21d4f8901`, 2026-06-25; the open edition is MCP-only.)* diff --git a/docs/adr/0013-bidirectional-messaging.md b/docs/adr/0013-bidirectional-messaging.md index 1f43a34ccf..6652087691 100644 --- a/docs/adr/0013-bidirectional-messaging.md +++ b/docs/adr/0013-bidirectional-messaging.md @@ -550,6 +550,11 @@ No new ADR-0011 surface is needed. The Action Registry, agent runtime, and tool- The following are clean enough to copy verbatim; each goes into `packages/messaging-utils/` with a NOTICE entry: +> **Path note (2026-09):** the three `packages/messaging-utils/src/…` paths in the *Our path* column +> are **proposed** destinations, not citations — no `packages/messaging-utils/` package has ever +> existed in this repository's history. They record where this ADR intended the borrowed artifacts +> to land. + | openclaw source | Our path | Why borrowed | |:---|:---|:---| | `plugin-sdk/security-runtime.ts::safeEqualSecret` | `packages/messaging-utils/src/safe-equal.ts` | Constant-time secret compare; well-tested, no objectstack-specific shape needed | diff --git a/docs/adr/0015-external-datasource-federation.md b/docs/adr/0015-external-datasource-federation.md index 9dc622686d..ca6cbe1a95 100644 --- a/docs/adr/0015-external-datasource-federation.md +++ b/docs/adr/0015-external-datasource-federation.md @@ -5,6 +5,16 @@ **Builds on**: [ADR-0005](./0005-metadata-customization-overlay.md) (one Zod source of truth per metadata type) **Consumers**: `@objectstack/spec`, `@objectstack/runtime`, `@objectstack/objectql`, `@objectstack/plugins/driver-sql`, `@objectstack/services/service-ai`, `@objectstack/cli`, `../objectui` +> **Path note (2026-09), paths only — no decision changes.** Five paths this record cites are +> historical and deliberately unlinked: `packages/spec/src/data/external-lookup.zod.ts` (retired +> under ADR-0049 enforce-or-remove, `29488ccae`, 2026-08-12), `packages/spec/src/automation/sync.zod.ts` +> (the L1 "Simple Sync" layer was retired whole, `891d345a7`, 2026-08-03), and +> `packages/services/service-ai/src/tools/query-data.tool.ts` + +> `packages/services/service-ai/src/schema-retriever.ts` (`service-ai` removed under ADR-0025 S2, +> `21d4f8901`, 2026-06-25). `packages/spec/src/shared/error-map.ts` is a **proposed** path — no file +> has ever existed there. Each is kept as written because it records this decision's surface at the +> time it was taken. + --- ## 0. Context diff --git a/docs/adr/0016-studio-package-authoring-and-publish.md b/docs/adr/0016-studio-package-authoring-and-publish.md index 031db2caf3..c8de176450 100644 --- a/docs/adr/0016-studio-package-authoring-and-publish.md +++ b/docs/adr/0016-studio-package-authoring-and-publish.md @@ -454,6 +454,7 @@ enabled), so disable state would otherwise be lost. Persistence is local-first: - `../objectui/.../layout/UnifiedSidebar.tsx` — `active_package` selector (authoring target) - `packages/runtime/src/http-dispatcher.ts` — `assemblePackageManifest` + `GET /packages/:id/export` (§9.2) - `packages/runtime/src/cloud/marketplace-install-local-plugin.ts` — inline-manifest import + register-before-persist (§9.2–9.3) + *(Path note, 2026-09: historical and deliberately unlinked — `packages/runtime/src/cloud/` was removed by ADR-0006 Phase 4 (`15fcd360d`, 2026-06-11), which took the cloud plugins out of the framework runtime.)* - `packages/objectql/src/registry.ts` — `isPackageDisabled` + `listItems` disabled-package filter (§9.5); `setInitialDisabledPackageIds` + `installPackage` disable seeding (§9.7) - `packages/metadata-protocol/src/protocol.ts` — `getMetaItems` final-merge disabled-package filter (§9.5) - `packages/objectql/src/engine.ts` — `registerApp` consumes `tools` / `skills` (§9.6) diff --git a/docs/adr/0017-object-has-many-view.md b/docs/adr/0017-object-has-many-view.md index d2a2be6d5c..517064a231 100644 --- a/docs/adr/0017-object-has-many-view.md +++ b/docs/adr/0017-object-has-many-view.md @@ -137,7 +137,7 @@ bound to that object, sorted, handling both array and `{items:[]}` response shapes. ### 3.6 Runtime switcher — `../objectui` -`packages/data-objectstack/src/index.ts` — the adapter's runtime-view +`objectui:packages/data-objectstack/src/index.ts` — the adapter's runtime-view CRUD (`listViews` / `createView` / `updateView` / `deleteView`) is repointed from the legacy metadata `view` overlay onto `sys_view_definition` via the generic data API: @@ -150,7 +150,7 @@ repointed from the legacy metadata `view` overlay onto the tab-bar consumes and the typed columns (config nested; identity hoisted). -`packages/app-shell/src/views/ObjectView.tsx` — the console switcher +`objectui:packages/app-shell/src/views/ObjectView.tsx` — the console switcher aggregates two sources it already merged: **package** views via `objectDef.listViews` (the dual-read aggregated container, surfaced by `MetadataProvider`) and **shared/personal** via `dataSource.listViews`. diff --git a/docs/adr/0025-plugin-package-distribution.md b/docs/adr/0025-plugin-package-distribution.md index 52e1e36240..bad59d6be8 100644 --- a/docs/adr/0025-plugin-package-distribution.md +++ b/docs/adr/0025-plugin-package-distribution.md @@ -46,6 +46,10 @@ to build, no dependencies to resolve, and no trust boundary to cross. `packages/runtime/src/cloud/marketplace-install-local-plugin.ts` and ADR-0016 §9. +> **Path note (2026-09):** every `packages/runtime/src/cloud/…` path in this record is historical and +> deliberately unlinked — `packages/runtime/src/cloud/` was removed by ADR-0006 Phase 4 (`15fcd360d`, 2026-06-11), which took the cloud plugins out of the framework runtime. +> They are kept as written because they record where this decision landed at the time. + The next step is **plugins**: distributable units that contain **executable code and npm dependencies**, not just metadata. The repository already has the *authoring* half of this story: diff --git a/docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md b/docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md index 1e022cc0e8..8929007ccf 100644 --- a/docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md +++ b/docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md @@ -2,6 +2,12 @@ **Status**: Accepted in part (2026-06-21) — D1–D3/D8 implemented (scope-depth enum + evaluator, `sys_business_unit` tree, hierarchy-resolver seam, conformance rows); **D4–D7 superseded by ADR-0090 D3 / ADR-0095**: the `sys_role`/`sys_user_role`/`role_and_subordinates` vocabulary never shipped — the code realizes them as flat `sys_position`/`sys_user_position` with rollup on the BU tree. This ADR's own implementation-status table predates that supersession; read it with the rename applied. **Deciders**: ObjectStack Protocol Architects +**Path note (2026-09), paths only — no decision changes**: this record cites the **pre-rename** +vocabulary, and those four paths no longer resolve. `sys-department.object.ts` and `department-graph.ts` +became `sys-business-unit.object.ts` / `business-unit-graph.ts` in this ADR's own landing (`e16f2a830`); +`sys-role.object.ts` and `role-graph.ts` became `sys-position.object.ts` / `position-graph.ts` in the +ADR-0090 P1 position rename (`6d83431cf`, 2026-07-09). The historical spellings are kept below because +the argument is *about* the pre-rename shape. **Builds on**: [ADR-0010](./0010-metadata-protection-model.md) (metadata protection / object ownership), [ADR-0049](./0049-no-unenforced-security-properties.md) (enforce-or-remove), [ADR-0054](./0054-runtime-proof-for-authorable-surface.md) (runtime proof), diff --git a/docs/adr/0071-dataset-semantic-layer-depth.md b/docs/adr/0071-dataset-semantic-layer-depth.md index aa57456b7d..7d69d4210a 100644 --- a/docs/adr/0071-dataset-semantic-layer-depth.md +++ b/docs/adr/0071-dataset-semantic-layer-depth.md @@ -12,12 +12,12 @@ The first merged draft listed **matrix / across pivoting** as an open gap (a proposed "P1"). That was wrong — a check of the current code found matrix pivoting **already implemented end-to-end**: -- **Render** — `packages/plugin-report/src/DatasetReportRenderer.tsx` → +- **Render** — `objectui:packages/plugin-report/src/DatasetReportRenderer.tsx` → `DatasetMatrixTable` does a true cross-tab: one dataset query over `[...rows, ...columns]`, pivoted client-side into row × column × measure cells, with server-supplied row/column subtotals + grand total and drill-down. Covered by `DatasetReportRenderer.test.tsx`. -- **Author** — `packages/app-shell/src/views/metadata-admin/inspectors/ReportDefaultInspector.tsx` +- **Author** — `objectui:packages/app-shell/src/views/metadata-admin/inspectors/ReportDefaultInspector.tsx` offers `type: 'matrix'` and a dedicated "columns across" dimension editor; `packages/spec/src/ui/report.form.ts` reveals `columns` when `type == 'matrix'`. diff --git a/docs/adr/0080-ai-authored-ui-jsx-source.md b/docs/adr/0080-ai-authored-ui-jsx-source.md index e9107d23e9..c05b64e27e 100644 --- a/docs/adr/0080-ai-authored-ui-jsx-source.md +++ b/docs/adr/0080-ai-authored-ui-jsx-source.md @@ -35,7 +35,7 @@ The SDUI runtime is **not** the thing that needs to change: | Recursive tree interpreter (`type` → component, children recurse) | `@object-ui/react` `SchemaRenderer` → `ComponentRegistry.get()` → `React.createElement` | | Recursive node schema (`{ type, props, children }`, `className`/`style`, `visibleOn`) | `@object-ui/types` `BaseSchema` / discriminated `LayoutSchema` (`objectui:packages/types/src/layout.ts`, literal `type` discriminants) | | Per-component prop declaration | `ComponentInput[]` on `register()` (`objectui:packages/core/src/registry/Registry.ts`) | -| Conflict-free styling channels | typed primitive props → safelisted class map (`ResponsiveGrid.tsx`), and **scoped per-node CSS** (ADR-0065, `packages/core/src/styling/scoped-styles.ts`) | +| Conflict-free styling channels | typed primitive props → safelisted class map (`ResponsiveGrid.tsx`), and **scoped per-node CSS** (ADR-0065, `objectui:packages/core/src/styling/scoped-styles.ts`) | | Enumerable catalog across ~40 plugins | `ComponentRegistry.getAllConfigs()` / `getAllTypes()` | | An HTML escape hatch (today unsafe) | `renderers/basic/html.tsx` — raw `dangerouslySetInnerHTML`, no sanitize | diff --git a/docs/adr/0107-withdrawn-hook-body-write-set-static-gap.md b/docs/adr/0107-withdrawn-hook-body-write-set-static-gap.md index 6948c37bf5..8ee4868454 100644 --- a/docs/adr/0107-withdrawn-hook-body-write-set-static-gap.md +++ b/docs/adr/0107-withdrawn-hook-body-write-set-static-gap.md @@ -74,7 +74,8 @@ state the invariant its ADR decided, and this number decided nothing. The citations that exist today all discuss the withdrawal itself: -- `.changeset/withdraw-adr-0107-drop-writes-proposal.md` — the changeset that withdrew it; +- `.changeset/withdraw-adr-0107-drop-writes-proposal.md` — the changeset that withdrew it (since + consumed by the release, `24c1b91e4`); - `docs/audits/2026-07-app-metadata-reference-integrity-assessment.md` §5 D4 — the audit whose open decision it recorded, which carries the revision; - `scripts/check-adr-anchors.mjs` — the gate, describing this case. diff --git a/docs/adr/0126-packaged-metadata-customization-model.md b/docs/adr/0126-packaged-metadata-customization-model.md index 90e8eb5d20..d5c2168221 100644 --- a/docs/adr/0126-packaged-metadata-customization-model.md +++ b/docs/adr/0126-packaged-metadata-customization-model.md @@ -97,7 +97,9 @@ Three real mechanisms operate across those tiers, each invented separately: object, or nav items to another package's app, merged at boot. Package-grain, additive, upgrade-safe. -And one **paper** mechanism: `packages/spec/src/kernel/metadata-customization.zod.ts` declares a +And one **paper** mechanism: `packages/spec/src/kernel/metadata-customization.zod.ts` (*Path note, +2026-09: the module was retired and deleted whole on 2026-08-29, `9e0ba21a1` — the disposition §6.4 +records; the path is kept as the record of what this section measured*) declares a three-layer (system/platform/user) overlay protocol with field-level change tracking — exported, published in the reference docs, and consumed by **zero** runtime packages ([#12057](https://github.com/objectstack-ai/objectstack/issues/12057)). §6.4 records its From 30c3cf833a7a422e5939cf580105fa177b2cf707 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:12:31 +0000 Subject: [PATCH 3/4] docs(adr): annotate the two ADR-0025 References paths the record-level note did not reach Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --- docs/adr/0025-plugin-package-distribution.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/adr/0025-plugin-package-distribution.md b/docs/adr/0025-plugin-package-distribution.md index bad59d6be8..e4be85f1c4 100644 --- a/docs/adr/0025-plugin-package-distribution.md +++ b/docs/adr/0025-plugin-package-distribution.md @@ -513,6 +513,9 @@ the developers and operators who compose Apps and provision runtimes. - `packages/runtime/src/sandbox/quickjs-runner.ts` — QuickJS-WASM sandbox (T1) - `packages/runtime/src/cloud/marketplace-install-local-plugin.ts` — local inline install (ADR-0016 §9) - `packages/runtime/src/cloud/marketplace-proxy-plugin.ts` — marketplace browse proxy + *(Path note, 2026-09: both `marketplace-install-local-plugin.ts` and `marketplace-proxy-plugin.ts` + are historical and deliberately unlinked — `packages/runtime/src/cloud/` was removed by ADR-0006 + Phase 4, `15fcd360d`, 2026-06-11.)* - `packages/runtime/src/package-state-store.ts` — per-environment disable-state persistence - `packages/cli/src/commands/package/publish.ts` — existing package publish pipeline - `packages/drivers/driver-memory/objectstack.config.ts` — example plugin manifest (`ObjectStackManifest`) From 73998d9f702d692f5a36a8e5dd100b67c7b8e0bd Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 4 Sep 2026 04:14:33 +0000 Subject: [PATCH 4/4] docs(adr): date ADR-0113's two Context sites as the pre-P0 state, re-anchored by symbol Both sites now say they describe the state at decision time (2026-07-30) and name the storage.notNull site that superseded them, and the citation is a symbol anchor (sql-driver.ts#createColumn) rather than a line number. No decision text changed. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --- ...required-write-contract-vs-column-constraint.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/adr/0113-required-write-contract-vs-column-constraint.md b/docs/adr/0113-required-write-contract-vs-column-constraint.md index 97725a6522..56790fed3a 100644 --- a/docs/adr/0113-required-write-contract-vs-column-constraint.md +++ b/docs/adr/0113-required-write-contract-vs-column-constraint.md @@ -16,7 +16,7 @@ verified sites: | Meaning | Where it lives today | |---|---| | a write must provide the value | `objectql/validation/record-validator.ts` | -| the COLUMN is `NOT NULL` | `packages/drivers/driver-sql/src/sql-driver.ts` — `if (field.required) col.notNullable()` | +| the COLUMN is `NOT NULL` | **At decision time (2026-07-30):** `packages/drivers/driver-sql/src/sql-driver.ts#createColumn` — `if (field.required) col.notNullable()`. **Superseded by this ADR's P0** (2026-09 note, #14193): the physical constraint now keys off the explicitly-authored `storage.notNull` at that same `#createColumn` site; `field.required` no longer drives the DDL. | | required-vs-nullable divergence is DRIFT | `packages/drivers/driver-sql/src/schema-drift.ts` — metadata-required + nullable column ⇒ expected `NOT NULL`, and imposing `NOT NULL` over possibly-null data is the classifier's `destructive` class | > ⚠️ **Anchor note (#13556).** The three anchors above were line numbers into @@ -30,6 +30,14 @@ verified sites: > deliberately **not** repaired here: this record's Context describes the > PRE-decision state, and rewriting it inside an anchor migration would edit a > decision record's substance under cover of a formatting change. +> +> **Resolved (2026-09, #14193).** The two Context sites — the table row above and +> the prose sentence under *The tri-binding, concretely* — are now annotated in +> place as the state **at decision time**, each naming the `storage.notNull` site +> that superseded it, and both citations are re-anchored by symbol +> (`packages/drivers/driver-sql/src/sql-driver.ts#createColumn`) rather than by line. ⛔ No decision text changed: +> the Context still describes the pre-P0 tri-binding, which is what motivated the +> decision — it is now dated, so it cannot be read as a description of today. Because all three ride one flag, **tightening any invariant on a deployed object is a destructive migration, blocked by the very legacy nulls that @@ -56,7 +64,9 @@ becomes a recognized posture: *new writes must provide; old rows may rest.* ### The tri-binding, concretely Authoring `required: true` on a field of a **new** object is unremarkable: the -column is created `NOT NULL` (packages/drivers/driver-sql/src/sql-driver.ts), the validator enforces +column is created `NOT NULL` (`packages/drivers/driver-sql/src/sql-driver.ts#createColumn` — *at +decision time; superseded by this ADR's P0, where that same site keys the constraint off the +explicit `storage.notNull` instead*), the validator enforces presence, the form shows the marker, drift never fires. The knob works — until the object has deployed data.