Closes #347.
Until now, g1t work close N --commit SHA only accepted a commit whose message already said Fixes #N. Such a commit closes the item by itself when it lands, so the after-the-fact close never worked (#339 hit this).
What an explicit close with a commit accepts (closing_commit, decided by the pure function tie()):
- Named: the commit's message names the item after a closing keyword (unchanged).
- Merged: a merged PR whose
merge_commitis this commit names the item, through its own work item, its storedclosesorparts, or its current title and description. - By hand: nothing names the item, but the person has Write on the repository.
- Anything else is refused with 403, which says that tying a commit by hand takes Write.
The default-branch check and its drift logic are unchanged (still 422). Automatic closing from pushes and merges still needs a keyword. The new Landing.tie field is set only on this path.
The timeline says how the commit was tied: "…, which names it", "…, which merged acme/web#14" or "…, tied by hand: the commit does not name it".
Tests cover:
- the
tiedecision for each case, with and without Write; on_branch;- the note wording;
- the
MERGED_ASSQL run against the migrated schema.
The docs updated are the closing guide, work/agents.md, the CLI help, the API operation and parameter, reference.json and the MCP instructions. The CLI reference and OpenAPI are regenerated.
Validation: cargo test passes for g1t-work, g1t-contracts, g1t-api and g1t; the workspace and wasm32 checks pass; astro, prettier and git diff --check are clean.