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
{{ message }}
Repository navigation
Commit 9e254cb
Browse filesBrowse the repository at this point in the historyBrowse files
docs(adr): index self-test judges the generator only; check:adr-index alias; versions cite-as; 0071 status on one line
Contract-review respin of the ADR index (seat 1, record 6434963378):
- scripts/adr-index.mjs --self-test no longer asserts on what the live
records say (the one-spelling and ui-parses assertions moved out; they
were already --report's warnings). The live-tree battery now proves only
that the generator reads and renders the real registry. A record with
another status spelling is a warning, never a red — ruling A, 门禁不加.
- The lint step is its own, report-only step running the root alias
`pnpm check:adr-index` (= --self-test then --report), per the GATE
INVOCATION IDIOM that landed in c91544a; the anchors step is back to
`pnpm check:adr-anchors` alone. `adr:index` stays the regeneration alias.
- Shared numbers: a versions group states that the bare number names the
decision and its current text is the highest version; the superseded
unversioned file is cited by its stem, never offered as `ADR-0006`.
- A `**Decided**:` header line is a date line (ADR-0079 now dates to its
decision, 2026-06-28, not its 2026-08-08 reconstruction).
- ADR-0071's status paragraph folded onto its one `**Status**:` line.
Claude-Session: https://claude.ai/code/session_01WGufzgAZv5vcb4H6qvqBAM
Co-authored-by: Claude <noreply@anthropic.com>
**Status**: Proposed. (Refocused — see **Correction** below. The first merged draft also
4
-
proposed matrix/across pivoting; a code check found that already implemented, so
5
-
this ADR now covers only the remaining gap: multi-hop joins.) **Multi-hop to-one joins (≤3 hops / 4 objects) have since been implemented & are live — header pending formal update.**
3
+
**Status**: Proposed. (Refocused — see **Correction** below. The first merged draft also proposed matrix/across pivoting; a code check found that already implemented, so this ADR now covers only the remaining gap: multi-hop joins.) **Multi-hop to-one joins (≤3 hops / 4 objects) have since been implemented & are live — header pending formal update.**
Copy file name to clipboardExpand all lines: docs/adr/README.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,11 +34,13 @@ Listed side by side, never renumbered (Prime Directive 13). A **collision** is t
34
34
35
35
### ADR-0006 — one decision, 3 versions
36
36
37
+
A bare `ADR-0006` names the decision; its current text is [0006-project-environment-split.v4.md](./0006-project-environment-split.v4.md). Cite one revision by its version or its stem.
38
+
37
39
| Cite as | File | Title | Status | Date |
38
40
|---|---|---|---|---|
39
-
|`ADR-0006`|[0006-project-environment-split.md](./0006-project-environment-split.md)| Environment & Project as Independent Siblings — v3 | Superseded — by v4 (`0006-project-environment-split.v4.md`) — 2026-05-20 | 2026-05-20 |
|[ADR-0073](./0073-automation-execution-identity.md)| Automation execution identity — a built-in non-human principal for user-less runs, `runAs` as authorization p… | Proposed — 2026-06-25 | 2026-06-25 | — | — |
146
148
|[ADR-0074](./0074-canonical-audit-timestamp-storage-on-sqlite.md)| Audit timestamps are stored in one canonical, timezone-explicit format on SQLite | Accepted — 2026-06-26. Read side extended (2026-09-07): the read repair th… | 2026-06-26 | — | — |
147
149
|[ADR-0076](./0076-objectql-core-tiering.md)| objectql is the data engine — relocate metadata management (protocol) out of it; enforce the boundary; defer… | Accepted — D1/D2/D4/D5/D6/D8/D9 implemented; D10/D12 partially landed; D11… | 2026-08-15 | — | — |
148
150
|[ADR-0077](./0077-authoring-surface-boundary-hook-flow-validation.md)| The authoring-surface boundary — route by intent, not mechanism; verifiability tier = friction tier; loud-not… | Proposed — 2026-06-28 | 2026-06-28 | — | — |
149
151
|[ADR-0078](./0078-no-silently-inert-metadata.md)| A Zod-valid metadata instance that is functionally incomplete must fail loudly at author time, uniformly acro… | Accepted — framework implemented; the cloud half of §2/§3 pending (cloud)… | 2026-06-28 | — | — |
150
-
|[ADR-0079](./0079-record-display-name.md)| The record display-name contract — `nameField` is the one canonical primary-title pointer | Accepted — implemented. This file is a RETROACTIVE RECONSTRUCTION written… | 2026-08-08| — | — |
152
+
|[ADR-0079](./0079-record-display-name.md)| The record display-name contract — `nameField` is the one canonical primary-title pointer | Accepted — implemented. This file is a RETROACTIVE RECONSTRUCTION written… | 2026-06-28| — | — |
151
153
|[ADR-0080](./0080-ai-authored-ui-jsx-source.md)| AI-authored UI pages — JSX source compiled to the SDUI tree (parse ≠ execute); the component registry is the… | Proposed — 2026-06-29 — partially implemented (2026-07-16 audit): `sdui-pa… | 2026-06-29 | — | ADR-0065 |
152
154
|[ADR-0081](./0081-trusted-react-page-tier.md)| A trusted `kind:'react'` page tier — real React executed in the main tree, gated by a host capability; and re… | Accepted — 2026-06-30 — framework scope implemented (`html`/`react` page k… | 2026-06-30 | — | ADR-0065 |
153
155
|[ADR-0082](./0082-react-component-contract-governance.md)| Governing the react-tier component contract — spec is the protocol source of truth, the registry is a designe… | Accepted — 2026-06-30 | 2026-06-30 | — | — |
@@ -202,7 +204,7 @@ Listed side by side, never renumbered (Prime Directive 13). A **collision** is t
202
204
|[ADR-0132](./0132-multi-organization-runtime-is-open-core.md)| The multi-organization runtime is open core — single-database organization isolation ships open; only the ent… | Accepted — 2026-09-07 — accepted by the merge that landed it on `main`| 2026-09-07 | — | — |
203
205
|[ADR-0133](./0133-org-management-open-basics.md)| Organization management — the open basics; a mirror of cloud ADR-0081 D1/D3/D4 in the repository whose code e… | Accepted — 2026-09-07 — accepted by the merge that landed it on `main` (#1… | 2026-09-07 | — | — |
204
206
|[ADR-0134](./0134-env-side-scim-provisioning.md)| Env-side SCIM provisioning — `@better-auth/scim` is the mechanism, and this platform writes the deactivation | Proposed — 2026-09-07. This file is a MIRROR of the open, mechanism half of | 2026-09-07 | — | — |
205
-
|[ADR-0135](./0135-identity-and-access-architecture.md)| Identity and access architecture — the open half, mirrored from cloud ADR-0024 | Accepted — The DECISION is — it is `objectstack-ai/cloud` ADR-0024, accept… |—| — | — |
207
+
|[ADR-0135](./0135-identity-and-access-architecture.md)| Identity and access architecture — the open half, mirrored from cloud ADR-0024 | Accepted — The DECISION is — it is `objectstack-ai/cloud` ADR-0024, accept… |2026-06-25| — | — |
206
208
|[ADR-0137](./0137-predicate-fault-semantics-are-contract.md)| A predicate's FAULT semantics are part of the protocol — loud at submit, fail-open at render, and a blank pre… | Accepted — 2026-09-18 — this record declares; it implements nothing. D1's… | 2026-09-18 | — | — |
207
209
|[ADR-0138](./0138-guest-model-anonymous-principal-doors-grants-and-organization.md)| The guest model — one anonymous principal, a closed list of doors, one grants channel, one organization rule,… | Accepted — 2026-10-13, accepted by the maintainer's approval of the pull r… | 2026-10-13 | — | — |
208
210
|[ADR-0139](./0139-engine-internal-semi-join-leaf-readable-parent-ids.md)| One engine-internal semi-join leaf — "the ids of object X this caller may read" — pushed down by ObjectQL, ne… | Accepted — 2026-10-11, accepted by the merge that landed it on `main`| 2026-10-11 | — | — |
out+=`A bare \`ADR-${s.number}\` names the decision; its current text is [${current.file}](./${current.file}). Cite one revision by its version or its stem.\n\n`;
420
+
}
417
421
out+='| Cite as | File | Title | Status | Date |\n|---|---|---|---|---|\n';
assert('a-decided-line-is-a-date-line',rec('0042-answer.md',canonical('Accepted — reconstructed 2026-08-08','- **Decided**: 2026-06-28 (the decision), reconstructed 2026-08-08 (this file)\n')).date==='2026-06-28','the decision date, not the reconstruction date');
610
623
assert('date-falls-back-to-the-status-line',rec('0042-answer.md',canonical('Proposed (2026-06-22)')).date==='2026-06-22','the first ISO date in the status value');
611
624
assert('date-is-null-when-nothing-states-one',rec('0042-answer.md',canonical('Proposed')).date===null,'no date is invented');
612
625
}
@@ -648,6 +661,8 @@ export function runSelfTest() {
assert('a-versions-group-cites-the-bare-number-as-the-highest-version',vtext.includes('A bare `ADR-0006` names the decision; its current text is [0006-split.v4.md](./0006-split.v4.md)')&&vtext.includes('| `ADR-0006` (current) / `ADR-0006 v4` / `ADR-0006-split'+'.v4` |')&&vtext.includes('| `ADR-0006-split` (unversioned file, superseded) |'),'the superseded unversioned file is never offered as the bare citation');
assert('ui-records-never-join-a-root-number-group',!text.includes('## Shared numbers\n\nListed')&&text.includes('[ui-0001](../../ui/docs/adr/0001-ui.md)'),'the two registries are indexed apart');
653
668
}
@@ -684,16 +699,20 @@ export function runSelfTest() {
684
699
assert('report-mode-is-exit-zero-by-construction',/return0;\s*}\s*functionmodeJson/.test(readFileSync(join(process.cwd(),SELF_PATH),'utf8'))&&!/process\.exit\(1\)[^\n]*report/.test(readFileSync(join(process.cwd(),SELF_PATH),'utf8')),'modeReport must end in `return 0` and never exit 1');
685
700
}
686
701
687
-
battery('Live tree: every record parses and the registry is not empty');
702
+
battery('Live tree: the generator reads the real registry (the records themselves are --report\'s business)');
688
703
{
704
+
// ⛔ Nothing here asserts on what the records SAY. A record with another
705
+
// status spelling, a stray note in the directory or a stale index is
706
+
// --report's warning (#26076, ruling A: 门禁不加), never this self-test's
707
+
// red — this battery only proves the generator finds and renders the
708
+
// real tree, so a wrong ADR_DIR or a renderer that throws on live input
709
+
// cannot pass on fixtures alone.
689
710
constlive=readRegistries(process.cwd());
690
-
assert('live-root-registry-is-populated',live.root.records.length>=100,`got ${live.root.records.length} records under ${ADR_DIR}/`);
691
-
assert('live-root-registry-has-no-foreign-files',live.root.foreign.length===0,`non-record markdown under ${ADR_DIR}/: ${live.root.foreign.join(', ')}`);
assert('live-root-registry-is-read',live.root.records.length>=1,`got ${live.root.records.length} records under ${ADR_DIR}/ — run from the repository root`);
712
+
assert('live-ui-registry-is-read',live.ui.records.length>=1,`got ${live.ui.records.length} records under ${UI_ADR_DIR}/`);
696
713
assert('live-index-renders',renderIndex({root: live.root.records,ui: live.ui.records}).length>10_000,'the live rendering is not trivially small');
assert('live-verdict-is-a-reading-not-a-throw',typeofv.stale==='boolean'&&Array.isArray(v.problems)&&typeofv.expected==='string','verdict() over the live tree returns its three fields');
697
716
}
698
717
}catch(e){
699
718
failures.push(`self-test threw before finishing — ${e&&e.stack ? e.stack : e}`);
0 commit comments