Repository navigation
revertCommit cannot restore an object overlay at all — it passes no write intent, so restoreVersion defaults to override-artifact and the repository answers NOT_OVERRIDABLE #6563
Description
Activity
Triage:
pm:queue+domain:metadata+target:v17.- Classification: concrete defect with a measured repro (
revertedCount: 0,failedCount: 1on a realSysMetadataRepositoryover an in-memory double) ⇒ queue. - Landing anchors verified on
origin/main@f549a0d(not a worktree):packages/metadata-protocol/src/protocol.ts:10109-10113— therevertCommitrestoreVersion call passesactor/source/messageand nointent;packages/metadata-protocol/src/sys-metadata-repository.ts:698/:768/:1267—intent: opts.intent ?? 'override-artifact'default; the siblingrollbackMetaItemderivesartifactBackedinstead (protocol.ts:2340 family), exactly as the body states. Line numbers in the body drifted (main was force-updated since filing); everything re-located by content. - Routing: fix lands in
packages/metadata-protocol⇒domain:metadataper the domain table. - Dedup: repo-scoped search for
revertCommitfinds only rollbackMetaItem / revertCommit always 409 on a package-bound overlay row — restoreVersion's put() scopes the parent lookup topackage_id IS NULL#6215 — samerestoreVersioncall site, different cause (package scoping vs missing intent; the body itself draws the line). Not a duplicate. No shadow in objectui/cloud. target:v17grounds ①: shipped package-commit undo (ADR-0067) silently fails forobjectitems — the type Studio/AI-built apps edit most — and reports overallsuccesswith a populatedfailed[], so it reads as flaky rather than systematic. Maintainer may strike.- Serialization note for the metadata lane: rollbackMetaItem / revertCommit always 409 on a package-bound overlay row — restoreVersion's put() scopes the parent lookup to
package_id IS NULL#6215 ispm:dispatchedon the samerestoreVersioncall region right now — land rollbackMetaItem / revertCommit always 409 on a package-bound overlay row — restoreVersion's put() scopes the parent lookup topackage_id IS NULL#6215 first. File collision, not substance, so noBlocked-by:.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Classification: concrete defect with a measured repro (
Claim: PM loop round 4 (
domain:metadataseat, sticker #6367)
Session:session_01KDU3qAuJyajAQm3GkUXdfA
Branch:claude/issue-6563-revert-commit-write-intent
Worktree:objectstack-issue-6563
Domain:domain:metadata
File surface:packages/metadata-protocol/src/protocol.ts— therevertCommitrestore limb (per-item intent derivation, therollbackMetaItemidiom) — + tests (the #6215 pin files inpackages/objectqlare the natural home:protocol-commit-history.test.tsalready drivesrevertCommitagainst the real repository). Stop on breach; explain in the report.
Serial constraints cleared: the triage serialization note said "land #6215 first" — PR #6574 MERGED 06:11Z; the other protocol.ts in-landing PR #6600 MERGED 07:1xZ (loadMetaFromDb region — different limb, now on main); #5839 (engine-core seat) still holds its claim on the ensureOverlayIndex region with no remote branch — no overlap with the revertCommit limb, merge-main discipline applies; #6479 (same file, updateData region) deliberately held for the NEXT slot — never same-batch with this card.
Container class: M —mode:subagent, shared container.
Generated by Claude Code
ACCEPT (PM review,
domain:metadataseat, sessionsession_01KDU3qAuJyajAQm3GkUXdfA) — PR #6642, now ready + queued.Shipped:
revertCommit's restore limb derives the write intent per item (isArtifactBacked→override-artifact, elseruntime-only), exactly asrollbackMetaItemdoes; the repository's?? 'override-artifact'default is untouched per the ruling, so the gate is stated rather than widened — the artifact-backed refusal is pinned alongside the fix and still answersNOT_OVERRIDABLE.Review verified against GitHub: 3 files exactly on the claimed surface (changeset,
protocol.ts+28 confined to the restore limb, the #6215 pin suite extended in place); ESLint and TypeScript Type Checkcompleted: success, 24 checks zero failures; patch changeset present. Reverse verification 4-red/13-green in the predicted direction, and therollbackToPackageCommitcase correctly asserts the stored body rather thansuccess— becausesuccess: truewas already true on the defect, so a status assertion would have been green on it. That is the right instinct and worth naming.Two caveats reported honestly rather than papered over, both accepted:
- The dispatch asked for "the restored registry state carries the right body" — measured not true today for any type (
revertCommithas no registry write-through), so the pins assert the persisted row instead of manufacturing the claim. Filed as A successfulrevertCommitnever refreshes the SchemaRegistry — the runtime keeps dispatching the reverted-away body until restart (the #4521 rule, missing on the batch path) #6621. - The sibling soft-remove limb hard-codes
override-artifact, so a commit that created an object still cannot be reverted — measured identical before/after, left untouched per the restore-limb-only surface. Filed as revertCommit's soft-remove limb hard-codesintent: 'override-artifact', so a commit that CREATED an object cannot be reverted either #6620.
Both are on the lane's handoff ledger (seat sticker #6367) as the natural next cards on this seam.
The issue closes on merge via the
Fixesline.
Generated by Claude Code
- The dispatch asked for "the restored registry state carries the right body" — measured not true today for any type (
Found while implementing #6215 (the package-scoping half of the same call). Recording only, per Prime Directive #10 — it is a different cause on a different line, outside that issue's ruled file surface.
Evidence
ObjectStackProtocolImplementation.revertCommit(packages/metadata-protocol/src/protocol.ts, theexistedBeforelimb) restores an edited artifact with:No
intent.SysMetadataRepository.restoreVersiontherefore defaults tointent: opts.intent ?? 'override-artifact', andputopens withassertAllowed(ref.type, opts.intent), which refuses any type whose registry entry is notallowOrgOverride.objectis exactly such a type, so everyobjectitem in a reverted commit comes back infailed[]:Measured on a real
SysMetadataRepositoryover an in-memorysys_metadata/sys_metadata_historydouble while writing #6215's pin tests: anobjectsaved twice throughsaveMetaItemand then reverted throughrevertCommitreturnsrevertedCount: 0,failedCount: 1with that message. Package binding is irrelevant — a package-less object fails identically.Why the sibling caller works
rollbackMetaItemderives the intent instead of defaulting it:A runtime-created object (
_provenance: 'org', the shape Studio's package workspace produces) is not artifact-backed, so the per-item rollback passesruntime-onlyand the same repository line admits it.revertCommitnever computes that, so the two user-facing revert paths disagree about what is revertable — for the metadata type Studio creates most.Why it matters
revertCommitis the package-commit "undo" (ADR-0067). A commit that edited an object — the common case for an AI-built or Studio-built app — reports partial failure and leaves the edit in place, while the same edit reverts fine one artifact at a time through the version-history revert. The failure is per item, so the revert also reportssuccessoverall with a populatedfailed[], which reads as a flaky revert rather than a systematic refusal.rollbackToPackageCommitreverts through the same loop, so it inherits this.Suggested direction (not a ruling)
Compute the intent from the artifact the same way
rollbackMetaItemdoes, rather than defaulting it at the repository — the repository's default is right for callers that genuinely mean "override an artifact", and the bug is that this caller never states which of the two it is. NoterevertCommitreverts a batch, so the intent is per item, not per call.Related: #6215 (the package-scoping defect on the same
restoreVersioncall; its pin tests useviewprecisely becauseobjectcannot reach the scoping line), ADR-0067, ADR-0048.