Skip to content

Commit c2a9936

Browse files
committed
docs(spec): re-anchor the dead tracker citations in seven more liveness ledgers to the commits that decided them
123 note sites across the datasource, api, query, object, email_template, mapping and webhook ledgers cited GitHub issues that answer 404. Each now names the commit that decided it, or says the decision in words where the number alone carried it. The manifest permissions note gains the commit that recorded its structured arm's zero. Note strings only: every row's status, evidence, proof and verifiedAt is unchanged. Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 085ca6b commit c2a9936

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)