Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/20595-objectql-provenance-anchors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
'@objectstack/objectql': patch
---

Provenance comments in `@objectstack/objectql` cite the commits and ADRs that decided them, not tracker numbers that no longer resolve

Clause-②: no

Docblocks and comments across the package cited issue-tracker numbers that now answer 404 on GitHub.
Each one now cites the commit in this repository's history that made the decision it describes, or the
ADR that records it (ADR-0029 D9.2a, ADR-0104's 2026-09-05 addendum, ADR-0126 §7.2, ADR-0130 D3).
Some of these docblocks sit on exported members, so the reworded text appears in the published
`index.d.ts` / `index.d.mts`, `core.d.ts` / `core.d.mts` and the shared type chunk, and comments that
esbuild keeps appear in the JavaScript output.

Comment only: no export, type, error code, status, message text or runtime behaviour changes.
2 changes: 1 addition & 1 deletion packages/objectql/src/action-activation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// would switch off an entire installation's actions on its first boot.
// 4. **The write is durable BEFORE it is local.** A store that throws must
// leave the projection untouched, or the engine reports an activation state
// the ledger does not carry — the #10243 shape with persistence bolted on,
// the ledger does not carry — the env-wide toggle leak's shape with persistence bolted on,
// which ADR-0126 §7.2 exists to remove.
// 5. **Survives re-registration**, which is the in-process half of "survives a
// restart": `resyncAuthoredActions` re-registers handlers on every
Expand Down
2 changes: 1 addition & 1 deletion packages/objectql/src/action-activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export class ObjectStoreActionActivationStore extends ObjectStoreMetadataActivat
* written from exactly two places — {@link hydrate} (boot, from the ledger) and
* {@link setActive} (which writes the durable row FIRST and updates the set only
* after that write returns) — so it cannot drift into being an independent,
* process-local off-switch, which is the #10243 mechanism ADR-0126 retires.
* process-local off-switch, which is the env-wide toggle leak's mechanism ADR-0126 §7.2 retires.
*
* ⚠️ It is deliberately NOT re-read per `metadata:reloaded`: a reload
* re-registers HANDLERS, and a re-registered handler must stay disabled. The
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* #14423 — the audit and the router, defined on ONE identity and ONE set of
* Commit a56baa2bd — the audit and the router, defined on ONE identity and ONE set of
* sources.
*
* ---------------------------------------------------------------------------
Expand Down
18 changes: 9 additions & 9 deletions packages/objectql/src/action-governance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
* undeclared only when EVERY source the router resolves through answered
* nothing for it.
*
* [#14423] EXISTENCE is settled now too, on both halves of the D5 bijection
* [commit a56baa2bd] EXISTENCE is settled now too, on both halves of the D5 bijection
* and in both of the ways the two sides could disagree:
*
* - IDENTITY — the metadata plane is read KEYED
Expand Down Expand Up @@ -264,7 +264,7 @@ export function reconcileActionRegistrations(
/**
* One declaration the engine can dispatch against.
*
* ## [#14423] `storeKey` — the identity a body is not required to carry
* ## [commit a56baa2bd] `storeKey` — the identity a body is not required to carry
*
* `action` is the declaration BODY, exactly as its source hands it over.
* `storeKey` is the key the metadata plane holds that body under, present
Expand Down Expand Up @@ -317,7 +317,7 @@ export interface GovernanceLogger {
* with the object-embedded copy winning, mirroring the execution layer's
* artifact-wins rule.
*
* ## [#14423] Two spellings for the metadata source, and why the keyed one wins
* ## [commit a56baa2bd] Two spellings for the metadata source, and why the keyed one wins
*
* `loadStandaloneActionsKeyed` reads the plane under the identity the STORE
* holds each row by (`MetadataManager.loadManyKeyed`); `loadStandaloneActions`
Expand All @@ -336,7 +336,7 @@ export interface GovernanceLogger {
* So when the keyed source is present it REPLACES the unkeyed one — they read
* the same population, and reading both would only re-admit the guess. The
* unkeyed parameter stays for callers that have no keyed read to offer; it is
* the pre-#14423 behaviour verbatim, nameless rows dropped and all.
* the behaviour before commit a56baa2bd, verbatim, nameless rows dropped and all.
*/
export async function collectEngineActionDeclarations(
objects: any[],
Expand Down Expand Up @@ -394,7 +394,7 @@ export async function collectEngineActionDeclarations(

/**
* The router's BY-NAME rungs, applied to the handlers the declaration set did
* not cover — `registry.getItem('action', <key>)` (rung 2) and, since #14423,
* not cover — `registry.getItem('action', <key>)` (rung 2) and, since commit a56baa2bd,
* `meta.loadDiagnosed('action', <key>)` / `meta.load(…)` (rung 3) — each
* accepted on the router's own ownership test.
*
Expand All @@ -403,7 +403,7 @@ export async function collectEngineActionDeclarations(
* The router never enumerates either source: it asks for ONE name. Mirroring
* it means asking for one name. And enumeration is not a substitute here even
* where it exists — a plural read and a by-name read of the same plane can
* disagree, which is the whole subject of #14423: one loader fault is
* disagree, which is the whole subject of the card commit a56baa2bd closed: one loader fault is
* swallowed by the plural read and served by the by-name read, so a handler
* whose declaration lives on the faulted loader reads "undeclared" from the
* enumeration alone. The keyed enumeration closes the IDENTITY half of that
Expand Down Expand Up @@ -474,7 +474,7 @@ function fingerprint(r: ReturnType<typeof reconcileActionRegistrations>): string
* (`metadata:reloaded` re-runs this; a re-sync that changed nothing should
* not repeat the same warning).
*
* ## [#14423] Both halves of the bijection read what the router reads
* ## [commit a56baa2bd] Both halves of the bijection read what the router reads
*
* The two findings used to stand on different sources, which is how the audit
* could contradict the router about whether a declaration exists:
Expand Down Expand Up @@ -522,7 +522,7 @@ export async function runActionGovernanceInventory(args: {
*/
loadStandaloneActions?: () => Promise<any[]>;
/**
* [#14423] The metadata plane's `action` rows KEYED by the store's own key
* [commit a56baa2bd] The metadata plane's `action` rows KEYED by the store's own key
* (`meta.loadManyKeyed('action')`). This is the source the declaration
* half of the bijection is defined on, so that the audit and the router
* share ONE identity — the store key (#14205) — instead of the audit
Expand All @@ -538,7 +538,7 @@ export async function runActionGovernanceInventory(args: {
*/
lookupRegistryAction?: (actionName: string) => unknown;
/**
* [#14423] The router's rung 3, injected the same way:
* [commit a56baa2bd] The router's rung 3, injected the same way:
* `meta.loadDiagnosed('action', name)?.data`, falling back to
* `meta.load('action', name)` — the caller unwraps, so this returns the
* declaration or nothing, exactly like {@link lookupRegistryAction}.
Expand Down
8 changes: 4 additions & 4 deletions packages/objectql/src/action-owner-key-single-source.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.

/**
* This package spells the standalone-action owner-key ladder ONCE (#14422).
* This package spells the standalone-action owner-key ladder ONCE (commit dc7c226b9).
*
* `ObjectQLPlugin` carried a private `actionObjectKey` that repeated
* {@link standaloneActionOwnerKey}'s three rungs, and the only thing holding
Expand Down Expand Up @@ -73,7 +73,7 @@ describe('standalone-action owner key — one spelling in @objectstack/objectql
expect(plugin, 'plugin.ts is missing from the scan').toBeDefined();
// The negative that used to live here — "plugin.ts does not name the
// deleted member" — moved to the TREE-scoped section at the bottom of
// this file (#14878). Its scope was the defect, not its subject. What
// this file (commit 29db3cd2a). Its scope was the defect, not its subject. What
// stays here is the positive half: the plugin still derives owner keys,
// it just does it through the canonical helper now.
expect(plugin!.text).toContain('standaloneActionOwnerKey(');
Expand All @@ -95,7 +95,7 @@ describe('standalone-action owner key — one spelling in @objectstack/objectql
});

/**
* ── [#14878] The absence assertion is TREE-scoped, not FILE-scoped ──────────
* ── [commit 29db3cd2a] The absence assertion is TREE-scoped, not FILE-scoped ──────────
*
* The negative that used to sit in the plugin test above read `plugin.ts` and
* nothing else, and THAT SCOPE was the defect. A pin written by the deleting PR
Expand Down Expand Up @@ -165,7 +165,7 @@ describe('standalone-action owner key — one spelling in @objectstack/objectql
*/

/**
* The member PR #14667 deleted from `ObjectQLPlugin`. Held as DATA: naming a
* The member commit dc7c226b9 deleted from `ObjectQLPlugin`. Held as DATA: naming a
* symbol in a string cannot resurrect it, and this file is excluded from its own
* scan precisely so it may carry the name.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/**
* [#15989] The kernel→driver supply seam for the ADR-0104 media arm, from the
* ENGINE's side — the ruling on #15041 step 2, as amended by the director
* ENGINE's side — sequencing step 2 of ADR-0104's 2026-09-05 addendum, as amended by the director
* ruling (decision batch #120 item 1).
*
* The driver has accepted `SqlDriverConfig.fileColumnsMoved` since PR #17403,
Expand Down
2 changes: 1 addition & 1 deletion packages/objectql/src/core-boundary.ratchet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
// What this file does NOT see, and what does (#15347)
//
// This is a SOURCE SCAN over two hard-coded names. Both limits are by
// construction, and #14680 is what they cost: a heavyweight arriving through
// construction, and the leak commit 3bd9b3498 closed is what they cost: a heavyweight arriving through
// any other specifier is outside FORBIDDEN_PACKAGES, and a scan of this
// package's own sources cannot follow one that arrives three packages deep —
// which is how that one arrived, invisible to every gate for the whole time it
Expand Down
10 changes: 5 additions & 5 deletions packages/objectql/src/driver-fault-redaction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ describe('redactStatementFromMessage', () => {
});
});

// #8823 — the tail is kept because it names IDENTIFIERS, and on MySQL's
// Commit 4dfa369a9 — the tail is kept because it names IDENTIFIERS, and on MySQL's
// duplicate-entry family it does not: `ER_DUP_ENTRY` prints the conflicting
// VALUE in the diagnostic itself. These cases pin both halves of the remedy —
// the value goes, the index name stays — because a fix that blanked the tail
Expand Down Expand Up @@ -136,7 +136,7 @@ describe('#8823 — a caller value inlined in the diagnostic itself', () => {
});

it('redacts a BARE diagnostic too — the shape that reaches us without a statement', () => {
// Before #9030 the shared leak predicate did not recognise this phrasing,
// Before commit 27a567dd8 the shared leak predicate did not recognise this phrasing,
// so a bare `Duplicate entry …` was turned away at the door and kept its
// value. That limb landed for a different reason; the two compose here.
const out = redactStatementFromMessage(`Duplicate entry '${EMAIL}' for key 'crm_account.email'`);
Expand Down Expand Up @@ -284,7 +284,7 @@ describe('#9160 — the value-bearing families the live probe measured', () => {
});

describe('postgres invalid_text_representation (22P02) / invalid_datetime_format (22007)', () => {
// ⛔ The family the #8823 note was waiting for. Postgres' UNIQUE violation is
// ⛔ The family the commit 4dfa369a9 note was waiting for. Postgres' UNIQUE violation is
// saved only because its value sits on `error.detail`, which
// `ObjectLogger.write` never serializes — "coincidence, not a defence". This
// family puts the caller's value on `error.message`, which IS serialized, so
Expand Down Expand Up @@ -761,7 +761,7 @@ describe('#8682 half B — the write-path loggers', () => {
}

/**
* The one driver double in this file. #8823 needed a MySQL-shaped fault and
* The one driver double in this file. Commit 4dfa369a9 needed a MySQL-shaped fault and
* the shape is a PARAMETER rather than a second double — one fake engine per
* file keeps the contract the double implements reviewable in one place.
*/
Expand Down Expand Up @@ -864,7 +864,7 @@ describe('#8682 half B — the write-path loggers', () => {
});

/**
* [#8823] The same write path, with the fault MySQL raises instead — where
* [commit 4dfa369a9] The same write path, with the fault MySQL raises instead — where
* the caller's value is in the DIAGNOSTIC and not only in the statement, so
* the statement cut alone never reached it.
*/
Expand Down
24 changes: 12 additions & 12 deletions packages/objectql/src/driver-fault-redaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* Nothing else about it moved: the same redacted `message`/`stack` reach the
* same `error` key of the same meta bag (`ObjectQL.writeFailureLogMeta`).
*
* ## [#8823] …but "the tail names identifiers" is not true of every dialect
* ## [commit 4dfa369a9] …but "the tail names identifiers" is not true of every dialect
*
* The paragraph above was written with a premise attached: that whatever the
* database prints after the separator names IDENTIFIERS — a column, a table, a
Expand All @@ -60,7 +60,7 @@
* ```
*
* Three keep an identifier; the second keeps a caller's value. Measured through
* this function, not predicted — and re-measured byte-identical after #9030
* this function, not predicted — and re-measured byte-identical after commit 27a567dd8
* taught the shared leak predicate this phrasing, which moves the VERDICT but
* not the cut.
*
Expand All @@ -81,7 +81,7 @@
*
* ## [#9160] The list is now MEASURED, and there is a way to notice a gap
*
* #8823 left one entry and no instrument: nothing measured whether a diagnostic
* Commit 4dfa369a9 left one entry and no instrument: nothing measured whether a diagnostic
* a driver produced carried a value, so the next entry needed the same accident
* that found the first. `sql-driver-diagnostic-value-probe.test.ts` is that
* instrument. It plants a canary value, raises each candidate family against
Expand All @@ -108,7 +108,7 @@
* ```
*
* ¹ on `error.message`. Both put the caller's row on `error.detail`, which
* `ObjectLogger.write` does not serialize — the coincidence #8823 recorded, and
* `ObjectLogger.write` does not serialize — the coincidence commit 4dfa369a9 recorded, and
* it is still only a coincidence. **The three Postgres families marked VALUE put
* the caller's value on `message`, the field that IS serialized**, so nothing
* covers them but the entries below. That was the open question #9160 asked and
Expand Down Expand Up @@ -140,7 +140,7 @@
* ```
* pg 22P02/22007 value runs to end of message → head-anchored cut (below)
* mysql 1292 value runs to end of message → head-anchored cut (below)
* pg 22003 value "…" is out of range … → `tail`, the #8823 mechanism
* pg 22003 value "…" is out of range … → `tail`, the commit 4dfa369a9 mechanism
* ```
*
* `22003` was assumed unreachable on the reasoning that its value slot holds a
Expand Down Expand Up @@ -266,11 +266,11 @@ const STATEMENT_SEPARATOR = ' - ';
/** What replaces a statement that carried nothing but values. */
const REDACTED_STATEMENT = '[statement and bound values redacted]';

/** [#8823] What replaces one caller value inlined in the database's own diagnostic. */
/** [commit 4dfa369a9] What replaces one caller value inlined in the database's own diagnostic. */
const REDACTED_VALUE = '[value redacted]';

/**
* [#8823] MySQL/MariaDB `ER_DUP_ENTRY` (1062), whole: the template's own head,
* [commit 4dfa369a9] MySQL/MariaDB `ER_DUP_ENTRY` (1062), whole: the template's own head,
* the conflicting VALUE, and the `for key <index>` tail that anchors it.
*
* `Duplicate entry '%-.192s' for key '%-.192s'` — the first slot is whatever the
Expand All @@ -295,7 +295,7 @@ const REDACTED_VALUE = '[value redacted]';
const DUPLICATE_ENTRY = /(duplicate entry\s+)["'`][\s\S]*["'`](\s+for key\s+["'`][^"'`]+["'`])/gi;

/**
* [#8823] The same template with its head already gone — what the statement cut
* [commit 4dfa369a9] The same template with its head already gone — what the statement cut
* leaves behind when the conflicting VALUE itself contained ` - `.
*
* Measured: `insert into … values ('2026 - Q3 plan') - Duplicate entry '2026 -
Expand Down Expand Up @@ -352,7 +352,7 @@ const MYSQL_INCORRECT_VALUE_TAIL = /'(\s+for column\s+'[^']*'\s+at row\s+\d+)/gi
* invalid input syntax for type timestamp with time zone: "CANARY-notadate"
* ```
*
* **This is the family the #8823 note was waiting for.** Postgres' unique
* **This is the family the commit 4dfa369a9 note was waiting for.** Postgres' unique
* violation is saved only because its value sits on `error.detail`, which
* `ObjectLogger.write` does not serialize — recorded there as "coincidence, not
* a defence". Here the value is on `error.message`, the field that IS
Expand Down Expand Up @@ -405,7 +405,7 @@ const PG_VALUE_OUT_OF_RANGE = /(value\s+)"[\s\S]*"(\s+is out of range for type [
* logged: Q3" is out of range for type integer ← `Q3` is caller data
* ```
*
* This family keeps its right anchor, so it takes the #8823 recovery and NOT a
* This family keeps its right anchor, so it takes the commit 4dfa369a9 recovery and NOT a
* `head`: everything before ` is out of range for type` is value residue by
* construction and is dropped whole. ⛔ It must not be given a `head` — its
* diagnostic continues past the value, which is exactly the shape the head
Expand Down Expand Up @@ -678,7 +678,7 @@ export function redactStatementFromMessage(message: string): string {
if (!message || !looksLikeInternalErrorLeak(message)) return message;
const cut = statementCut(message);
// No statement to cut — but a dialect may still have inlined a value in the
// diagnostic itself, and since #9030 taught the shared predicate this
// diagnostic itself, and since commit 27a567dd8 taught the shared predicate this
// phrasing, a BARE `Duplicate entry …` now reaches this line instead of
// being turned away above.
if (cut === -1) return redactDiagnosticValues(message);
Expand Down Expand Up @@ -716,7 +716,7 @@ function statementCut(message: string): number {
}

/**
* [#8823] Drop the caller values a dialect inlines into its OWN diagnostic,
* [commit 4dfa369a9] Drop the caller values a dialect inlines into its OWN diagnostic,
* keeping every identifier around them.
*
* Runs on the tail the statement cut already produced, never on the whole
Expand Down
6 changes: 3 additions & 3 deletions packages/objectql/src/duplicate-record-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { isUniqueViolationError, uniqueViolationColumn } from '@objectstack/types';

/**
* The ADR-0112 envelope `engine.insert` (#14095) and `engine.update` (#14390)
* The ADR-0112 envelope `engine.insert` (#14095) and `engine.update` (commit 9d7f7259f)
* raise when a driver refuses a row as a unique-constraint violation.
*
* ## The defect this retires
Expand Down Expand Up @@ -36,7 +36,7 @@ import { isUniqueViolationError, uniqueViolationColumn } from '@objectstack/type
* caller of `engine.insert` / `engine.update` (a hook, a flow node, a
* script holding the engine) branches on, on every driver. ⛔ It is not
* the WIRE spelling: every REST route — the single-record door, the
* whole-request bulk / import doors, and since #14723 the per-row reports
* whole-request bulk / import doors, and since commit 65846bc46 the per-row reports
* of `POST /data/:object/batch` and the import runner alike — reports a
* unique-constraint refusal as `UNIQUE_VIOLATION`, the standard-catalog
* member the published protocol docs give for the 409 constraint-violation
Expand Down Expand Up @@ -134,7 +134,7 @@ function buildDuplicateMessage(object: string, field?: string): string {
}

/**
* A write door's driver-error exit — `insert` (#14095) and `update` (#14390),
* A write door's driver-error exit — `insert` (#14095) and `update` (commit 9d7f7259f),
* by-id and predicate alike: the platform envelope for a unique violation, or
* the caller's own error unchanged for anything else.
*
Expand Down
Loading
Loading