Skip to content

the challenge

Try to get unfinished work accepted.

A coding agent claims a directory, edits a file outside it, says it is done, hands over, and comes back. Majordomus refuses it, names the reason every time, and accepts the work only when the repository's own test passes. Every line below is a recorded run of the real tool, executed when this page was generated.

Coding agents are good at doing the work and bad at knowing when it is finished. They touch files nobody asked for, report success over a failing test, and forget the task when the session ends. A better prompt does not fix that, because the prompt is the part being ignored. What fixes it is a check the worker cannot talk its way past.

recorded steps
10
refusals
3
of them by finish
2
guarantees exercised
6

The run, step by step

Step through it, or read it straight down. A step marked worker is the change being judged; every other step is Majordomus answering it.

step 1 of 10 · Majordomusaccepted

The task claims lib. Another worker already claims lib in a second worktree, and start says so before any file is touched.

majordomus start 'refuse tabs in the parser' --scope lib

exit 0
started t-<id>  profile=implementation  scope=lib
INFO overlap     repo-other — claims lib — contains your lib  [reproduce: majordomus check --overlap]
next: majordomus context; checkpoint every 15m; majordomus check before claiming anything

What the scenario asserted at this step →

step 2 of 10 · the worker the change being judged

The worker makes the change it was asked for, and also edits a note under docs, which the task never claimed.

echo "tabs are refused" >> lib/a && echo "parser notes" >> docs/d

exit 0

What the scenario asserted at this step →

step 3 of 10 · Majordomusrefused

check names the file outside the claimed scope and exits non-zero. It is a failure, not a warning.

majordomus check

exit 10
  • knowledge passed
  • records passed
  • blockers passed
  • records passed
  • scope failed
  • state passed

→ check: 12 finding(s), 1 failing

The whole recorded output, 13 lines
OK   knowledge   records — 0 record(s) valid against knowledge/v1; every reference resolves  [reproduce: majordomus knowledge check]
·    checkpoint  t-<id> — <timed against the checkpoint interval>
OK   records     ledger.jsonl — every line is a well-formed event
OK   blockers    t-<id> — none open
OK   records     decisions.md — every entry is attributable
FAIL scope       docs/d — outside claimed scope (lib)  [reproduce: git status --porcelain; git log --first-parent --no-merges --name-only --format= <sha>..HEAD]
OK   state       t-<id> — exact (head <head>)
INFO mesh        t-<id> — the repository declares no enabled mesh
INFO use-case    30 advisory gap(s) — not covered by an active use case, and the policy does not require it: command:init command:update command:doctor command:watch command:start command:context command:checkpoint command:handover command:check command:finish command:history command:decision command:question command:prompt command:evidence command:skills command:capture command:search command:doctrine command:plan command:version command:session command:knowledge command:adr command:usecase command:rules command:migrate command:recover command:bench command:archive  [reproduce: majordomus usecase coverage]
OK   use-case    0 of 30 target(s) covered — every public command the policy requires is named and run by an active use case (policy use_cases.coverage)
INFO obligation  t-<id> — the task declares no obligations
INFO gate        t-<id> — this repository declares no CI model at .ai/repo/ci/gates.yaml; nothing can be planned
check: 12 finding(s), 1 failing

What the scenario asserted at this step →

step 4 of 10 · Majordomusrefused

The worker reports the task finished. finish evaluates the contract instead of believing it, and refuses.

majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

exit 10
  • blockers passed
  • note failed
  • scope failed
  • state passed
  • verification failed

→ finish: refused, 3 unmet

The whole recorded output, 18 lines
OK   blockers    t-<id> — none open
FAIL note        t-<id> — no --note file and no handover for this task  [reproduce: majordomus handover < note.md]
INFO regression  t-<id> — profile implementation adds no requirement beyond the shared contract
FAIL scope       docs/d — outside claimed scope (lib)  [reproduce: git status --porcelain; git log --first-parent --no-merges --name-only --format= <sha>..HEAD]
OK   state       t-<id> — exact (head <head>)
INFO continuity  t-<id> — applies to partial and blocked
INFO mesh        t-<id> — the repository declares no enabled mesh
INFO use-case    30 advisory gap(s) — not covered by an active use case, and the policy does not require it: command:init command:update command:doctor command:watch command:start command:context command:checkpoint command:handover command:check command:finish command:history command:decision command:question command:prompt command:evidence command:skills command:capture command:search command:doctrine command:plan command:version command:session command:knowledge command:adr command:usecase command:rules command:migrate command:recover command:bench command:archive  [reproduce: majordomus usecase coverage]
OK   use-case    0 of 30 target(s) covered — every public command the policy requires is named and run by an active use case (policy use_cases.coverage)
FAIL verification t-<id> — sh test/parse.sh — exit 1, <s>s  [reproduce: sh test/parse.sh]
INFO obligation  t-<id> — the task declares no obligations
INFO gate        t-<id> — this repository declares no CI model at .ai/repo/ci/gates.yaml; nothing can be planned
INFO gate        t-<id> — not in verification.finish_requires
finish: refused, 3 unmet
blocking doctrines:
- majordomus.note-integrity
- majordomus.scope-integrity
- majordomus.verification-integrity

