Finish
a typed outcome and a contract evaluated line by line; nothing written when any line fails
a typed outcome and a contract evaluated line by line; nothing written when any line fails
Where it lives
State it owns
What implements it
Specified in
The command that acts on it
majordomus finish
Evaluate the finish contract and refuse the outcome if any line of it is unmet.
- state-mutating
- active task optional
- --json
majordomus finish --outcome <completed|partial|blocked|no_match|failed> [--verify-command "<cmd>"] [--note <file>]
See it refuse, and accept
Choose a situation and see whether the outcome is accepted or refused, and for which reasons. Every scenario here is executed against the real binary by test/cases/34_command_fixtures.sh, so this page cannot claim behaviour the tool does not have.
Given this repository
# ... and an active task scoped to lib, with work done inside that scope. . "$FIXTURE_SETUP/installed.sh" "$MJ" start "narrow the parser" --scope lib >/dev/null echo work >> lib/a
Run
$ majordomus finish --outcome completed
Output contains
- FAIL verification
- FAIL note
- refused
exit
10
Two contract lines are unmet and both are named at once. A worker who fixes one and is refused again for the next learns the contract one round trip at a time, so every cause is reported together.
Given this repository
# An active task scoped to lib, with a change made under docs that it never claimed. . "$FIXTURE_SETUP/active-task.sh" echo stray >> docs/d
Run
$ majordomus finish --outcome completed --verify-command true
Output contains
- FAIL scope
- outside claimed scope
exit
10
The task claimed lib. A change under docs is work the task did not claim, and it is refused whatever else is in place.
Given this repository
# An active task with an unresolved question open against it. . "$FIXTURE_SETUP/active-task.sh" "$MJ" question add "does the parser need to accept tabs?" >/dev/null
Run
$ majordomus finish --outcome completed --verify-command true
Output contains
- FAIL blockers
exit
10
An open question refuses completed, and only completed. The same task can be finished as blocked, which is the honest outcome when the answer is not yours to give.
Given this repository
# An active task with the note the outcome requires already written. . "$FIXTURE_SETUP/active-task.sh" printf '# Objective\no\n# Current State\nc\n# Next Action\nn\n' | "$MJ" handover >/dev/null
Run
$ majordomus finish --outcome completed --verify-command false
Output contains
- FAIL verification
- exit 1
exit
10
The command is run, not asserted. Its exit code and duration are recorded whatever it returns, so "verification ran" cannot be claimed without something having actually run.
Given this repository
# A repository with Majordomus installed and projections generated, and one commit of work. "$MJ" init >/dev/null "$MJ" update >/dev/null mkdir -p lib docs echo a > lib/a echo d > docs/d git add . && git commit -qm base
Run
$ majordomus finish --check
Output contains
- nothing to enforce
exit
0
This is why a pre-push hook can run finish --check unconditionally: a repository with no active task is not a failing repository.
Given this repository
# An active task with the note the outcome requires already written. . "$FIXTURE_SETUP/active-task.sh" printf '# Objective\no\n# Current State\nc\n# Next Action\nn\n' | "$MJ" handover >/dev/null
Run
$ majordomus finish --outcome completed --verify-command true
Output contains
- completed
exit
0
Accepted, and the ledger records the outcome together with the verification that earned it.
What enforces it
- majordomus.blocker-resolution blocking enforced by check, finish No task can be completed while any question on this branch is unresolved; it can still be finished as blocked, partial, no_match or failed.
- majordomus.verification-integrity blocking enforced by finish Completion requires a verification command that actually ran and exited 0; its exit code and duration are recorded.
- majordomus.obligation-closure blocking enforced by check, finish A task that declares obligations reaches the outcome completed only when each one is established by the tool or has evidence, and that evidence still describes the tree or the commit it was taken over.
What is guaranteed
- guaranteed finish evaluates the finish contract line by line and refuses when any line is unmetproved by test/cases/06_finish.sh
- guaranteed An outcome is a value from a closed vocabulary, not free textproved by test/cases/06_finish.sh
- guaranteed An unresolved question blocks acceptance, and an entry the gate cannot parse is a failure rather than a silent passproved by test/cases/21_decision_question.sh
- guaranteed A blocking question keeps blocking after the work is handed to a new taskproved by test/cases/50_blocker_across_handover.sh
- guaranteed A task that declares obligations reaches the outcome completed only when each one has evidence recorded against it, and evidence taken over files that have since changed, or at a commit the branch has since left, no longer discharges anythingproved by test/cases/103_obligations.sh
- guaranteed An obligation whose fact the tool can hold is established live rather than recorded — a clean tree, a remote-tracking ref that reaches the head, a trunk that reaches it, a published site that serves it — and a hand-recorded line neither discharges it nor rescues itproved by test/cases/103_obligations.sh
Rules this command runs
Doctrines whose enforced_by names finish. Enforcing a rule and being governed by one are different relations, so they are listed separately.
- majordomus.blocker-resolution
- majordomus.note-integrity
- majordomus.profile-requirements
- majordomus.scope-integrity
- majordomus.state-consistency
- majordomus.task-continuity
- majordomus.use-case-coverage
- majordomus.verification-integrity
- majordomus.obligation-closure
The moments this answers
- accepted "done" because the model said so, and paid for it the next morning A fluent completion claim is accepted as evidence because nothing wrote down, beforehand, what would have to be true.
- watched a session undo last week's decision, for the reason it was made A decision whose reason lived in a conversation cannot be reviewed, only re-argued — by a worker with less information than the first one had.
- found finished work on a branch that nobody ever merged Workers produce far more than integration absorbs, and nothing distinguishes work that is done from work that is done and landed.
- closed an issue whose acceptance criteria nothing had actually checked Completion is recorded as a state change in a tracker rather than as evidence in the repository, so the two drift immediately.
- looked at the bill and could not say which of it produced anything Consumption is measured per account and outcomes are recorded per person, so the two can never be joined.