Skip to content

spec: retire the allowRestore / allowPurge permission props (ruled 2026-08-26; M2 anchor stays open, keys return with M2) #12497

Description

@os-steve

Filed by the skills seat executing a maintainer ruling (decision-inbox batch 5, 2026-08-26, session session_01JANH3y7qe3MD8aLaLXci8N, verbatim: 「12452 不处理,其他接受」 accepting #1883's presented recommendation B). Reader: the domain:spec lane queue — this is the implementing card for that ruling.

Scope

Retire the two declared-but-unenforceable object-permission props allowRestore and allowPurge from packages/spec, following the ADR-0049 enforce-or-remove discipline and the ADR-0087 retirement flow (the spec-property-retirement playbook is the route map: removal route choice, liveness-ledger verdict confirmation, registry conversion, generated baselines/forms/docs, pin tests).

allowTransfer is NOT in scope — it is enforced and stays.

Why (from the ruling)

The operations these props claim to gate (undelete/restore, hard-delete/purge) do not exist in the platform today: no destructive lifecycle verb is in the ObjectQL operation vocabulary (pinned by packages/objectql/src/engine-middleware-operation-vocabulary.test.ts, from PR #8106). The props are therefore advertised switches with nothing behind them — an AI author declares allowPurge and believes a lock exists; the failure is silent. Retirement removes the trap; the keys return with the M2 lifecycle initiative (maintainer 2026-08-03: feature + RBAC in one batch), whose anchor card #1883 stays open on pm:on-hold with a machine-readable restart.

Day-of obligations for the implementing dev

  1. Re-measure before touching anything — the anchor card's assertions are 72+ days old and its fact surface moved once already (allowTransfer got enforced after filing). Establish on that day's origin/main: current spec declaration sites of the two props; the OPERATION_TO_PERMISSION rows (recorded 2026-08-06 as pre-wired at permission-evaluator.ts:14-24 — re-verify); any reader that appeared since. A falsified premise ⇒ stop and report, never push through.
  2. The liveness ledger decides the fate of the pre-wired evaluator rows — either they stay as deliberate dormant pre-wiring (the recorded test(objectql): prove purge/transfer/restore never reach the security AST path, and pin it (#7809) #8106 asymmetry posture) or they retire in the same batch; measured, not assumed, and the choice is stated in the PR body.
  3. Retirement of published keys follows the playbook end to end (registries, baselines, forms, docs, pin tests) — never a drive-by delete. Clause-② applies at claim time (accepting-set change on a published surface).

Executable acceptance

git grep for allowRestore/allowPurge on origin/main after landing returns only ADR-0087 tombstone/registry rows (and the M2 anchor's prose); the retirement registries and generated surfaces are regenerated by the repo's tooling; the vocabulary pin stays green.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions