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
20 changes: 20 additions & 0 deletions .changeset/20595-metadata-core-provenance-anchors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@objectstack/metadata-core': patch
---

Provenance comments in `@objectstack/metadata-core` cite the commits 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 now cites the commit in this repository's history that made the decision it describes, with two
exceptions: two comments on `retiredFromLoadPath`'s jurisdiction (in `artifact-forward-conversion.ts`
and its test) cite ADR-0087, which records that determination, and five comments that meant an
objectui issue now spell it `objectui#6111`, as they already spelled `objectui#6110` beside it. One
commit citation sits inside a maintainer ruling quoted in `record-organization.ts`: the number there
became the bracketed editorial substitution `[commit 7901b2dd2]`, the commit that landed the ruling it
names, and the rest of the quotation is unchanged. Some of these docblocks sit on exported members, so
the reworded text appears in the published declaration files (`index.d.ts` / `index.d.cts`,
`testing.d.ts` and a shared declaration chunk); the JavaScript output and its sourcemaps do not change.

Comment only: no export, type, error code, status, message text or runtime behaviour changes.
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ describe('the artifact door never stamps a column constraint (ADR-0113, #16693)'
* the defect is WHO writes `_unpublished`).
*
* The entry is `retiredFromLoadPath: true`, which does NOT hold it back here —
* that flag's jurisdiction is the authoring funnel and nothing else (#16864's
* that flag's jurisdiction is the authoring funnel and nothing else (ADR-0087's recorded
* determination, landed). So before this fix an artifact declaring
* `engines.protocol: ^17.0.0` — the range `create-objectstack` stamps — had
* every `defineApp({ hidden: true })` in it registered as an unpublished app,
Expand Down
2 changes: 1 addition & 1 deletion packages/metadata-core/src/artifact-forward-conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
* for `field-required-notnull-explicit`, #16693; measured again for
* `app-hidden-to-unpublished`, #17885). Retirement does not hold those back
* either: `retiredFromLoadPath`'s jurisdiction is the AUTHORING funnel and
* nothing else (#16864's determination, and the flag's own docblock now says
* nothing else (ADR-0087's recorded determination, and the flag's own docblock now says
* so) — which is exactly why the window has to name them here.
*
* ⇒ {@link DEFAULT_FLIPS_NOT_REPLAYED_HERE} lists them, and the door refuses
Expand Down
2 changes: 1 addition & 1 deletion packages/metadata-core/src/code-artifact-provenance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* "Does a code package ship this name?" — the ADR-0029 D9.6 provenance test.
*
* [#10062] Sunk here from `@objectstack/objectql`'s registry by the same
* [commit fa5d137ab] Sunk here from `@objectstack/objectql`'s registry by the same
* criterion as the write-verb dispatch predicates and the audit governance
* table above it in `index.ts`: a second layer needs the answer, and the
* reverse import would either close a cycle or make the consumer depend on the
Expand Down
2 changes: 1 addition & 1 deletion packages/metadata-core/src/contract-suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export interface DeclaredDivergences {
* for it is a MAY. That sentence used to be unwritten, and this member's
* own doc used to name the no-`since` case as part of the divergence.
*
* Value is the tracking issue, e.g. `'#10842'`. **No declaration today:**
* Value is the tracking issue, e.g. the one commit f334d662e closed. **No declaration today:**
* `SysMetadataRepository`, the only one there has ever been, was fixed and
* deleted its line — the pin below is what told it to. An empty ledger is
* the mechanism at rest, not dead code; the shrink-only direction is the
Expand Down
8 changes: 4 additions & 4 deletions packages/metadata-core/src/form-predicate-root-policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe('the bound vocabulary is checked against the LIVE contract, not a copy
* metadata forms. No `current_user` at section level — it is unbound
* here and the predicate would fault open."
*
* #12914 replaced that sentence — objectui#6110 threads the host scope into
* Commit f887e5249 replaced that sentence — objectui#6110 threads the host scope into
* `isSectionVisible`, objectui#6111 evaluates the section predicate on the
* `section-divider` pseudo-field with that scope bound — and the copy above
* went stale HERE in total silence, because no gate reads a comment. It is
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('the bound vocabulary is checked against the LIVE contract, not a copy
// ⚠️ INVERTED IN PLACE. Was "judges the SAME predicate differently per
// surface — the whole point of the split", expecting `['current_user']`
// from the section vocabulary. The section binds the root since
// objectui#6110 + #6111 (contract landed by #12914), so the section answer
// objectui#6110 + objectui#6111 (contract landed by commit f887e5249), so the section answer
// is now `[]` too, and a finding there would be a boot notice about a
// predicate that resolves.
const source = 'current_user.id == record.owner';
Expand Down Expand Up @@ -255,7 +255,7 @@ describe('detectUnboundFormViewPredicateRoots — traversal', () => {

it('stays SILENT on a current_user-family predicate on EITHER surface', () => {
// Both regressions in one loop. Each of these resolves at FIELD level
// (objectui#6010) and at SECTION level (objectui#6110 + #6111), so
// (objectui#6010) and at SECTION level (objectui#6110 + objectui#6111), so
// flagging one is crying wolf on a legitimate, correctly-authored
// predicate — the failure the module doc forbids, once per surface.
for (const root of CURRENT_USER_FAMILY_ROOTS) {
Expand All @@ -276,7 +276,7 @@ describe('detectUnboundFormViewPredicateRoots — traversal', () => {
it('says NOTHING about the same root at SECTION level either — it binds there now', () => {
// ⚠️ INVERTED IN PLACE. This case asserted exactly ONE finding — the
// section slot — "where the contract says it is unbound", while the
// identical field predicate stayed silent. #12914 replaced that contract
// identical field predicate stayed silent. Commit f887e5249 replaced that contract
// sentence, so the two slots now answer alike and the artifact below is
// healthy on both. A finding here would be a boot notice about a predicate
// that resolves, which the module doc names as worse than no notice.
Expand Down
10 changes: 5 additions & 5 deletions packages/metadata-core/src/form-predicate-root-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* forms, and `data` — the row under edit, at every depth, repeater rows
* included — in metadata-editing forms. BOTH predicate surfaces additionally
* bind `current_user` and its ADR-0068 aliases — a FIELD since objectui#6010,
* a SECTION since objectui#6110 + #6111. The contract states the failure mode
* a SECTION since objectui#6110 + objectui#6111. The contract states the failure mode
* beside the vocabulary (`packages/spec/src/ui/view.zod.ts`,
* `FormFieldSchema.visibleWhen` / `FormSectionSchema.visibleWhen`): **a bare
* identifier is UNBOUND, the predicate faults, and `visibleWhen`'s fault
Expand Down Expand Up @@ -111,14 +111,14 @@
* 1. **FIELD.** The first version omitted `current_user`, quoting
* `FormFieldSchema.visibleWhen` faithfully — the root genuinely had been
* unbound there (#6146). objectui#6010 had already bound it and the prose
* had not caught up; #12930 re-measured the prose, and this module needed a
* had not caught up; commit b5a239815 re-measured the prose, and this module needed a
* same-day correction.
* 2. **SECTION.** That correction then split the vocabulary and justified the
* section half by quoting `FormSectionSchema.visibleWhen` — *"`current_user`
* is absent here and that is CORRECT for a section: the section docblock
* states it is unbound at that level and the predicate faults open."*
* Faithful again, and stale again: objectui#6110 + #6111 had bound it, and
* #12914 re-measured the prose. This list is that second correction.
* Faithful again, and stale again: objectui#6110 + objectui#6111 had bound it, and
* commit f887e5249 re-measured the prose. This list is that second correction.
*
* The prose is a transcription of a renderer, so it can only ever LAG one.
* Membership here is therefore decided by the mechanism, stated so a reader can
Expand Down Expand Up @@ -202,7 +202,7 @@ export const BOUND_FORM_VIEW_PREDICATE_ROOTS: readonly string[] = [
* that the QUESTION is still per surface: "what does a FIELD predicate bind?"
* and "what does a SECTION predicate bind?" are two questions with one answer
* today, and that answer rests on two different renderers (objectui#6010 versus
* objectui#6110 + #6111). Either can move without the other; when one does,
* objectui#6110 + objectui#6111). Either can move without the other; when one does,
* this is where the divergence goes, and the live-contract assertion in this
* module's test is what makes the day it happens findable.
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/metadata-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export * from './engine-findone-predicate.js';
// reporting two.
export * from './audit-field-governance.js';

// [#10062] The ADR-0029 D9.6 provenance pair, sunk here from
// [commit fa5d137ab] The ADR-0029 D9.6 provenance pair, sunk here from
// `@objectstack/objectql`'s registry by the same criterion as everything above:
// `@objectstack/service-automation` needs the same "does a code package ship
// this name?" answer for ADR-0048 flow precedence, and was reaching it by
Expand Down Expand Up @@ -117,7 +117,7 @@ export * from './meta-write-org-scope.js';
// (through `declaresOrgOverride`) so a second copy is forbidden drift.
export * from './meta-write-capability.js';

// [#8707 / #10101] The shared platform-row organization resolver — sunk here
// [commit 1408fe385 / #10101] The shared platform-row organization resolver — sunk here
// from `@objectstack/plugin-audit` per the maintainer ruling recorded on
// cloud#1395 ("promoted to a shared resolver used by all three platform-row
// writers"). The three sanctioned consumers — audit stamping, the approval-row
Expand Down
2 changes: 1 addition & 1 deletion packages/metadata-core/src/meta-write-capability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ describe('#12702 — org-scoped tier-A admission, derived from the registry', ()

it('the boundary fold composes: a URL-only spelling folded through canonicalMetaUrlType is admitted', () => {
// `email_templates` is a URL-only spelling (`SINGULAR_TO_PLURAL` has no
// manifest key for it — the #10340 measurement). The doors fold BEFORE
// manifest key for it — the measurement commit 26f3588fb wrote). The doors fold BEFORE
// asking; this case pins that the folded spelling answers tier-A.
expect(canonicalMetaUrlType('email_templates')).toBe('email_template');
const out = verdict({
Expand Down
4 changes: 2 additions & 2 deletions packages/metadata-core/src/meta-write-capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ export type MetaWriteCapabilityVerdict =
*
* `canonicalType` MUST be the URL segment folded through
* `canonicalMetaUrlType` — the boundary folds, the layers below read the
* canonical singular (`metadata-url-spelling.ts`; the #10340 measurement in
* canonical singular (`metadata-url-spelling.ts`; the measurement commit 26f3588fb wrote in
* `meta-write-org-scope.ts` is why this is not optional).
*
* `activeOrganizationId` MUST be the same value the door threads into
* {@link organizationIdForMetaWrite} (REST `ctx.tenantId`, dispatcher
* `resolveActiveOrganizationId`) — one resolution feeding authorization AND
* scope, the single-resolution shape the REST doors already carry (#8919).
* scope, the single-resolution shape the REST doors already carry (commit b5378550e).
*/
export function metaWriteCapabilityVerdict(input: {
isSystem?: boolean;
Expand Down
6 changes: 3 additions & 3 deletions packages/metadata-core/src/meta-write-org-scope.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
//
// #10340 — `declaresOrgOverride` and the boundary fold, pinned as ONE
// Commit 26f3588fb — `declaresOrgOverride` and the boundary fold, pinned as ONE
// composed contract.
//
// The predicate tolerates the MANIFEST-collection spellings only; the URL
Expand All @@ -19,7 +19,7 @@
// `metadata-url-spelling.ts` forbids ("nothing here should ever be
// consulted by a predicate one layer down"). If a future change widens
// the predicate, this pin turns red so the widening is argued against
// #10340 / #7894 rather than slipped in as a convenience.
// commit 26f3588fb / #7894 rather than slipped in as a convenience.

import { describe, it, expect } from 'vitest';
import { DEFAULT_METADATA_TYPE_REGISTRY } from '@objectstack/spec/kernel';
Expand All @@ -38,7 +38,7 @@ const REGISTRY_FLAG = new Map<string, boolean>(

describe('#10340 org scope composed with the boundary fold', () => {
it('fold → predicate answers the registry flag for EVERY spelling in the URL map', () => {
// The contract every REST door relies on after #10340: whatever the
// The contract every REST door relies on after commit 26f3588fb: whatever the
// caller spelled, folding first yields the canonical type's own
// declaration. Quantified over the whole map so a new spelling limb
// arrives already covered.
Expand Down
4 changes: 2 additions & 2 deletions packages/metadata-core/src/meta-write-org-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import { PLURAL_TO_SINGULAR, SINGULAR_TO_PLURAL } from '@objectstack/spec/shared
* Metadata types whose registry entry declares `allowOrgOverride: true`,
* augmented with each one's MANIFEST plural spelling (`SINGULAR_TO_PLURAL`).
*
* ⚠️ [#10340] That augmentation is NOT the protocol's URL fold, and the doc
* ⚠️ [commit 26f3588fb] That augmentation is NOT the protocol's URL fold, and the doc
* that used to stand here — "judged identically to the singular form — the
* same normalization the protocol's own allow-list does" — was measured
* false. The protocol folds through `META_URL_TO_SINGULAR`, the COMPLETE
Expand Down Expand Up @@ -109,7 +109,7 @@ const ORG_OVERRIDABLE_TYPES: ReadonlySet<string> = (() => {
*
* Expects the CANONICAL singular type. It additionally tolerates the
* manifest-collection spellings (`views`, `emailTemplates`, …) — kept for the
* dispatcher-era callers — but ⚠️ [#10340] that tolerance is NOT the URL
* dispatcher-era callers — but ⚠️ [commit 26f3588fb] that tolerance is NOT the URL
* fold: URL-only spellings (`translations`, `email_templates`) answer
* `false` here. A caller holding a raw `/meta/:type` segment must fold it
* through `canonicalMetaUrlType` BEFORE asking, as the REST doors do; see
Expand Down
6 changes: 3 additions & 3 deletions packages/metadata-core/src/record-organization.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.

/**
* [#8707 / #10101] The shared platform-row organization resolver — "which
* [commit 1408fe385 / #10101] The shared platform-row organization resolver — "which
* column carries THIS object's own organization?", resolved from the object's
* REGISTERED schema, never hard-coded to one spelling.
*
Expand All @@ -16,7 +16,7 @@
*
* ## The ruling this promotion implements (maintainer, 2026-08-17, cloud#1395)
*
* > Ruled: Option A — extend the #8778 ruling: `resolveRecordOrganizationField`
* > Ruled: Option A — extend the [commit 7901b2dd2] ruling: `resolveRecordOrganizationField`
* > is promoted to a shared resolver used by all three platform-row writers
* > (approvals, automation runs, audit). A platform row's organization is the
* > SUBJECT record's organization; actor context is the fallback, never the
Expand Down Expand Up @@ -174,7 +174,7 @@ export function createFieldPresenceProbe(
}

/**
* [#8707] "Which column carries THIS object's own organization?" — resolved
* [commit 1408fe385] "Which column carries THIS object's own organization?" — resolved
* from the object's REGISTERED schema, never hard-coded to one spelling.
*
* ## Precedence — deliberately the platform's own, not a second opinion
Expand Down
4 changes: 2 additions & 2 deletions packages/metadata-core/src/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
* moment MAY be dropped, on both paths alike.
*
* **Shutdown MUST NOT be delivered AS an event.** Written as a MUST NOT
* because it was tried, and both of its halves were measured (#11021). A
* because it was tried, and both of its halves were measured (commit 7d81c889f). A
* synthetic "we are closing" event is subject to the very filters `watch()`
* applies to real ones, so the subscriptions that most need draining are
* exactly the ones that drop it: any non-empty `filter` rejects a ref
Expand All @@ -75,7 +75,7 @@
* Stated conditionally because `close()` is not on the interface below;
* it is offered by some implementations and not others. Where it is
* offered, this is what it owes. Measured across today's three, and there
* are **no declared exceptions**: `SysMetadataRepository` conforms (#11021);
* are **no declared exceptions**: `SysMetadataRepository` conforms (commit 7d81c889f);
* `FileSystemRepository` conforms (#11127 — its `close()` used to retire
* the filesystem watcher and the resync sweep without ever reaching its
* event broker, leaving a parked iterator parked for every subscription
Expand Down
2 changes: 1 addition & 1 deletion packages/metadata-core/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const shared: Options = {
// file and resolve the SAME `@objectstack/spec/package.json`.
//
// Same line, same reason, same measurement as
// `packages/metadata-protocol/tsup.config.ts` (#11235) and
// `packages/metadata-protocol/tsup.config.ts` (commit 376c70f98) and
// `packages/runtime/tsup.config.ts` (#10993) — read either for the sibling
// history. `pnpm check:dual-build-cjs-loads` holds the class: it
// `require()`s every dual-built package's CJS entry point and reds on this
Expand Down
Loading