From ac57ce201176b6ebc45bb53698deab6d4d2f167d Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 6 Aug 2026 14:53:07 +0200 Subject: [PATCH] =?UTF-8?q?make=20help,=20and=20make=20ground=20=E2=80=94?= =?UTF-8?q?=20one=20way=20in,=20and=20a=20list=20of=20the=20rest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tier S (utility inside a boundary; chaos d8=5, no override). Provenance in this message per InnerLoop §Loop tiers. The maintainer asked how to start the UI. The answer was a five-flag cb-play invocation nobody could be expected to remember, in a Makefile whose own header calls itself "one command surface" -- a surface you have to read the source of is not one. make ground # play, recording a trial make ground PLAYERS=2 SLUG=darvo-confusion make trials # read the notes back `ground` timestamps the trial name so two sessions in one day cannot overwrite each other's notes, and keeps the date prefix because tools/trials.py reads the age from there. `make` with no target now lists targets instead of running the heaviest thing in the file. It extracts the `## ` comments that were already the convention -- ten of them existed and NOTHING HAD EVER RENDERED THEM. Which is how the first run found a real defect: `## run all GROUND scenarios through cb-sim` sat above `dep-weight:`, 167 lines from the `sim:` it describes. A doc comment nothing reads rots, and this one had -- same family as the message that sat unread for four days and the ten rulings nobody collected, in a third medium. Moved to `sim`, and `dep-weight` given its own. Documented the targets a person reaches for (coverage, status, all, self-tests, sim, design, difficulty, trials) and listed the undocumented instruments compactly, so nothing in the file is invisible. Verified end to end rather than by inspection: `make ground` served a page (200), a note posted through it (303), and `make trials` reported it bound to its position. loop-lint clean, check clean, self-tests 0 failures. Co-Authored-By: Claude Opus 5 --- Makefile | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0234113..8d8355e 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,22 @@ export PATH := $(dir $(CARGO)):$(PATH) PY := python3 TOOLS := $(REPO)/tools +# `make` with no target lists what there is, rather than running the +# heaviest thing in the file. The Makefile's own header calls itself "one +# command surface" -- a surface you have to read the source of is not one. +.DEFAULT_GOAL := help + +# A trial's name. Timestamped so two sessions on one day cannot overwrite +# each other's notes, and prefixed with the date because `tools/trials.py` +# reads the age from there (falling back to mtime). +TRIAL_NAME := $(shell date +%Y-%m-%d-%H%M)$(if $(SLUG),-$(SLUG),) +PLAYERS ?= 3 +PORT ?= 0 + # Every cargo recipe runs at the repo root; the shell does not persist cd. IN_REPO := cd $(REPO) && -.PHONY: check test sim bench bench-test coverage dep-weight cost cost-test cost-pin cost-budget shape-budget cost-mix loop-lint self-tests env-test task-done status facts-check facts-gen mutation-check size-metrics runtime-metrics build-time am6 am7 am8 edition-check replay-test loc play gate-review all \ +.PHONY: help ground check test sim bench bench-test coverage dep-weight cost cost-test cost-pin cost-budget shape-budget cost-mix loop-lint self-tests env-test task-done status facts-check facts-gen mutation-check size-metrics runtime-metrics build-time am6 am7 am8 edition-check replay-test loc play gate-review all \ design difficulty trials # `design`, `difficulty` and `trials` were added by CB-WP-0022, CB-WP-0025 # and CB-WP-0027 and none was declared here. Only `trials` revealed it, by @@ -32,6 +44,38 @@ IN_REPO := cd $(REPO) && # ran nothing. The other two work by luck: no file happens to share their # name. A target that is a command, not a file, belongs on this line. +## list every target, with what it does +## `make help` is also what bare `make` runs. +help: + @echo "clay-borg — make (bare \`make\` shows this)" + @echo + @awk '/^## /{ sub(/^## /,""); d[++n]=$$0; next } \ + /^[a-zA-Z][a-zA-Z0-9_-]*:/{ \ + if (n) { split($$1,a,":"); printf " %-16s %s\n", a[1], d[1]; \ + for (i=2;i<=n;i++) printf " %-16s %s\n", "", d[i]; print "" } \ + n=0; next } \ + { n=0 }' $(MAKEFILE_LIST) + @echo " Variables: PLAYERS=3 PORT=0 SLUG= ARGS=\"...\"" + @echo + @echo " Undocumented (instruments and gate internals):" + @awk '/^## /{ d=1; next } \ + /^[a-zA-Z][a-zA-Z0-9_-]*:/{ if (!d) { split($$1,a,":"); print a[1] } d=0; next } \ + { d=0 }' $(MAKEFILE_LIST) | sort -u | tr "\n" " " | fold -s -w 66 | sed "s/^/ /" + @echo + +## play GROUND in a browser, recording a trial (the usual way in) +## Opens a URL; game on the left, notes on the right. Everything you +## type in the notes panel is bound to the position you typed it at. +## `make ground PLAYERS=2 SLUG=darvo-confusion` +## Read the notes back afterwards with `make trials`. +ground: + @mkdir -p $(REPO)/trials + @echo " trial: trials/$(TRIAL_NAME).md (notes) + .yaml (the game)" + $(IN_REPO) $(CARGO) run -q -p cb-play -- \ + --players $(PLAYERS) --serve $(PORT) \ + --record trials/$(TRIAL_NAME).yaml \ + --trial trials/$(TRIAL_NAME).md $(ARGS) + ## fmt + clippy (deny warnings) + HashMap deny-lint check: $(IN_REPO) $(CARGO) fmt --all --check @@ -50,10 +94,11 @@ gate-review: test: $(IN_REPO) $(CARGO) test --workspace -## run all GROUND scenarios through cb-sim +## AM-4 dependency weight: third-party lines behind each budget dep-weight: $(PY) $(TOOLS)/dep-weight.py +## AM-1 rule coverage: which GROUND rules a scenario exercises coverage: $(PY) $(TOOLS)/rule-coverage.py @@ -117,6 +162,7 @@ loop-lint: $(PY) $(TOOLS)/loop-lint.py # Positive control for every reporting tool, per InnerLoop v1.1 Step 5. +## positive control for every reporting tool self-tests: $(PY) $(TOOLS)/cb-cost.py --self-test $(PY) $(TOOLS)/loop-lint.py --self-test @@ -171,12 +217,14 @@ facts-gen: # CB-WP-0027 T04: what the players said, and where. Surfacing is the # deliverable -- a commentary feature nobody can read is this project's # signature failure in a new medium (ADR-0014 D6). +## what the players said while playing, and where trials: @$(PY) $(TOOLS)/trials.py # CB-WP-0025 T06: the difficulty table (specs/RetrospectiveAnalysis.md §4). # Winnable fraction from the solver plus a PLURAL policy panel -- a single # policy's win rate may not be reported as a difficulty (§4.1). +## winnable fraction + a plural policy panel (never one bot's win rate) difficulty: @cargo run --release -q -p games-ground --example difficulty @@ -184,11 +232,13 @@ difficulty: # specs/GroundRules.md. Shows the QUEUE by default; the log of closed # findings is a line, not a listing, because a default view that mixes # them loses the queue property (ADR-0012 D5). +## the design-finding register: what is open, and what lacks a reproduction design: @$(PY) $(TOOLS)/design.py # T03: one-shot orientation — workplans, next task, spend, fast gates. # Cheap by design: no build. Start a session with this instead of grepping. +## one-shot orientation: workplans, next task, spend, fast gates status: @$(PY) $(TOOLS)/status.py @@ -218,6 +268,7 @@ cost-mix: cost-test cost-pin: cost-test $(PY) $(TOOLS)/cb-cost.py --pin fc76445 --composition --by-task +## run all GROUND scenarios through cb-sim sim: $(IN_REPO) $(CARGO) run -q -p cb-sim -- $(REPO)/scenarios/ground/*.yaml @@ -237,4 +288,5 @@ loc: printf '%-28s %s\n' $$d "$$(find $$d/src -name '*.rs' | xargs cat | grep -vcE '^\s*(//|$$)')"; \ done +## every gate, in order. The one CI would run. all: check test sim coverage size-metrics runtime-metrics am6 am7 am8 edition-check replay-test dep-weight self-tests env-test facts-check loop-lint bench-test