Skip to content

[Decision digest] maintainer inbox — generated view (please pin) #9822

Description

@os-support-ai

Generated view — not a second tracker. Authority lives on each card (one-board rule); this body is refreshed by the triage-seat Routine each round from a label query (needs-user-decision, all repos in scope) + literal-text extraction of each card's os-decision-facets block. Edit history = archive. Batch adjudication: reply in ONE comment below with one pair per line, each pair spelled like #9807 B (card number, space, option letter); the triage seat transcribes each ruling back onto its card citing your comment as provenance. (Standing per the 2026-08-18 ruling: standard block, pinned digest, batch channel — 「同意」.)

Last refresh: 2026-08-19 ~11:2xZ, session session_015BAKXkmpGhLRSys9AjNZMX. Current inbox: objectstack 7 (+#9968, +#9952 new this round; +#9617 re-entered by the skills seat — see its provenance note), objectui 1, objectos 5. Total 13. Cards with open downstream dependents: objectos#68 (← objectos#135, and via the chain objectos#75).


objectstack #9968impersonate_user / set_user_role still 403 every platform admin; neither vendor route is safely raw-mountable (auth/session boundary + ADR-0068 Option-3 veto tension)

Recommendation: B (retire set_user_role; for impersonate_user, measure the plugin-endpoint override question first, then re-implement as a better-auth plugin endpoint or retire) · A = status quo (dead buttons, fails closed) · C = re-implement set-role with a vendor-excluding vocabulary + plugin-endpoint impersonate.

<!-- os-decision-facets -->

  • platform long-term coherence: Retiring set_user_role (B) shrinks the retired dual-identity surface — ADR-0068 moved platform-admin membership to sys_user_permission_set, and a supported UI writer for the legacy scalar re-grows exactly that contract. For impersonation, a better-auth plugin endpoint (not a raw Hono mount) is the only shape that keeps the signed-cookie contract with /admin/stop-impersonating and the better-auth bearer plugin lets a bearer session silently shadow an impersonation the server just created — /admin/impersonate-user returns 200 and is a no-op for any bearer client #8243 rotation hook attached.
  • measured business pull: Both buttons are measured broken today (byte-identical 403 for admin and plain member). But nothing measured pulls for set-role's only effect — writing the vetoed scalar; impersonation is a real admin-support workflow, though no usage telemetry exists.
  • AI-agent error-resistance: A raw re-implementation must hand-roll better-auth's signed-cookie format — a subtly wrong signature is a broken exit path or a forgeable cookie, and the detached path-keyed hook re-introduces better-auth bearer plugin lets a bearer session silently shadow an impersonation the server just created — /admin/impersonate-user returns 200 and is a no-op for any bearer client #8243 with no failing test. Removing the set-role text box removes a one-user-at-a-time resurrection channel for the dual identity.
  • startup scope discipline: Remove beats declare-and-maintain for set-role. For impersonate, the cheap first step is the unmeasured probe (checkEndpointConflicts override behaviour), not a commitment to re-implement.
    Confidence gap: this analysis cannot see whether any real deployment relies on impersonation (zero usage telemetry), and the plugin-endpoint conflict behaviour on better-auth 1.7.1 is explicitly unmeasured — if the probe fails, the impersonate half of B collapses back into A vs. a much more expensive path.

objectstack #9952 — [field report] rc→GA envs: package-declared permission sets frozen at first-boot snapshot; provenance skip is silent, no adoption/migration path (stored-data migration shape)

Recommendation: B (explicit operator command, e.g. os meta adopt-permission-sets, + surface the skip in Setup) · A = boot-time auto-adoption + surfacing · C = document SQL remediation only.

<!-- os-decision-facets -->

  • platform long-term coherence: The env-authored protection is sound; the defect is the platform's own historical rows landing in that bucket with no exit. A one-time adoption path restores the [cli/plugin-security] dev 元数据物化不一致:默认权限集 insert-if-not-exists 不重物化(声明集走 upsert) #2705 reconcile intent without weakening provenance; leaving it means "declared = enforced" is permanently false for every rc→GA env.
  • measured business pull: Production field report, measured on a live env — grants shipped after first boot return 403 to real users, remediation today is raw SQL. Every env upgraded along the same rc line is affected.
  • AI-agent error-resistance: The current failure signal is a log counter — the exact silent-tolerance shape that lets drift run for weeks. Surfacing the skip loudly (Setup badge/warning on the set) is the contract-tightening half and looks safe under every option.
  • startup scope discipline: Keep it a narrow, one-time adoption keyed on name-match + provenance-predates-scheme; do not build a general reconciliation framework.
    Confidence gap: cannot see how many envs sit on the rc→GA line, nor whether any genuinely admin-authored set shares a package set's name in the wild — the collision likelihood is what would flip B to A.

objectstack #9930 — retire the legacy sys_webhook.definition_json.headers cleartext read path (stored-data migration + accepted-input removal)

Recommendation: A (three-step retirement: measure population → boot-sweep migration into headers_secret → flip readLegacyHeaders to loud rejection; migration isolated in its own flagged PR) · B = migrate but keep warn-and-accept · C = leave as-is.

<!-- os-decision-facets -->


objectstack #9901 — federation datasource routes admit any authenticated caller while the admin twin now requires a capability (security boundary; two WRITE routes included)

Recommendation: A (manage_platform_settings on the read twins per #9593; manage_metadata on the write routes import/refresh-catalog; fold the equivalence-test divergence row back) · B = mirror #9593 exactly, no read/write split · C = rule the federation family deliberately lower-privilege and document it.

<!-- os-decision-facets -->


objectstack #9885sys_position.permissions is a declared "JSON-serialized array of permission strings" column with zero producers and zero readers (enforce-or-remove)

Recommendation: A (REMOVE via the ADR-0049/ADR-0087 retirement flow, incl. the clone_position copy entry and docs riders; objectui designer-preview check folded into the retirement checklist) · B = enforce (design position-level direct grants — a real security feature, only on real pull) · C = leave declared-and-inert.

<!-- os-decision-facets -->


objectstack #9864 — duplicate plugin registration: LiteKernel throws, ObjectKernel silently overwrites (fourth two-kernel semantic split; #9863 rides the overwrite)

Recommendation: A (converge on refuse-loudly in both kernels + an explicit supersede spelling for #9863's config-over-CLI case, pinned dual-kernel) · B = converge on overwrite-with-warning · C = declare the kernels intentionally different and document it.

<!-- os-decision-facets -->


objectstack #9617 — checklist-test's documented QA-run title convention matches 0 of 23 real records (governed-surface contract; ⚠️ has a recorded ruling AND a revert — see provenance)

Recommendation: 2, new-records-only (one canonical title shape, strict parser, no migration of the 23 records) · 1 = document bends to measured reality. Provenance: comment 5334893052 (08-18 22:31) recorded Option 2 as ruled via the live-chat batch acceptance 「其他接受你的建议」; the skills seat (comment 5340733624, 08-19 10:19) re-entered it for an explicit per-card verdict. A one-word confirm resolves it.

<!-- os-decision-facets -->

  • platform long-term coherence: a documented convention matching 0 of 23 real records is declared≠enforced in the agent-instruction layer; only direction 2 (one canonical shape, strict parser) prevents recurrence.
  • measured business pull: real and current — PR tooling(qa): roll-up view over qa-run records — selector, latest verdict, staleness #9616's roll-up parses these titles today and had to be written against the measured shape, not the documented one.
  • AI-agent error-resistance: one emitted shape + a strict parser that prints what it cannot read makes deviation loud on first occurrence; canonizing five phrasings is the tolerant-consumer shape that hides authoring errors.
  • startup scope discipline: direction 2 with new-records-only costs one SKILL.md edit and zero migration; the "Not parsed" roll-up section already exists as the enforcement surface.
    Confidence gap: none material on substance — the open question is provenance, above.

objectui #5301 — WidgetConfigPanel's resolveLabel reads only the RETIRED label form; opening the panel on a locale-map title shows EMPTY and a save writes '' over the author's map

Recommendation: A (display via pickLocalized; un-edited fields round-trip byte-for-byte; an edit writes the active locale's map entry, preserving other locales; map-editing UX stays a future card) · B = read fix + lossy collapse-to-string on edit · C = full multi-locale editing UI now.

<!-- os-decision-facets -->

  • platform long-term coherence: fourth private copy of the retired-form resolver (fix(runtime,rest): advertise mcp only when it is actually serveable #4032 swept three); whichever write-back rule is chosen should be stated once and shared, not re-derived per panel.
  • measured business pull: the destructive path is the ordinary one — open a widget whose title is an inline locale map, change anything, save ⇒ the author's map is replaced by ''. Studio authors hit this on every map-titled widget today.
  • AI-agent error-resistance: an editor that silently collapses a multi-locale map to one string (or to empty) destroys data with no failure signal; write-back-only-the-edited-locale keeps saves idempotent for untouched fields.
  • startup scope discipline: a full map-editing UI is the expensive road; the minimal honest fix needs no new UI.
    Confidence gap: not checked whether the dashboard save path round-trips unknown keys untouched or rebuilds config from the draft — decides whether A needs a diff mechanism.

objectos inbox (5 open — options and recommendations on the cards; standard facet blocks pending backfill, a low-frequency sub-round item)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions