Skip to content

docs(data): accept-and-document mongo/turso passthrough secrets with no binder slot - #9253

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-9124-mongo-passthrough-at-rest-doc
Aug 17, 2026
Merged

os-project-manager merged 1 commit into
mainfrom
claude/issue-9124-mongo-passthrough-at-rest-doc

Conversation

@os-project-manager

@os-project-manager os-project-manager commented Aug 17, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #9124

What

Maintainer ruling 2026-08-17 03:19Z (issue comment 5311378700): Option B — accept-and-document. This PR is the docs deliverable only; Option A (named binder slots) and Option C (publish-door refusal) stay out of scope by that ruling.

Adds a new subsection to content/docs/data-modeling/drivers.mdx — "Secret-shaped keys with no binder slot: accepted at-rest risk", placed directly under the existing "config is validated per driver" section (the section a reader configuring any datasource driver already lands on). It:

  • Names the five keys: mongo's options.proxyPassword, options.tlsCertificateKeyFilePassword, options.key, options.passphrase, and turso's encryptionKey.
  • States plainly that they are writable (the parse accepts them) and stored at rest in sys_metadata as plain text.
  • States the protection that exists today is read-side only: they are stripped before ever being served back over the admin API / Setup UI (mongo config.options.auth.password is a fourth spelling of an inline credential — authorable, persisted cleartext, unredacted, and read by the client #9040, shipped).
  • Records the named restart condition from the ruling: the first real deployment needing an authenticated SOCKS5 proxy or a passphrase-protected key converts this into the binder-slot programme (Option A) — one mechanism covering all five keys.

Verification of the card's premises (done before writing, per the dispatch instructions)

  • PASSTHROUGH_SECRET_PATHS in packages/spec/src/data/datasource-credential-redaction.ts covers exactly the four mongo keys (options.auth.password, options.proxyPassword, options.tlsCertificateKeyFilePassword, options.key, options.passphrase, plus options.authMechanismProperties.AWS_SESSION_TOKEN) — the four named in the card are all present and confirmed still-writable (only auth.password is also refused at write, mirrored in refusedPassthroughSecretPaths).
  • The restore mirror lives in packages/services/service-datasource/src/datasource-config-redaction.ts (restoreRedactedConfig), imports passthroughSecretPaths from spec, and is wired into datasource-admin-service.ts (merged.config = restoreRedactedConfig(...)) — confirmed.
  • turso's encryptionKey (packages/spec/src/data/driver/turso.zod.ts) is z.string().optional() with format: 'password' metadata — a top-level writable config key (STILL_WRITABLE_CREDENTIAL_KEYS.turso), a different code path from mongo's nested passthrough keys (PASSTHROUGH_SECRET_PATHS). The outcome shape the card claims — writable, stored cleartext at rest, redacted only on read — is genuinely the same for both; the underlying mechanism is not identical, and the doc text says "same … posture," not "same mechanism."
  • Confirmed sys_metadata is the real, durable storage table for datasource records (packages/services/service-datasource/src/datasource-admin-plugin.ts, packages/metadata-core/src/objects/sys-metadata.object.ts).

Scope discipline

No runtime code changed — this PR touches only content/docs/data-modeling/drivers.mdx. Per the dispatch scope fence: no publish-door refusal added (Option C), no binder slot growth (Option A).

Out-of-scope finding, not fixed here — filed as #9254: the auto-generated options field description in packages/spec/src/data/driver/mongo.zod.ts (rendered into content/docs/references/data/driver-mongo.mdx and the Studio connection-form help text) currently reads "credential material is refused" — true only for auth.password, not for the four keys this card is about. Not fixed in-place here: it is a packages/spec source edit that pulls in the spec build/docs-regen gate surface, a different verification surface than this docs-only PR.

Tests

Documentation-only change; no test suite applies. Local gates, all green at 5dd33ddd0:

  • pnpm check:nul-bytes
  • pnpm check:docs-audit-scope
  • pnpm check:docs-redirects
  • pnpm check:role-word
  • pnpm --filter @objectstack/spec run check:empty-state
  • pnpm --filter @objectstack/spec run check:liveness
  • pnpm --filter @objectstack/spec run check:strictness-ledger
  • pnpm --filter @objectstack/spec run check:variant-docs

(the four spec gates run because content/docs/** is a CI trigger path in spec-liveness-check.yml, per node scripts/pm/dispatch-gates.mjs content/docs/data-modeling/drivers.mdx; packages/spec was built first per the toolchain-trap note.)

Changeset

None — docs-only, nothing published moves. skip-changeset label applied.

Generated by Claude Code

…no binder slot

Adds a "Secret-shaped keys with no binder slot: accepted at-rest risk"
subsection to the database drivers guide, naming the five keys the datasource
secret binder has no slot for -- mongo's options.proxyPassword,
options.tlsCertificateKeyFilePassword, options.key, options.passphrase, and
turso's encryptionKey. States plainly that they are writable and stored at
rest in sys_metadata as plain text, that read-side redaction (#9040, shipped)
is the only protection today, and records the restart condition: the first
real deployment needing an authenticated SOCKS5 proxy or a passphrase-
protected key converts this into the binder-slot programme (Option A).

Maintainer ruling 2026-08-17 03:19Z (issue comment 5311378700): Option B,
accept-and-document. No runtime code changed; Option A (binder slots) and
Option C (publish-door refusal) stay explicitly out of scope.

Fixes #9124
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Aug 17, 2026
@os-project-manager os-project-manager added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 17, 2026 — with Claude
@os-project-manager
os-project-manager marked this pull request as ready for review August 17, 2026 08:12
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 17, 2026
Merged via the queue into main with commit 2d11ddb Aug 17, 2026
27 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-9124-mongo-passthrough-at-rest-doc branch August 17, 2026 08:30
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 17, 2026
…two claims objectstack-ai#17328 falsified are gone (objectstack-ai#18492)

Fixes objectstack-ai#17670

Clause-②: yes

objectstack-ai#17328 established, by browser measurement in Chromium at three surface
widths (390 / 720 / 1700), that two shipped sentences are false. This PR
removes them from the six carriers in range and states each key's
measured behaviour instead. It invents no replacement guidance and takes
no side between the two keys.

**Round 2 — remediation.** The isolated contract review of head
`419e3173cf` returned FAIL: the replacement text was measured at the
`.objectui-sha` pin only and asserted timelessly, and it is false on
objectui's `main`. Every carrier now says what the key **resolves to** —
true on both renderer states — and anchors the **tier** behaviour to a
named commit.

## The renderer has two states, and the first round only saw one

Re-derived here, not taken on trust: both implementations were extracted
from the real git blobs at each commit and executed. `resolveColSpan`
(`packages/plugin-form/src/autoLayout.ts`) is byte-identical at both, so
the only difference is which classes the form renderer emits.

| probe, 3-column grid (`grid-cols-1 @md:grid-cols-2 @2XL:grid-cols-3`)
| effective span | at the pin `53ded82bf7` | at objectui `main` |
|:--|:--|:--|:--|
| `span: 'full'` | 3 | `@2xl:col-span-3` | `@md:col-span-2
@2XL:col-span-3` |
| `colSpan: 4` | 3 | `@2xl:col-span-3` | `@md:col-span-2
@2XL:col-span-3` |
| `colSpan: 2` | 2 | `@md:col-span-2` | `@md:col-span-2` |
| `colSpan: 1` | 1 | (no class) | (no class) |

The pin column reproduces objectstack-ai#17328's measured table exactly — the same
emitted classes it recorded in Chromium at 390 / 720 / 1700. So the
claims "emits it as **one** container-query-scoped span class" and
"gated at the top breakpoint only … identical to omitting the key at
every narrower width" are true **at the pin** and false ahead of it.

⭐ **And this is why it is more than staleness.** The objectui fix's own
docblock, its two pin tests and its changeset quote the sentence round 1
**deleted** — "whole row at any column count" — as *the published
declaration they implement*. Its commit message says so outright: "That
is the spelling `@objectstack/spec` (17.4.0) declares as 'whole row at
any column count' … so the contract is published and the renderer was
not keeping it. Fixed in the renderer rather than by relaxing the
declaration." Landing round 1's text would have rewritten the contract
to codify the behaviour that fix had just corrected against it.

## ⚠️ A correction to the review record's own citation

The review named the renderer-side fix **`objectui#9244`, commit
`5e9b502fa4`, 2026-09-13**, and said one commit since the pin touches
`form.tsx`. Measured on a full (un-shallowed) objectui clone:

- `5e9b502fa4` is **`fix(plugin-dashboard): compose a chart series label
in DashboardGridLayout (objectstack-ai#9402)`** — plugin-dashboard only, nothing to do
with form spans.
- The span-ladder commit is **`bd09957380`**, `fix(form): emit one
col-span class per breakpoint tier, not one for the widest (objectstack-ai#9253)`,
**2026-09-12**, whose trailer reads `Part of objectui#9244`. It is the
commit that introduces `spanLadderFor` and ships
`.changeset/span-full-tier-ladder-9244.md` and the two `-9244` pin
tests.
- `packages/plugin-form/src/form.tsx` does not exist; the renderer is
`packages/components/src/renderers/form/form.tsx`, and **7** commits
since the pin touch it, not 1.
- `objectui#9244` itself answers **404** over the API, while
`objectui#9253` resolves (merged 2026-09-12T06:24:38Z).

So the published prose cites the **verifiable** pair — `objectui#9253` /
`bd09957380` — and the changeset records `part of objectui#9244`, which
is the spelling objectui's own tree uses. Substance of the review's
probe table: confirmed independently, above.

⚠️ `git merge-base --is-ancestor PIN origin/main` answered **exit 1** on
the shallow clone this container ships and **exit 0** after `git fetch
--unshallow` (control leg, a commit five back from the pin: exit 0 both
times). The shallow negative was a false negative.

## Carriers, and what each now says

| # | carrier | now |
|:--|:--|:--|
| 1 | `view.zod.ts` — `.describe()` on `FormField.colSpan` | clamped to
**the form grid's** current column count; `colSpan: 4` in a 3-column
grid renders as 3; `colSpan: 1` emits no span class. No tier claim — the
clamp holds on both states. |
| 2 | `view.zod.ts` — `.describe()` on `FormField.span` | `'full'`
**resolves to the form grid's full column count**; how far down the
container-query tiers that span is emitted is stated as the renderer's,
anchored at the pin. |
| 3 | `view.zod.ts` — TSDoc above `span` (carrier the card's table
missed; it ships in `dist`, ×30) | same shape, plus the forward pointer
to `objectui#9253` / `bd09957380` and a "re-read at the pin bump"
instruction. |
| 4 | `content/docs/references/ui/view.mdx` | **regeneration only** —
`check:generated --fix`, never hand-edited. |
| 5 | `content/docs/ui/views.mdx` | `:434` comment and the `span` row.
The `colSpan` row at `:450` was already right on both states and is
unchanged. |
| 6 | `content/docs/protocol/objectui/layout-dsl.mdx` | "Custom Span
Widths" prose. The `:223` callout was already right and is unchanged. |

**The span is the form grid's column count** — the explicit form
`columns`, else the widest section's `columns`, else inferred — not "the
section's declared column count". Those coincide only in a
single-section form, which is what objectstack-ai#17328 measured.

## ⛔ The pin is deliberately not moved

`.objectui-sha` stays at `53ded82bf7`. The ladder is **unreleased**:
`@object-ui/components` is `17.6.0` at both the pin and objectui HEAD,
and `git tag --contains bd09957` returns **0** tags. A pin bump is
not a rider on a prose PR. This text anchors the pin; it does not move
it.

## Counts, both sides, with controls

⚠️ **The table below is round-2 vintage, measured at `a3dd4bbd4a`; the
clause it counts was replaced in round 3 — see the round-3 section at
the end for the counts at the current head.** Whitespace-normalised
occurrence counts, so a phrase wrapped across comment lines cannot read
as a false zero (the failure mode that made the card's own carrier table
miss carrier 3). Measured at `a3dd4bbd4a` after the final build and
regeneration.

| spelling | src | `dist` | `json-schema` | generated `view.mdx` |
`views.mdx` | `layout-dsl.mdx` | changeset |
|:--|:--|:--|:--|:--|:--|:--|:--|
| OLD `gated at the top breakpoint only` | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| OLD `emits it as one container-query-scoped span class` | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
| OLD `section's declared column count` | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| OLD `it is not a whole row at every column count` | 0 | 0 | 0 | 0 | 0
| 0 | 0 |
| NEW `resolves to the form grid's full column count` | 2 | 60 | 22 | 2
| 1 | 1 | 1 |
| NEW `form grid's current column count` | 1 | 30 | 22 | 2 | 0 | 0 | 0 |
| NEW `.objectui-sha pin 53ded82` (the gate's historical spelling) |
2 | 60 | 22 | 2 | 0 | 0 | 1 |
| NEW `objectui#9253` | 1 | 30 | 0 | 0 | 1 | 1 | 1 |
| **lit control** `colSpan` | 4 | 852 | 88 | 8 | 1 | 2 | 5 |
| **dark control** `zzz-no-such-token` | 0 | 0 | 0 | 0 | 0 | 0 | 0 |

`objectui#9253` reads 0 in `json-schema` on purpose: that surface
carries `.describe()` strings only, and the forward pointer lives in the
TSDoc. The TSDoc reaching `dist` ×30 is the measured reason carrier 3 is
not "source-only".

`check:generated` found **exactly one** of 15 artifacts stale
(`content/docs/references/**`) and `--fix` moved only that one;
`check:generated` re-runs green, 15/15 current.

## Verification

Exit codes captured by redirect-then-`$?`, never through a pipe. Heavy
runs through `scripts/pm/os-verify-lock.sh`; the verdict quoted is the
wrapper's own `VERDICT command-exit` line.

- `pnpm --filter @objectstack/spec build` → **exit 0** (twice; the
second after the describe edit below).
- `pnpm --filter @objectstack/spec test` → **exit 0** — `Test Files 483
passed (483)`, `Tests 13773 passed (13773)`.
- `pnpm --filter @objectstack/spec typecheck` → **exit 0** (`tsc
--noEmit`, `check:scripts-typecheck`, `check:test-typecheck`).
- `pnpm --filter @objectstack/spec check:generated` → **exit 0**, 15/15
current.
- `pnpm --filter @objectstack/spec check:objectui-pin-citations` →
**exit 0** (R9): 26 asserting citations match `.objectui-sha`, 38
historical recorded — the two new historical citations parse in the
recognised spelling.
- `check:docs`, `check:authorable-surface`, `check:api-surface`,
`check:doc-anchors`, `check:doc-authoring`,
`check:docs-spec-enumerations`, `check:docs-single-h1`,
`check:quick-reference-counts`, `check:objectui-changeset`,
`check:docs-audit-scope`, `check:doc-frontmatter`,
`check:spec-docblock-symbol-anchors`, `check:adr-0087-registration`,
`check:changeset-no-major`, `check:empty-changeset`,
`check:closing-keyword-parity`, `check:nul-bytes` → all **exit 0**.
- `pnpm lint` (repo-wide `eslint . --no-inline-config`) → **exit 0** at
`a3dd4bbd4a`, 16:57:58Z–16:59:42Z. Not narrowed; the union ran at the
final commit.
- `node scripts/pm/check-clause2-carriers.mjs --pair 18492` → **exit
0**, both carriers agree. ⚠️ **Round-2 vintage.** After the at-tier
FAIL, the seat cleared the gate from both carriers (that is what a FAIL
does), the head moved twice, and the gate was re-hung on both carriers
at 2026-09-16T19:24:04Z. Between the clear and the re-hang the same
command read exit 4, naming exactly that state. Re-read it rather than
quoting this line.

⚠️ **One red, and it falsifies the review's R2 string.** R2 prescribes
ending the `span` describe with `(objectstack#17328, Chromium at
390/720/1700)`. `check:doc-authoring` reds that: an internal issue id in
customer-facing `.describe()` prose, which projects into
`content/docs/references/**` and the generated skill artifacts, whose
readers have no tracker to resolve `#NNNN` against. Per the gate's own
guidance the parenthetical keeps the measurement and drops the
citation-shaped token; the anchor stays one line above in the TSDoc,
where the gate puts internal references. Control: no other `.describe()`
in `view.zod.ts` carries an issue id (0). The gate is green after the
change.

**NOT MEASURED**, stated rather than assumed green: the remaining
families in `dispatch-gates --commands` (102 commands at this change
set) beyond those listed, the 50 artifact-roster families whose silence
is a fact about a list, the 11 declared-wide families, the 5 families
taking a value from the workflow, and the 6 path-scheduled CI jobs.
Those are CI's run. `dispatch-gates` also warns this branch is ≥10
commits behind `origin/main` and that 6 gate scripts it derives from
changed in that range — the derivation read the branch's older copies.

## Changeset

`@objectstack/spec: minor`, unchanged. Its two bullets now match the
carriers, and the sentence claiming the renderer question "is not
answered today" is replaced by one naming `objectui#9253` / `bd09957380`
and its unreleased status. Nothing an author writes moves: both keys
unchanged, both still parse, no validation, default or emitted class
changes.

## Acceptance notes

Out of this PR's scope; nothing here is filed by this PR.

1. **`skills/objectstack-ui/rules/navigation.md:139`** still carries the
falsified prescription. Governed surface, already filed as objectstack-ai#18496 by the
seat — carried, not re-filed.
2. **`examples/app-showcase/src/ui/views/task.view.ts:363-366`** carries
the same claim plus the withdrawn lint rule; it escapes a line-oriented
grep because the phrase breaks across a comment line. Noted, not filed —
successor to the same routing round as objectstack-ai#18496, which already records it.
3. **`check:cross-package-test-inputs`** fails locally whenever
`packages/spec/dist` exists and is structurally dormant in the CI job
that runs it. Already carried by objectstack-ai#18348 since 01:51Z; objectstack-ai#18495 is a
probable duplicate. ⛔ Not re-filed here — the seat holds the dedupe.
4. **`content/docs/protocol/objectui/layout-dsl.mdx:846`** lists a
`FormField` interface with `colSpan` and no `span`. Incompleteness, not
an error — copying it does not fail. Noted, not filed; successor:
whoever next edits that interface block.
5. **The spec/objectui contract will need reconciling at the pin bump
that absorbs `bd09957380`** — carrier 3's TSDoc says so in-place, which
is the only durable channel prose has. Dedupe words: `spanLadderFor`,
`objectui#9253`, `span-full-tier-ladder`, `top breakpoint only`.

## Maintainer note on the label

`needs:contract-review` is the seat's to hang on both carriers. This
branch does not hang, strip or wait on it. Its presence is a moving
state, not a fact this body can assert: the seat hung it, cleared it
from both carriers on the at-tier FAIL, and re-hung it on both at
2026-09-16T19:24:04Z when the remediation push landed. ⛔ Do not read
this section as a claim about the label's current state — read the
labels.

---

## Round 3 — remediation of the at-tier FAIL

The at-tier contract review of head `a3dd4bbd4a` returned **FAIL** on
one clause, and only that clause. Record:
objectstack-ai#18492 (comment)
· handover with R1-R5:
objectstack-ai#17670 (comment)

**The defect.** "so at intermediate widths the field rendered
identically to omitting the key" is FALSE at the `.objectui-sha` pin
`53ded82bf7` in a reachable configuration: form grid 3 with a section
`columns: 2` — a plain field with `span` omitted resolves to eff 2
(`round(3/2)`) → `@md:col-span-2` → 2 of 2 cells at 720px, while `span:
'full'` at the pin → `@2xl:col-span-3` → 1 of 2 cells. Not identical,
and `'full'` is the narrower one. The identity holds only in the single
3-column section objectstack-ai#17328 measured.

**What changed — three exact string replacements, nothing else.** The
`span` describe (`view.zod.ts:2622`), the TSDoc above it (`:2616-2617`,
the carrier that wraps across two comment lines), and the changeset
bullet. Each OLD string was verified uniquely present in the HEAD blob
before replacement, and the edited tree was proved byte-identical to
HEAD-plus-exactly-those-three-replacements — no near-miss, no drive-by
edit. Nothing the record called RIGHT was touched.

**Counts at the head this PR now carries, both sides.** Occurrences (not
lines), wrap-tolerant, over `packages/spec/src` · `packages/spec/dist` ·
`packages/spec/json-schema` · `content/docs/references`:

| string | src | dist | json-schema | generated docs |
|---|---|---|---|---|
| OLD "identically to omitting the key" | 0 | 0 | 0 | 0 |
| NEW "a single cell, not the row" | 2 | 60 | 22 | 2 |
| lit control `colSpan` | 131 | 852 | 88 | 8 |
| dark control `zzz-no-such-token` | 0 | 0 | 0 | 0 |

**Regeneration.** `check:generated --fix` reported exactly 1 of 15
artifacts stale and moved only `content/docs/references/ui/view.mdx` (2
rows, both the span row). Then, all exit 0: `check:generated`,
`check:docs` (223 generated files in sync), `check:doc-authoring` (8619
describe strings clean), `check:objectui-pin-citations` (26 asserting
citations match `.objectui-sha`, 38 historical recorded),
`check-changeset-no-major`, `check-empty-changeset`,
`check-adr-0087-registration`, `check:nul-bytes`, plus 40 further
derived gate invocations.

**The item the review left NOT MEASURED is now measured.** `pnpm
--filter @objectstack/spec test` → exit 0, 483 test files / 13773 tests
passed.

**Two gates refused a verdict rather than false-greening** —
`check:docs-transcript-drift` (exit 3, PREREQUISITE NOT MET) and
`check:skill-examples` (exit 1) both need a built dependency. Their
prerequisites were satisfied and both then re-ran exit 0. ⛔ Neither was
recorded as a red.

**One intermediate red, accounted for.** The WIP push `d341967995`
failed `Type Check · source gates`. Despite the job's name the failing
step was **`check:docs`** — the generated projection had not been
regenerated yet — and the job's own "Type check (@objectstack/spec)"
step PASSED on that same head. Reproduced locally by restoring the stale
projection (mutation proved on disk, then restored, `git diff HEAD`
empty). It is gone on the current head: `Type Check · source gates` and
`TypeScript Type Check` both success.

**CI on this head**, latest run per check NAME: 35 names — 33 success, 2
skipped (`Console Pin Gate`, `Packed-tarball smoke (opt-in)` — NOT
MEASURED, not verdicts), 0 failure, 0 cancelled.

A fresh at-tier review is owed on this head: the FAIL record named an
older one, and a record that does not name the current head cannot land
it.

---
_Generated by [Claude Code](https://claude.ai/code)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants