Global git.auto_close authorizes the unattended GitLab publish and merge #131
Labels
No labels
already-shipped
bug
documentation
duplicate
enhancement
external-review
good first issue
help wanted
in progress
invalid
needs-decision
proposal
question
security
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: crenshawdev/cadence-archived#131
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: deep dive F1; strict re-review C-04 (independent convergence)
Verdict: AGREE - high, conditional on GitLab
Claim as reviewed
A user-global
git.auto_close=truecan authorize the unattended GitLab publication and merge path even though the stated policy and the git-publish seam require repository-local authorization.At HEAD
f354864(v3.3.0)cadence-core/bin/git-publish.mjs:65-72(repoAutoClose) reads.planning/config.jsondirectly and never the merged value, enforcing D-08.cadence-core/config.schema.json:47states the same contract.skills/cad-land/SKILL.md:23-27readsgit.auto_closethroughconfig.mjs get, which returns the merged global-plus-repo value, and a true value enters the no-prompt branch at:69-77.GitHub and Forgejo then publish through the repo-authorized seam and would stop on
ok:false. GitLab does not:skills/cad-land/SKILL.md:100-124states "On GitLabglab mr createpublishes the source branch itself, so no seam call is needed there", and the workflow proceeds toglab mr merge.cadence-core/bin/land-cleanup.mjs:126-147records the discrepancy in the source: "on GitHub the chain then died at the publish seam; on GitLab nothing gates it at all".Note
The prior narrowing (0b1c322, reverted) aligned the two seams' values and broke the skipped-ask / halt pairing that
land-cleanup.mjs gatedepends on. The fix that does not touch that pairing is to resolve two distinct booleans:autoCloseRequestedfrom the merged config (presentation, and what the gate reads),autoCloseAuthorizedfrom the repo layer only, required before any unattended external mutation on every host including GitLab.Do not re-do the reverted fix
The obvious change - narrow the land gate to
layers.reposo both seams read one value - was already made and reverted, andcadence-core/bin/land-cleanup.mjs:126-147records why in the source:The gate and the skipped publish-ask are a matched pair and must read the same value. That is not the bug.
The fix that does not touch the pairing
Two named booleans, resolved separately:
autoCloseRequested- merged config. Drives presentation and theland-cleanup.mjs gatehalt, exactly as today. Unchanged behaviour.autoCloseAuthorized- repository layer only. Required before any unattended external mutation, on every host.skills/cad-land/SKILL.mdstep 3b may enter the unattended chain on requested, but must not publish or merge on any host without authorized. Today GitHub and Forgejo get that for free because they route throughgit-publish.mjs:65-72; GitLab does not, becauseglab mr createpublishes the source branch itself (SKILL.md:100-124).Vocabulary collision with #121
#121 lands first at v3.4.0 and rewrites
/cad-landstep 1. Its naming trap section warns thatgit.auto_closealready means "merge the branch unattended" and that issue-closing vocabulary must not collide with it in this file. AddingautoCloseRequested/autoCloseAuthorizedputs moreauto_close-shaped names in the same prose. Read that section before naming anything here.Verification — live GitLab repo
John is creating a throwaway GitLab account and repo for this. That matters because the defect is in the wiring, not in a decision function: a unit test over the resolver can pass while
glab mr createstill publishes.Two cases, both walked against the live repo, neither automatable in CI:
git.auto_close: true; repo.planning/config.jsonwithout it; GitLab origin. Run/cad-land. Expected after the fix: the publish ask is NOT skipped, or the unattended arm refuses beforeglab mr create. Today: it publishes and merges.git.auto_close: true. Run/cad-land. Expected: unchanged - publishes, opens the MR, merges.Split the work accordingly: a regression test over the two-boolean resolver, and a
/cad-verifyUAT item for the live walk. The live walk performs a real merge on a real remote, so keep it to the throwaway repo.Better fix than the two hand-rolled booleans above - the provenance mechanism already exists and this path just does not use it.
cadence-core/bin/lib/config-merge.mjs:129-135 returns
layers.repoandlayers.globalalongside the merged config, for exactly this reason, in its own words: 'the merge LOSES provenance, and a key whose schemasrcisrepohas to know which file carried it. Without it a caller can only read the merged value, which is how arisk.override.<surface>written once in the user-global file waived a risk floor in every repository on the machine.'git.auto_close is already declared
src: repoat config.schema.json:47. So the schema states the constraint and the merge exposes the evidence for it. What breaks the chain is that skills/cad-land/SKILL.md:23-27 reads throughconfig.mjs get, which returns the merged value and dropslayersentirely.Compare review.key_file (
src: global), which IS enforced - a repo layer setting it is stripped at the merge and named in warnings.So evaluate this before writing autoCloseRequested/autoCloseAuthorized by hand: can
config.mjs getsurface the repo-layer value for ansrc: repokey - a flag, a second field, whatever fits the envelope - so the skill branches on provenance that already exists? That is a smaller change, it generalizes to everysrc: repokey at once, and it does not add auto_close-shaped vocabulary to the file #121's naming-trap section warns about.