What the scenario asserted at this step →

step 5 of 10 · the worker the change being judged

The stray edit is taken back.

git checkout -- docs/d

exit 0

What the scenario asserted at this step →

step 6 of 10 · Majordomusaccepted

The session ends. What the next one needs is written into the repository, not left in a transcript.

majordomus handover < challenge-handover.md

exit 0
.ai/local/state/handovers/<time>--main--<head>--<hash>.md

What the scenario asserted at this step →

step 7 of 10 · Majordomusaccepted

A new session asks the repository what it needs to know, and gets the task, its scope and the handover back.

majordomus context

exit 0
# Majordomus context — <time>
# a projection of durable state, not a source of truth: validate every line against git

## GIT
repository   <repo>
branch       main
head         <sha>
working_tree dirty
task_record  exact (recorded head <head>)

## TASK
id           t-<id>
The remaining 45 lines of the output
task         refuse tabs in the parser
profile      implementation
owner        <owner>
outcome      active
scope        lib
started      <time> (<age> ago)
checkpoint   <time> (<age> ago, interval 15m)

## PROFILE implementation
capability   standard
effort       medium
verbosity    concise
presentation engineering
verification verify command
output       outcome, changes, verification, blockers, next_action

## CONTEXT DOCUMENTS (for the scope, root first; majordomus context explain <path>)
lib  ai.layer

## KNOWLEDGE (candidates awaiting review on this branch; majordomus knowledge candidates)
No knowledge candidates await review on this branch. That is an answer, not a gap: `majordomus knowledge candidates` lists every branch.

## DECISIONS (5 most recent for this task)
(none)

## LATEST COMPATIBLE HANDOVER (.ai/local/state/handovers/<time>--main--<head>--<hash>.md)
match        same_worktree_same_branch
git state    exact
created      <time> (<age> ago)
task         t-<id>
# Objective
refuse tabs in the parser
# Current State
tabs are refused; the stray note under docs is reverted; the parser's test still fails
# Next Action
make the message name the column, then run the parser's test again

## FILES TOUCHED IN SCOPE (1)
lib/a

## EXCLUDED
- history — profile implementation sets context.recent_history_depth: 0

## BUDGET
57 of 300 lines

What the scenario asserted at this step →

step 8 of 10 · Majordomusrefused

Scope is clean now, but the repository's own test still fails. finish runs it and refuses again.

majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

exit 10
  • blockers passed
  • note passed
  • scope passed
  • state passed
  • verification failed

→ finish: refused, 1 unmet

The whole recorded output, 16 lines
OK   blockers    t-<id> — none open
OK   note        t-<id> — <time>--main--<head>--<hash>.md
INFO regression  t-<id> — profile implementation adds no requirement beyond the shared contract
OK   scope       t-<id> — 1 touched file(s), all within scope
OK   state       t-<id> — exact (head <head>)
INFO continuity  t-<id> — applies to partial and blocked
INFO mesh        t-<id> — the repository declares no enabled mesh
INFO use-case    30 advisory gap(s) — not covered by an active use case, and the policy does not require it: command:init command:update command:doctor command:watch command:start command:context command:checkpoint command:handover command:check command:finish command:history command:decision command:question command:prompt command:evidence command:skills command:capture command:search command:doctrine command:plan command:version command:session command:knowledge command:adr command:usecase command:rules command:migrate command:recover command:bench command:archive  [reproduce: majordomus usecase coverage]
OK   use-case    0 of 30 target(s) covered — every public command the policy requires is named and run by an active use case (policy use_cases.coverage)
FAIL verification t-<id> — sh test/parse.sh — exit 1, <s>s  [reproduce: sh test/parse.sh]
INFO obligation  t-<id> — the task declares no obligations
INFO gate        t-<id> — this repository declares no CI model at .ai/repo/ci/gates.yaml; nothing can be planned
INFO gate        t-<id> — not in verification.finish_requires
finish: refused, 1 unmet
blocking doctrines:
- majordomus.verification-integrity

What the scenario asserted at this step →

step 9 of 10 · the worker the change being judged

The worker does what the handover said was left.

echo "the message names the column" >> lib/a

exit 0

What the scenario asserted at this step →

step 10 of 10 · Majordomusaccepted

Every line of the contract passes, so the outcome is recorded, with the verification that proved it.

majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

exit 0
  • blockers passed
  • note passed
  • scope passed
  • state passed
  • verification passed

