Uh oh!
There was an error while loading. Please reload this page.
feat(spec): per-type metadata redaction seam in kernel, one credential-key definition in data (#8300) - #8530
Conversation
…al-key definition in data (#8300) - kernel/metadata-type-redaction.ts: registerMetadataTypeRedactor / getMetadataTypeRedactor / listMetadataTypeRedactorTypes, mirroring the registerMetadataTypeSchema registry pattern; the datasource redactor is wired as a BUILT-IN (plugin-init registration is measured fail-open). - data/datasource-credential-redaction.ts: the credential-key derivation and read-path redaction moved from service-datasource (z.never() contract + pre-#8078 aliases + turso encryptionKey), pinned byte-equal by test. - service-datasource re-exports the moved names and keeps restoreRedactedConfig (write-path inverse). - api-surface/ + export-origins/ regenerated for the new exports. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
…adata-redaction-seam
…ee (#8300 relay) Post-merge regeneration on a known-good base per scripts/pm/os-regen-merge.sh: the merge commit took origin/main's side of the os-regen artifacts; this commit re-derives them from the merged source (5074 exports, data + kernel shards), discharging the pre-commit deferral. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MNV7ZSCjNfA38eDCjsXQL
Uh oh!
There was an error while loading. Please reload this page.
Fixes#8300
#8154 (the consumer card,
Blocked-by:this one) unblocks on merge: the metadata read exits can resolvegetMetadataTypeRedactor(type)and apply it per item; the write-path carry-forward and the read-exit application both stay on #8154, per the card's fence.What this delivers
1. The per-type redaction seam —
packages/spec/src/kernel/metadata-type-redaction.ts.registerMetadataTypeRedactor/getMetadataTypeRedactor/listMetadataTypeRedactorTypes, the same built-in-map + runtime-overlay registry pattern as its siblingsregisterMetadataTypeSchemaandregisterMetadataTypeActions, exported beside them from@objectstack/spec/kernel. The redactor contract is minimal: a pure(item) => { item, redactedKeys }whereredactedKeys: []means "ran, nothing to hide" and anundefinedlookup means "no redactor registered" — the absence-vs-empty distinction #8154's consumer depends on. The module header states the two consumer ordering rules #8154 measured (diagnostics computed on the raw body BEFORE redaction; the stored record never mutated).2. One definition of "what is a credential key" —
packages/spec/src/data/datasource-credential-redaction.ts. The derivation half ofservice-datasource'sdatasource-config-redaction.ts(PR #8126), moved verbatim: refused keys derived from each driver's ownz.never()contract, plus the pre-#8078 alias list, plus turso's still-writableencryptionKey; and the read-path redaction built on it (redactUrlPassword,redactDatasourceConfig).service-datasourcenow re-exports these names from@objectstack/spec/data(every existing consumer compiles unchanged) and keepsrestoreRedactedConfig, the admin service's write-path inverse.3. Registration wiring:
datasourceis a BUILT-IN, not a plugin registration. The card's fail-open measurement is the constraint:DatasourceAdminServicePlugin.initis opt-in whilesys_metadatarows and the/metaread exits exist without it, so plugin-init registration would serve cleartext while looking protected. The derivation's ownership is this same package, so the honest non-opt-in site is a built-in map entry — present the moment@objectstack/spec/kernelloads, on every composition that can serve a datasource row. Nothing is left for #8154 to register.Verified premises (re-tested, not re-derived)
git grep -l "@objectstack/metadata-protocol" origin/main -- 'packages/services/*/package.json' 'packages/connectors/*/package.json'→ no matches (exit 1), re-run atorigin/main8c8f0df25— a registry inmetadata-protocolstays unreachable from every package that must call it.origin/mainon top of feat(spec): refuse${…}placeholder syntax in connection-material driver config keys at publish (#8336) #8457's placeholder refusals;placeholderFree/containsUnresolvedPlaceholderindata/driver/common.zod.tsuntouched.Coverage
kernel/metadata-type-redaction.test.ts): register/lookup, replace-on-re-register, registered-overrides-builtin.getMetadataTypeRedactor('datasource')resolves with ZERO registration calls; end-to-end redaction of a legacy stored row (config.password+ URL-embedded password dropped,_diagnosticspassed through by reference, stored body untouched).data/datasource-credential-redaction.test.ts): per-driver literal arrays pinning the exact key set theservice-datasourceoriginal derived — byte-equal, insertion order included — for postgres/mysql/mongodb/turso, the credential-less drivers' canonical fallback, and the unknown-driver fallback. Plus the write-door alignment property:redactUrlPassword's output always passesurlUserinfoPassword(the [Decision] URL-embedded credentials (user:password@hostin driverconfig.url) remain a live cleartext door after #7990 — refuse at publish, or accept as residual risk? #8082 write-door parse), and write-door-accepted URLs come back byte-for-byte.undefined; clean config →redactedKeys: [].service-datasourcesuite (376 tests, including the 8126 redaction pins) passes through the re-export.Verification
@objectstack/spec: full vitest suite 395 files / 10465 tests passed;pnpm typecheckclean (tsc + test-layer ledger unchanged).@objectstack/service-datasource: 16 files / 376 tests passed;pnpm typecheckclean.datasourceentry removed, the fail-closed suite went red (6 tests); with thepwdalias dropped from the moved derivation, the byte-equal pin went red. Both restored from the committed state; 18/18 green after restore.check:generated: all 13 artifacts up to date aftergen:api-surface+gen:export-origins(the two it proved stale — new exports on thedataandkernelentries).check:dev-prereqs(12 unrelated packages have no localdist— only affected closures were built here; CI builds fresh) andcheck:objectui-pin-fresh(.objectui-shastaleness, a release-time fact independent of this diff).Changeset
@objectstack/specminor (new public seam + moved exports),@objectstack/service-datasourcepatch (re-export, behaviour unchanged); adr-0087not-required (no-migration-prescription)— additive exports plus a same-name re-export move, nothing for an upgrader to migrate.Out of scope, untouched:
content/docs/releases/**,packages/spec/src/api/error-code-ledger.zod.ts,packages/spec/src/system/i18n-resolver.ts,packages/spec/src/ui/component.zod.ts,packages/spec/src/contracts/**.Generated by Claude Code