An AI-native dev harness. Solemnly swear you're up to no good.
Project description
marauders-mischief
An AI-native dev harness. Solemnly swear you're up to no good.
A workflow for Claude Code that makes a coding agent behave like an engineering team instead of a single overcaffeinated junior.
Why
If you've used a coding agent for more than half an hour, you've watched it do at least one of these:
- Delete the failing test to make the suite green.
- Confidently report "feature shipped" when the feature doesn't work.
- Refactor while you asked it to fix a bug, breaking three other things on the way.
- Lose its mind around the second hour of a long task and forget what you asked for.
- Run overnight in autonomous mode and commit garbage to
mainwhile you slept.
Agents are very good at writing code. They are very bad at the parts of engineering that aren't writing code: planning, peer review, knowing when to stop, knowing when to ask. Most setups paper over that gap by just letting it happen and hoping for the best.
mar is the setup that doesn't. It splits each task into the stages a real team uses (research, plan, build, test, review, integrate), runs each stage in a fresh-context sub-agent that hasn't been defending its own previous choices, and enforces the boundaries mechanically. Not by asking nicely.
What it does
For every task you give it:
- Research — pulls together what you need to know about the problem (the codebase, the libraries, the prior art). Surfaces options; doesn't decide.
- Plan — an author writes the plan. A skeptic in a fresh context tries to break it. They reconcile, or you do.
- Execute — small steps, fresh agent per step, no accumulated context drift.
- Test — multiple test kinds in parallel: unit, eval, agent-flow, browser, perf. The orchestrator picks which apply to what changed.
- Refine — when something fails, the fix goes in the code. Not in the test. A PreToolUse hook physically blocks the agent from writing to
tests/, fixtures, snapshots, or eval data. - Simplify — a cleanup pass. Same author/skeptic pattern. Reverts itself if cleanup regresses anything.
- Verify — a structured pre-PR adherence check. Classifies failures by who should fix them (refine / replan / user) instead of bouncing everything back to refine.
- Review + Tester — fresh-context PR review (inline comments on the actual PR) and functional validation (does the feature work for a user?) — in parallel.
- Integrate — squash merge with the commit story you approved in step 2.
Every stage runs as a fresh sub-agent. None of them inherit the running history. The only thing that persists between stages is files: plan.md, test-report.md, verification.md. Context-as-files, not context-as-tokens. The plan, not the chat log, is the source of truth.
What it stops
| Failure mode | What stops it |
|---|---|
| Agent weakens a failing test instead of fixing the code | tests/, fixtures, snapshots, eval data are write-blocked during refine via the scope hook |
| A refine cycle introduces new failures while patching old ones | Each round is checkpointed; new failures auto-revert and escalate via the refine-regression-wall safeguard |
| Plan and shipped reality drift apart | Verify runs 5 mechanical pre-checks (diff vs scope, unresolved questions, unchecked manual steps, deviations triage, plan-quality) before reasoning, with structured evidence required for every adherence claim |
| Long agents lose track of state | Each build step is a fresh sub-agent reading the previous step's handoff file |
| Autonomous mode ships broken work silently | 15+ always-on safeguards pause autonomous sessions on every known silent-failure mode |
| Agent self-grades and rubber-stamps its own work | Author/skeptic split at design-time stages (research, plan, simplify); fresh-context review at Stage 5 |
| Long-lived branches diverge and produce merge nightmares | One phase, one branch, one PR. Squash-merged at integrate. Phases run sequentially |
Autonomy modes
Pick how much you want to be in the loop:
interactive— every gate pauses for your approval.normal— gates pause for important things; routine stuff auto-passes.streamlined— auto-passes if no issues; gates only when something needs you.autonomous— runs end-to-end. You provide no input after/mar:session-startuntil the session finishes or a safeguard pauses it.
All four modes use the same safeguards. Autonomous is allowed to be unattended because the safeguards make it safe to be unattended, not because nobody's looking.
Install
pipx install marauders-mischief
# or
uv tool install marauders-mischief
Prereqs:
- Claude Code installed
ghauthenticated for your repo (gh auth login)
Quickstart
mkdir my-project && cd my-project
git init
gh repo create --private --source=. --remote=origin # or use an existing repo
mar init
# Fill in the two files mar wants you to fill in:
# .brain/CONTEXT.md — what you're building, in plain language
# .brain/STATE.md — where you are right now
Then open Claude Code and run a session:
/mar:session-start "fix the auth token refresh bug"
# picker: size (XS/S/M/L/XL), kind, guidance, autonomy
/mar:plan
# → research, plan, plan-skeptic review
/mar:approve plan
/mar:ship
# → branch, execute, test, refine, simplify, verify, review + tester, draft PR
/mar:approve integrate
# → gh pr ready + gh pr merge --squash
For a tiny task (typo, isolated bug) the loop fits in 5-15 minutes. For a multi-day feature you'll plan it as L or XL and run multiple phases sequentially, each one its own PR.
Slash commands
| Command | What it does |
|---|---|
/mar:session-start |
Start a session (size / kind / guidance / autonomy picker) |
/mar:plan |
Run the current planning sub-stage |
/mar:ship |
The build loop: branch → execute → test → refine → simplify → verify → review + tester → draft PR |
/mar:integrate |
Compose the commit story; pause for approval |
/mar:approve <gate> |
Pass a gate (research / meta-plan / plan / integrate / …) |
/mar:iterate <gate> "<note>" |
Refine the gate's output without losing position |
/mar:revise <target> "<note>" |
Back up to a prior stage with a note |
/mar:redirect "<direction>" |
Pivot the session entirely |
/mar:reject <gate> |
Discard the gate's artifact and back up |
/mar:status |
Where am I? |
/mar:session-list |
All active and archived sessions |
/mar:retrospect <id> |
Post-archive audit; surfaces framework feedback for the maintainer |
There are more (idea capture, session resume, between-session machinery). See .claude/commands/mar/ after install, or the full spec at ops/workflow/README.md.
What mar init writes
your-project/
├── CLAUDE.md Project-level context. You own it.
├── .brain/ Curated context. You own it.
│ ├── CONTEXT.md What you're building.
│ ├── STATE.md Current state of play.
│ ├── STACK.md Stack decisions.
│ ├── DECISIONS.md Why you made the calls you made.
│ └── RISKS.md What could go wrong.
├── .claude/
│ ├── agents/ ~30 sub-agents (research, plan, execute, review, …)
│ ├── commands/mar/ 20+ slash commands (/mar:*)
│ └── settings.json Hooks + permissions. mar manages its own keys.
├── ops/workflow/ Spec, scripts, templates
└── .mm/lockfile.json SHA256 of every framework file. `mar update` reads this.
Every shipped file falls into one of three classes:
- framework — owned by mar. Overwritten on
mar update. Drift is detected if you edit. - scaffolded — created once at init. Yours forever after. mar never touches.
- merged — mar owns specific keys; you own everything else in the same file (
.claude/settings.json,.gitignore).
This split is what lets mar update upgrade the framework without clobbering your project.
Development
git clone git@github.com:sindreespeland/marauders-mischief.git
cd marauders-mischief
uv sync --dev
uv run pytest
uv run ruff check src tests
# Try mar init against a throwaway directory
mkdir /tmp/test-install && cd /tmp/test-install
uv run --project ~/repos/marauders-mischief mar init
Status
Pre-release. The build loop is hardened end-to-end (v0.5 through v0.13.3). The PR-native flow is live (v0.12). Smoke-test against a throwaway repo before trusting it on real work.
Each minor release hardens one stage. See the roadmap below or the GitHub Releases page for what landed when.
Roadmap
Shipped:
- v0.5 — phase research: hypothesis-driven, 5-section structured output, optional skeptic
- v0.6 — phase plan: author + skeptic at per-phase grain, AI-aware checks
- v0.7 — execute step-decomposition: bounded context per build step
- v0.8 — multi-kind testing: strategist + parallel runners (unit/eval/agent-flow/browser/perf), target-aware refine
- v0.9 — simplify hardened: dynamic conventions, targeted re-test, revert on regression
- v0.10 — refine hardened: protected surfaces (tests/fixtures/snapshots/evals), checkpoint + revert across all four refine loops
- v0.11 — verify hardened: route-based dispatch (refine/replan/user), mechanical pre-checks, structured evidence
- v0.12 — PR-native flow: draft PR at Stage 2.2, review/tester in PR mode, squash-merge at
/mar:approve integrate - v0.13 — retrospect redesigned: per-session output, maintainer feedback via chat, no framework-shared file in user repos
- v0.13.1 — first-run fix:
/mar:shipauto-creates the phase branch - v0.13.2 —
CLAUDE.mdtemplate brought up to date (session awareness, files-as-source-of-truth table, safeguards list, post-v12 repo map) - v0.13.3 — critical fix:
.claude/settings.jsonhook shape corrected (was being rejected by Claude Code, silently disabling the scope hook)
Next:
- v0.14 — PR-native polish: ready-for-review at Stage 5 verdict-clear, CI as hard merge-block, worktree-per-phase (multi-phase parallelism)
- v0.15 —
mar update(with conflict resolution),mar status,mar doctor - v0.16 — Codex CLI adapter, Cursor adapter
- v0.17 —
mar update --auto-check(optional auto-notify on session start)
Contributing
Issues and PRs welcome at github.com/sindreespeland/marauders-mischief. Run /mar:retrospect after a session if you find friction; the chat output formats framework findings as paste-ready issue bodies.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file marauders_mischief-0.14.0.tar.gz.
File metadata
- Download URL: marauders_mischief-0.14.0.tar.gz
- Upload date:
- Size: 257.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c1d1ac46f7cd04fd03a153fb76f847c687e54720bf00a25c68f4f5b564030e6
|
|
| MD5 |
68eca564a135ddaae2b36e736f4c6019
|
|
| BLAKE2b-256 |
e3747728d69efafb69214bf995a47848cc6abbf56e68a431879b12e744039097
|
Provenance
The following attestation bundles were made for marauders_mischief-0.14.0.tar.gz:
Publisher:
release.yml on sindreespeland/marauders-mischief
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marauders_mischief-0.14.0.tar.gz -
Subject digest:
2c1d1ac46f7cd04fd03a153fb76f847c687e54720bf00a25c68f4f5b564030e6 - Sigstore transparency entry: 1794601878
- Sigstore integration time:
-
Permalink:
sindreespeland/marauders-mischief@b1c1fdf00afe46a023cba21d0dcdf54ba1ae3993 -
Branch / Tag:
refs/tags/v0.14.0 - Owner: https://github.com/sindreespeland
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b1c1fdf00afe46a023cba21d0dcdf54ba1ae3993 -
Trigger Event:
push
-
Statement type:
File details
Details for the file marauders_mischief-0.14.0-py3-none-any.whl.
File metadata
- Download URL: marauders_mischief-0.14.0-py3-none-any.whl
- Upload date:
- Size: 335.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b0413aafbcf22d5f12fdfc3099dfdb3efc45ed9ae8c175846199ed7ba497b34
|
|
| MD5 |
00ad572a246990d1b804c3667a404c92
|
|
| BLAKE2b-256 |
313056d063f10b9dcacaa46a41d7cbfb4994adc76f3ada57702752b086e35533
|
Provenance
The following attestation bundles were made for marauders_mischief-0.14.0-py3-none-any.whl:
Publisher:
release.yml on sindreespeland/marauders-mischief
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
marauders_mischief-0.14.0-py3-none-any.whl -
Subject digest:
5b0413aafbcf22d5f12fdfc3099dfdb3efc45ed9ae8c175846199ed7ba497b34 - Sigstore transparency entry: 1794602001
- Sigstore integration time:
-
Permalink:
sindreespeland/marauders-mischief@b1c1fdf00afe46a023cba21d0dcdf54ba1ae3993 -
Branch / Tag:
refs/tags/v0.14.0 - Owner: https://github.com/sindreespeland
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b1c1fdf00afe46a023cba21d0dcdf54ba1ae3993 -
Trigger Event:
push
-
Statement type: