git-ents.gitmain
⌘K
foforge
commit c176d17
spec: pin reviewed content with a second ref per review

A data field cannot keep the reviewed commit alive; the pin ref can. Each re-review advances the pin fast-forward with a merge-shaped signed commit, retaining every reviewed round as its own audit trail.

spec: require the refs/meta/pins/reviews/<id> retention pin (model.review-pin) spec: exempt refs/meta/pins/* from the tree-is-the-entity shape Assisted-by: Claude:claude-fable-5

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

docs/development-plan.adoc @@ -223,7 +223,11 @@ `model.comment-thread`, `model.review`): the Comment struct's migration (`meta-ref.migration` — old trees must stay readable), working-tree capture and projection in `ents-anchor` (`anchor.working-tree`), the - Review entity, and porcelain — `comment reply/resolve/reopen`, + Review entity plus its retention pin ref (`model.review-pin` — + `refs/meta/pins/reviews/<id>`, an empty-tree signed commit whose + parents include the reviewed commit; verify the gate's tip-signed and + fast-forward checks accept the merge-shaped pin advance), and + porcelain — `comment reply/resolve/reopen`, `comment list --worktree` with a machine-readable form (`lens.parity`), `issue` and `review` actions.
docs/spec/meta-ref.adoc @@ -21,6 +21,9 @@ synchronization (fetching or pushing the ref moves exactly that entity), authorization (refname-keyed rules gate who may advance it), and history (its commit chain is the audit trail). +Retention pins under `refs/meta/pins/*` (<<model.review-pin>>) are the +sole exception: a pin's commits anchor other content's reachability and +carry the empty tree, never an entity. -- [role="requirement", id="meta-ref.granularity"]
docs/spec/model.adoc @@ -162,13 +162,17 @@ .Review Is a Verdict Plus a Context -- A Review entity MUST be a typed tree under its own ref in -`refs/meta/reviews/*`, one ref per review (<<meta-ref.granularity>>), +`refs/meta/reviews/<id>`, one ref per review (<<meta-ref.granularity>>), written, gated, synced, and audited exactly like a comment. -A Review MUST carry the reviewed commit's id as a plain data field — -best-effort reachability, the same stance <<anchor.immutable>> takes for -an anchor's commit — a verdict, and a body; `approve` and -`request-changes` are conventions, not an enum, because custom verdicts -are schema, not platform features (<<model.extensibility>>). +Every review MUST occupy exactly two refs: the entity ref above, and a +retention pin at `refs/meta/pins/reviews/<id>` anchoring the reviewed +content itself (<<model.review-pin>>). +A Review MUST carry the id of the most recently reviewed commit as a +plain data field, a verdict, and a body; reading the field MUST NOT +require the pin ref — the pin anchors, the entity describes. +`approve` and `request-changes` are conventions, not an enum, because +custom verdicts are schema, not platform features +(<<model.extensibility>>). A review's discussion MUST be Comment entities naming the review as their context (<<model.comment-context>>), anchored into the reviewed code where they concern specific lines (<<anchor.definition>>); the @@ -177,6 +181,27 @@ (<<meta-ref.trailers>>). -- +[role="requirement", id="model.review-pin"] +.The Review Pin Anchors the Reviewed Content +-- +A review's pin ref, `refs/meta/pins/reviews/<id>` — the entity's own +canonical suffix prefixed the same way <<meta-ref.inbox>> prefixes one — +MUST keep the reviewed content reachable: its tip is a signed commit +authored by the reviewer whose parents include the reviewed commit, so +that commit and its ancestry survive force-push, branch deletion, and gc +for as long as the review exists. +This is the commit-level counterpart of <<anchor.retention>>, which can +embed blobs but has no reachability edge for commits — a gitlink is not +one. +Re-reviewing after the target moves MUST advance the pin fast-forward +with a new signed commit whose parents are the previous pin tip and the +newly reviewed commit, so every reviewed round stays retained and the +pin's own history is the audit trail of exactly what was reviewed, when. +A pin commit carries no entity: its tree MUST be the empty tree, the +sole deliberate exception to <<meta-ref.namespace>>'s +tree-is-the-entity shape. +-- + === Effect [role="requirement", id="model.effect-definition"]