Skip to content

Commit 41dcf11

Browse files
docs(spec): seven more liveness ledgers cite the deciding commit, or state the decision in words, in place of dead tracker numbers (#20788)
Part of #20234 Clause-②: no Slice 2 covers the `datasource`, `api`, `query`, `object`, `email_template`, `mapping` and `webhook` ledgers. Each note that cited a tracker number answering 404 now names the commit that decided it, or, where the number alone carried the meaning, says what was decided. The `manifest` `permissions` note gains the commit pointer the slice-1 review asked for. Only `note` and `_note` strings change: no status, evidence, proof or date moves. One `datasource` evidence string still cites `#8874`; the next slice takes it. One `@objectstack/spec` patch changeset. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8acdae9 commit 41dcf11

9 files changed

Lines changed: 128 additions & 112 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
Notes in seven more liveness ledgers cite the commit that decided them, or say the decision in words, instead of a tracker number that no longer resolves
6+
7+
Clause-②: no
8+
9+
Notes in the `datasource`, `api`, `query`, `object`, `email_template`, `mapping` and
10+
`webhook` ledgers named GitHub issues that no longer exist, so a reader could not tell why
11+
a row carries its verdict. Each such note now either names the commit that made the
12+
decision or, where the number alone carried the meaning, says what was decided. The
13+
`manifest` ledger's `permissions` note also names the commit that recorded its structured
14+
arm's zero apart. The `liveness/` ledgers ship in this package's tarball, which is why
15+
this is a release note at all. Note text only: no row's status, evidence, proof or date
16+
changes, and no schema, export or runtime behaviour changes.

‎packages/spec/liveness/api.json‎

Lines changed: 22 additions & 22 deletions
Large diffs are not rendered by default.

‎packages/spec/liveness/datasource.json‎

Lines changed: 24 additions & 24 deletions
Large diffs are not rendered by default.

‎packages/spec/liveness/email_template.json‎

Lines changed: 14 additions & 14 deletions
Large diffs are not rendered by default.

‎packages/spec/liveness/manifest.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"evidence": "packages/plugins/plugin-security/src/suggested-audience-bindings.ts#collectDeclaredSuggestions (declared permission strings from every enabled installed package feed the suggested audience bindings — `Array.isArray(manifest?.permissions) ? manifest.permissions : []`, which is also where the legacy-arm-only reading below is measured)",
6464
"verifiedAt": "2026-08-28",
6565
"evidenceScope": "cross-repo",
66-
"note": "LIVE ON ONE ARM ONLY, and the split matters. `ManifestPermissionsSchema` (manifest.zod.ts:54) is a union of the legacy flat `string[]` and the structured `PluginPermissionsSchema` (services / hooks / network / fs, ADR-0025 §3.2). The single reader is guarded by `Array.isArray(manifest?.permissions)`, so it reads the LEGACY arm and skips the structured one entirely; no other reader exists in objectstack or objectui. PluginPermissionEnforcer (packages/core/src/security/plugin-permission-enforcer.ts:94-104) is not the missing consumer — it registers the set the install-time consent flow persisted to `sys_package_installation.granted_permissions`, explicitly \"independent of whatever the manifest *requested*\", and nothing in this repo feeds the manifest declaration into it. The verdict is `live` because the key is read; the structured arm's zero is recorded apart rather than being flattened into this one-level row. Cloud unmeasured (see `_note`) — the consent flow ADR-0025 §3.5 describes lives there. 2026-08-28: RE-ANCHORED (commit 9ee2dcfbd) — the citation was still ACCURATE (`suggested-audience-bindings.ts:252` names the read), so this is a grammar migration. What the anchor buys here is specific to this row's shape: the whole `live` verdict rests on ONE reader, so if `collectDeclaredSuggestions` is deleted or renamed the entry now goes red instead of pointing at whatever line 252 has become. Re-closed by hand against c459da6bc."
66+
"note": "LIVE ON ONE ARM ONLY, and the split matters. `ManifestPermissionsSchema` (manifest.zod.ts:54) is a union of the legacy flat `string[]` and the structured `PluginPermissionsSchema` (services / hooks / network / fs, ADR-0025 §3.2). The single reader is guarded by `Array.isArray(manifest?.permissions)`, so it reads the LEGACY arm and skips the structured one entirely; no other reader exists in objectstack or objectui. PluginPermissionEnforcer (packages/core/src/security/plugin-permission-enforcer.ts:94-104) is not the missing consumer — it registers the set the install-time consent flow persisted to `sys_package_installation.granted_permissions`, explicitly \"independent of whatever the manifest *requested*\", and nothing in this repo feeds the manifest declaration into it. The verdict is `live` because the key is read; the structured arm's zero is recorded apart (commit aaacf1d5c, the `PluginPermissionsSchema` docblock) rather than being flattened into this one-level row. Cloud unmeasured (see `_note`) — the consent flow ADR-0025 §3.5 describes lives there. 2026-08-28: RE-ANCHORED (commit 9ee2dcfbd) — the citation was still ACCURATE (`suggested-audience-bindings.ts:252` names the read), so this is a grammar migration. What the anchor buys here is specific to this row's shape: the whole `live` verdict rests on ONE reader, so if `collectDeclaredSuggestions` is deleted or renamed the entry now goes red instead of pointing at whatever line 252 has become. Re-closed by hand against c459da6bc."
6767
},
6868
"objects": {
6969
"status": "live",
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"type": "mapping",
3-
"_note": "MappingSchema (#2611 reusable import mapping). Consumers: the REST import path — resolveNamedMapping fetches the artifact by name and validates it against the request (packages/rest/src/import-mapping.ts:60-107), applyMappingToRows runs the fieldMapping pipeline (:115-167), and import-prepare adopts the artifact's mode/upsertKey as request defaults (packages/rest/src/import-prepare.ts:321-326); objectui's ImportWizard offers registered mappings in a saved-mapping picker (@940ba24 packages/plugin-grid/src/ImportWizard.tsx:979). Seeded 2026-08-01 (#4488) at 8 of 11 live; 7 of 7 live since #4509 removed the three that were not. The IMPORT half of the schema is real and loudly enforced (unsupported transforms/formats are 400s, not silent skips — Prime Directive #10). What left in 17.0.0: the EXPORT half (`extractQuery` — no exporter reads a mapping artifact at all) and the two tuning knobs (`errorPolicy`, `batchSize` — error handling belongs to the import REQUEST, and the write path sizes its own batches). Rows DELETED rather than kept: MappingSchema is strict, so the keys left the walked shape and a retained row would report ORPHAN. Both knobs were unwarnable (schema defaults materialize at parse, so the lint could not tell authored from supplied) — removal was the only channel that could reach an author, which is why they went out inside the 17.0.0 window rather than after a deprecation cycle. 2026-08-28 (#13003): all seven `path:NNN` citations in this file were re-anchored to their consuming symbols. This is the one file in batch 4 whose lines were mostly RIGHT — repaired and re-measured by #11210 on 2026-08-23 — and it is kept as the counter-example: five of the seven landed on the read or inside the statement that performs it, and the two that did not (`mode`, `upsertKey`) had already drifted five lines in five days, onto a guard and a comment inside the right function. Correctness of a line is a property of the day it was measured; the anchor is what makes it a property of the code.",
3+
"_note": "MappingSchema (#2611 reusable import mapping). Consumers: the REST import path — resolveNamedMapping fetches the artifact by name and validates it against the request (packages/rest/src/import-mapping.ts:60-107), applyMappingToRows runs the fieldMapping pipeline (:115-167), and import-prepare adopts the artifact's mode/upsertKey as request defaults (packages/rest/src/import-prepare.ts:321-326); objectui's ImportWizard offers registered mappings in a saved-mapping picker (@940ba24 packages/plugin-grid/src/ImportWizard.tsx:979). Seeded 2026-08-01 (#4488) at 8 of 11 live; 7 of 7 live since #4509 removed the three that were not. The IMPORT half of the schema is real and loudly enforced (unsupported transforms/formats are 400s, not silent skips — Prime Directive #10). What left in 17.0.0: the EXPORT half (`extractQuery` — no exporter reads a mapping artifact at all) and the two tuning knobs (`errorPolicy`, `batchSize` — error handling belongs to the import REQUEST, and the write path sizes its own batches). Rows DELETED rather than kept: MappingSchema is strict, so the keys left the walked shape and a retained row would report ORPHAN. Both knobs were unwarnable (schema defaults materialize at parse, so the lint could not tell authored from supplied) — removal was the only channel that could reach an author, which is why they went out inside the 17.0.0 window rather than after a deprecation cycle. 2026-08-28 (commit 8f10a79f7): all seven `path:NNN` citations in this file were re-anchored to their consuming symbols. This is the one file in batch 4 whose lines were mostly RIGHT — repaired and re-measured by commit 905019b1b on 2026-08-23 — and it is kept as the counter-example: five of the seven landed on the read or inside the statement that performs it, and the two that did not (`mode`, `upsertKey`) had already drifted five lines in five days, onto a guard and a comment inside the right function. Correctness of a line is a property of the day it was measured; the anchor is what makes it a property of the code.",
44
"props": {
55
"name": {
66
"status": "live",
77
"verifiedAt": "2026-08-28",
88
"evidence": "packages/rest/src/import-mapping.ts#resolveNamedMapping (the artifact is read by `{ type: 'mapping', name: mappingName }`; a miss is 404 MAPPING_NOT_FOUND)",
9-
"note": "artifact resolution key for the request's `mappingName` (missing → 404 MAPPING_NOT_FOUND). 2026-08-28: RE-ANCHORED (#13003) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because #11210 re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
9+
"note": "artifact resolution key for the request's `mappingName` (missing → 404 MAPPING_NOT_FOUND). 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because commit 905019b1b re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
1010
},
1111
"label": {
1212
"status": "live",
@@ -18,31 +18,31 @@
1818
"status": "live",
1919
"verifiedAt": "2026-08-28",
2020
"evidence": "packages/rest/src/import-mapping.ts#resolveNamedMapping (`const declared = artifact.sourceFormat` — `xml`/`sql` are refused outright with MAPPING_FORMAT_UNSUPPORTED, a csv-declared mapping applies to xlsx too, and any other mismatch is MAPPING_FORMAT_MISMATCH; never a silent reinterpretation)",
21-
"note": "declared-format gate: `xml`/`sql` are rejected outright (the import endpoint accepts csv/json/xlsx), and a csv-declared mapping applies to xlsx too; a mismatch is a 400, never a silent reinterpretation. 2026-08-28: RE-ANCHORED (#13003) — the enclosing function is unchanged, but the cited RANGE's endpoint (`:97`) had drifted onto the sibling `transform === 'javascript'` refusal, a different key's check inside the same function. That is precisely why the anchor names the function and not a span. Re-closed by hand against 8cb96ec41."
21+
"note": "declared-format gate: `xml`/`sql` are rejected outright (the import endpoint accepts csv/json/xlsx), and a csv-declared mapping applies to xlsx too; a mismatch is a 400, never a silent reinterpretation. 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — the enclosing function is unchanged, but the cited RANGE's endpoint (`:97`) had drifted onto the sibling `transform === 'javascript'` refusal, a different key's check inside the same function. That is precisely why the anchor names the function and not a span. Re-closed by hand against 8cb96ec41."
2222
},
2323
"targetObject": {
2424
"status": "live",
2525
"verifiedAt": "2026-08-28",
2626
"evidence": "packages/rest/src/import-mapping.ts#resolveNamedMapping (`if (artifact.targetObject !== objectName)` → 400 MAPPING_TARGET_MISMATCH)",
27-
"note": "must equal the URL object or the import 400s (MAPPING_TARGET_MISMATCH). 2026-08-28: RE-ANCHORED (#13003) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because #11210 re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
27+
"note": "must equal the URL object or the import 400s (MAPPING_TARGET_MISMATCH). 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because commit 905019b1b re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
2828
},
2929
"fieldMapping": {
3030
"status": "live",
3131
"verifiedAt": "2026-08-28",
3232
"evidence": "packages/rest/src/import-mapping.ts#resolveNamedMapping (the `transform === 'javascript'` refusal — implement-or-reject-loudly, there is no server sandbox); packages/rest/src/import-mapping.ts#applyMappingToRows (the pipeline itself: source/target/transform/params, with none/constant/map/split/join applied here and `lookup` copied through for the pipeline's reference resolution)",
33-
"note": "Lines re-measured 2026-08-23 (#11210): the second range ended at :167 in a 164-line file — the file shrank under the citation and no gate could see it, since the FILE still resolved. The consumer never moved: the javascript rejection is the loop at :95-102 (was :98-105) and the pipeline is applyMappingToRows at :112-164 (was :115-167); the three inline line refs below were off by the same three lines and are corrected with them. the pipeline itself: source/target/transform/params all consumed. none/constant/map/split/join applied in applyMappingToRows (`params.separator` :121, `.value` :129, `.valueMap` :134); `lookup` copies through for the pipeline's metaMap reference resolution; `javascript` is REJECTED with a 400 (no server sandbox — implement-or-reject-loudly). SUB-WALK BOUNDARY, resolved: `params`' lookup-specific keys (`object`/`fromField`/`toField`/`autoCreate`) were read by nothing — reference resolution comes from the target object's own field definitions, not from these — and were REMOVED in the 17.x line (#10329, ADR-0049 enforce-or-remove; strict deletion, so nothing dead remains one level below the drill). Every spelling — the four canonical keys and their eleven ex-aliases — now lands on a guidance prescription at parse; the mapping-lookup-params-removed conversion (protocol 18) strips them from stored sources. The surviving params keys (`value`/`valueMap`/`separator`) are all consumed by applyMappingToRows. 2026-08-28: RE-ANCHORED (#13003) — both ranges land inside their functions (their endpoints `:102` and `:164` are the functions' own closing braces), so this is the grammar migration. Worth recording beside the 2026-08-23 entry above: that repair moved these pointers three lines and they were right for five days; the anchor is the version that does not need re-measuring. Re-closed by hand against 8cb96ec41."
33+
"note": "Lines re-measured 2026-08-23 (commit 905019b1b): the second range ended at :167 in a 164-line file — the file shrank under the citation and no gate could see it, since the FILE still resolved. The consumer never moved: the javascript rejection is the loop at :95-102 (was :98-105) and the pipeline is applyMappingToRows at :112-164 (was :115-167); the three inline line refs below were off by the same three lines and are corrected with them. the pipeline itself: source/target/transform/params all consumed. none/constant/map/split/join applied in applyMappingToRows (`params.separator` :121, `.value` :129, `.valueMap` :134); `lookup` copies through for the pipeline's metaMap reference resolution; `javascript` is REJECTED with a 400 (no server sandbox — implement-or-reject-loudly). SUB-WALK BOUNDARY, resolved: `params`' lookup-specific keys (`object`/`fromField`/`toField`/`autoCreate`) were read by nothing — reference resolution comes from the target object's own field definitions, not from these — and were REMOVED in the 17.x line (commit 15d58dbf1, ADR-0049 enforce-or-remove; strict deletion, so nothing dead remains one level below the drill). Every spelling — the four canonical keys and their eleven ex-aliases — now lands on a guidance prescription at parse; the mapping-lookup-params-removed conversion (protocol 18) strips them from stored sources. The surviving params keys (`value`/`valueMap`/`separator`) are all consumed by applyMappingToRows. 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — both ranges land inside their functions (their endpoints `:102` and `:164` are the functions' own closing braces), so this is the grammar migration. Worth recording beside the 2026-08-23 entry above: that repair moved these pointers three lines and they were right for five days; the anchor is the version that does not need re-measuring. Re-closed by hand against 8cb96ec41."
3434
},
3535
"mode": {
3636
"status": "live",
3737
"verifiedAt": "2026-08-28",
3838
"evidence": "packages/rest/src/import-prepare.ts#prepareImportRequest (`if (body?.writeMode === undefined && (mappingArtifact.mode === 'update' || mappingArtifact.mode === 'upsert')) writeMode = mappingArtifact.mode` — a DEFAULT; an explicit request `writeMode` still wins)",
39-
"note": "an artifact declaring update/upsert sets the import's writeMode default (an explicit request `writeMode` still wins). 2026-08-28: RE-ANCHORED (#13003) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because #11210 re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
39+
"note": "an artifact declaring update/upsert sets the import's writeMode default (an explicit request `writeMode` still wins). 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — the cited line was inside the consuming function, so this is the grammar migration rather than a repair. This file is the batch's counter-example and worth keeping as one: its lines were right because commit 905019b1b re-measured them five days ago, and the anchor is what stops the next edit ABOVE the function from making them wrong again. Re-closed by hand against 8cb96ec41."
4040
},
4141
"upsertKey": {
4242
"status": "live",
4343
"verifiedAt": "2026-08-28",
4444
"evidence": "packages/rest/src/import-prepare.ts#prepareImportRequest (`if (matchFields.length === 0 && Array.isArray(mappingArtifact.upsertKey))` — adopted as the upsert match fields only when the request names none)",
45-
"note": "adopted as the upsert match fields when the request names none. 2026-08-28: RE-ANCHORED (#13003) — `:325` sat on a comment line two lines above the read, inside the right function. The grammar migration, not a repair. Re-closed by hand against 8cb96ec41."
45+
"note": "adopted as the upsert match fields when the request names none. 2026-08-28: RE-ANCHORED (commit 8f10a79f7) — `:325` sat on a comment line two lines above the read, inside the right function. The grammar migration, not a repair. Re-closed by hand against 8cb96ec41."
4646
}
4747
}
4848
}

0 commit comments

Comments
 (0)