→ finish: t-<id> completed

The whole recorded output, 14 lines
OK   blockers    t-<id> — none open
OK   note        t-<id> — <time>--main--<head>--<hash>.md
INFO regression  t-<id> — profile implementation adds no requirement beyond the shared contract
OK   scope       t-<id> — 1 touched file(s), all within scope
OK   state       t-<id> — exact (head <head>)
INFO continuity  t-<id> — applies to partial and blocked
INFO mesh        t-<id> — the repository declares no enabled mesh
INFO use-case    30 advisory gap(s) — not covered by an active use case, and the policy does not require it: command:init command:update command:doctor command:watch command:start command:context command:checkpoint command:handover command:check command:finish command:history command:decision command:question command:prompt command:evidence command:skills command:capture command:search command:doctrine command:plan command:version command:session command:knowledge command:adr command:usecase command:rules command:migrate command:recover command:bench command:archive  [reproduce: majordomus usecase coverage]
OK   use-case    0 of 30 target(s) covered — every public command the policy requires is named and run by an active use case (policy use_cases.coverage)
OK   verification t-<id> — sh test/parse.sh — exit 0, <s>s, tree <tree>
INFO obligation  t-<id> — the task declares no obligations
INFO gate        t-<id> — this repository declares no CI model at .ai/repo/ci/gates.yaml; nothing can be planned
INFO gate        t-<id> — not in verification.finish_requires
finish: t-<id> completed

What the scenario asserted at this step →

What it checked, and what it decided

Every step at which Majordomus judged the work, in the order the run reached it: each line of the contract it checked, passed or failed, and the verdict that closed the step. It is read off the run's own output, which is one click away in the replay above.

  1. step 3 majordomus check

    check names the file outside the claimed scope and exits non-zero. It is a failure, not a warning.

    • knowledge passed
    • records passed
    • blockers passed
    • records passed
    • scope failed
    • state passed

    → check: 12 finding(s), 1 failing refused

  2. step 4 majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

    The worker reports the task finished. finish evaluates the contract instead of believing it, and refuses.

    • blockers passed
    • note failed
    • scope failed
    • state passed
    • verification failed

    → finish: refused, 3 unmet refused

  3. step 8 majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

    Scope is clean now, but the repository's own test still fails. finish runs it and refuses again.

    • blockers passed
    • note passed
    • scope passed
    • state passed
    • verification failed

    → finish: refused, 1 unmet refused

  4. step 10 majordomus finish --outcome completed --verify-command 'sh test/parse.sh'

    Every line of the contract passes, so the outcome is recorded, with the verification that proved it.

    • blockers passed
    • note passed
    • scope passed
    • state passed
    • verification passed

    → finish: t-<id> completed accepted

The agent saying it is finished is not one of the inputs. The work is accepted when every line of the contract passes, and not before.

Where the decision lives

The same work, with and without a control plane. Each row links the guarantee that holds it and the test that proves the guarantee.

Without a control planeWith MajordomusHeld byDeclaredRecorded evidence
The agent says the work is done. finish evaluates a contract and writes nothing while any line fails. finish-contract
implemented in lib/finish.sh
test test/cases/06_finish.sh
declared status: guaranteed recorded evidence: not run
Which files a task may touch is implied by the prompt. The task claims its paths, and a touched file outside them is a failure. scope-enforcement
implemented in lib/check.sh
test test/cases/04_start_check.sh
declared status: guaranteed recorded evidence: not run
Two agents edit the same paths and find out at merge time. start reports another worker already claiming those paths. overlap-report
implemented in lib/check.sh
test test/cases/04_start_check.sh
declared status: guaranteed recorded evidence: not run
The next session starts from a transcript, or from nothing. The handover is a structured record in the repository, and context returns it. handover-record
implemented in lib/handover.sh
test test/cases/05_handover.sh
declared status: guaranteed recorded evidence: not run
An outcome is whatever the last message said. An outcome is one of a closed set, recorded with the verification that proved it. typed-outcome
implemented in lib/finish.sh
test test/cases/06_finish.sh
declared status: guaranteed recorded evidence: not run

Run it yourself

The scenario is a file in the repository. Install the tool, clone the repository, and run the use case: it builds a disposable repository, replays every step against your build, and fails if any recorded exit code or pattern no longer holds.

  1. install the tool
    curl -fsSL https://majordomus.dev/install.sh | sh
  2. get the scenario
    git clone https://github.com/korczis/prismatic-majordomus.git && cd prismatic-majordomus
  3. replay it
    majordomus usecase run catch-an-agent-that-says-it-is-done

Then put it on your own repository →

Inspect how it works

Nothing here is staged. These are the files that define, prepare and run the scenario, and the guarantees it exercises.

Guarantees this run exercises

Searches the titles and descriptions of every page this site publishes.