Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @DivyamTalwar
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[![verify](https://github.com/divyamtalwar/fablewright/actions/workflows/ci.yml/badge.svg)](https://github.com/divyamtalwar/fablewright/actions/workflows/ci.yml)
[![tests](https://img.shields.io/badge/tests-143%20offline-brightgreen.svg)](tests/run-tests.sh)
[![checks](https://img.shields.io/badge/verify-149%20checks-brightgreen.svg)](scripts/verify.sh)
[![verify](https://img.shields.io/badge/verify-fail--closed-brightgreen.svg)](scripts/verify.sh)
[![hosts](https://img.shields.io/badge/hosts-Claude%20Code%20%C2%B7%20Codex-blue.svg)](#quickstart)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)

Expand All @@ -19,7 +19,7 @@ have done.

</div>

![FABLEWRIGHT architecture](docs/images/architecture.png)
![One wright plans and accepts; four pinned lanes implement; a fresh read-only reader from a different model family returns ship, fix-first or rethink](docs/images/architecture.png)

---

Expand Down Expand Up @@ -83,7 +83,7 @@ ERROR: lane luna was pinned to effort 'max' but thread bbbb... also ran at: low
(across 3 turns).
```

![Proven routing versus a refused lane](docs/images/proof.png)
![Two runs of the same command: one verified and exiting 0, one refused with exit 69 because the lane dropped below its pinned effort](docs/images/proof.png)

---

Expand Down Expand Up @@ -165,7 +165,7 @@ anyone starts, a written integration step owned by the wright, one reader over t
*combined* change set, and every lane from one model family — because a single reader
cannot be cross-family with two families at once.

![The five routes and how the wright chooses between them](docs/images/routes.png)
![The five routes ordered cheapest-first, with who implements, who reviews, and the question that selects each](docs/images/routes.png)

---

Expand Down Expand Up @@ -301,6 +301,44 @@ scripts/ ask-wright · cast-call · install-agents · inspect-age
tests/ offline suite with synthetic rollout fixtures
```

## Contributing

Issues and pull requests are welcome, and the bar is the same one the project holds
itself to: evidence over description.

`main` is protected. Every change arrives as a pull request, CI must be green on both
runners, and the maintainer merges. That is not ceremony — it is the same separation of
authorship and acceptance the tool itself enforces.

```sh
git switch -c fix/short-scope
# change something
sh tests/run-tests.sh # 143 offline cases, no model calls
sh scripts/verify.sh # manifests, pins, wording, links, images, then the suite
shellcheck --severity=warning scripts/*.sh tests/*.sh
git push -u origin fix/short-scope
gh pr create
```

Both gates are offline: they call no model, spend no tokens, and write nothing outside a
temporary directory. A green `verify.sh` is the bar.

Before proposing a change to the scripts, read
**[Traps this codebase has already hit](CONTRIBUTING.md#traps-this-codebase-has-already-hit)**.
The code carries no inline commentary, so that section is where the reasoning lives —
every entry is a real defect found in review, not a hypothetical. Changes that weaken
fail-closed behaviour will be declined however convenient they are; the rules are listed
in [CONTRIBUTING.md](CONTRIBUTING.md).

Found something that behaves differently from what the docs promise? Open an issue with
the exact command and its exact output. If a lane was refused, that may be correct — this
tool stops a lane rather than returning work it could not verify — so paste the refusal
and let the evidence settle it.

Security reports go through
[GitHub's private advisory flow](https://github.com/divyamtalwar/fablewright/security/advisories/new),
never a public issue. See [SECURITY.md](SECURITY.md).

## Prior art

The route-gating discipline — declare the route before the first task tool, default to
Expand Down
2 changes: 1 addition & 1 deletion docs/WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ passed: 143 failed: 0
ALL TESTS PASSED

$ sh scripts/verify.sh
verify 1.0.0: passed 149, failed 0
verify 1.0.0: passed 155, failed 0
VERIFY PASSED
```

Expand Down
Binary file added docs/images/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/proof.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/routes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions scripts/verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,26 @@ for cmd in hosts/claude-code/commands/*.md; do
done
[ "$bare_paths" -eq 0 ] && ok 'every command references repo files via ${CLAUDE_PLUGIN_ROOT}'

group 'every referenced image exists'
missing_images=0
for image in $(grep -oE '!\[[^]]*\]\(([^)]+\.(png|jpg|jpeg|svg|gif))\)' README.md docs/*.md 2>/dev/null |
sed 's/.*(//; s/)$//' | sort -u); do
case "$image" in http*) continue ;; esac
if [ -f "$image" ]; then
ok "image exists: $image"
else
bad "image exists: $image" 'a README referencing a missing image renders a broken icon'
missing_images=$((missing_images + 1))
fi
done
for image in docs/images/architecture.png docs/images/proof.png docs/images/routes.png; do
if grep -Fq "$image" README.md; then
ok "README uses the diagram: ${image##*/}"
else
bad "README uses the diagram: ${image##*/}"
fi
done

group 'every internal document link resolves'
broken_links=0
link_report=${TMPDIR:-/tmp}/fablewright-links.$$
Expand Down
Loading