verify-e2e
Skill4 starsChanged 3 months agoMITView on GitHub
Run the markgate end-to-end CLI verification script (`.claude/scripts/e2e.sh`). It exercises the full CLI surface — original primitives (set / verify / clear / run / init / version, default key, --hash files + --include, --state-dir, env-var, precedence) plus every feature added in the 2026-05-09 batch (completion, config lint, TTL, --explain, bare status, composes / requires), the hash: diff strategy, the dead-include-glob refusal shared by both scoped modes, and clear surviving an invalid config. Wraps the script in `markgate run` so unchanged repos skip the run. Use whenever you want to confirm "all features still work" before declaring done, opening a PR, or merging — or when your changes touch the CLI surface and you want a quick smoke before pushing.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- tyrantpiper/travel-pwatheir own version, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- tyrantpiper/travel-pwa★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository3 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- audit-before-doneSkill
- iterate-designSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 4 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 15
After a non-trivial change anywhere under cmd/ or internal/cli/ — the unit tests cover most of this, but the black-box harness catches …
- Distinctive: line 19
Before opening a PR for a CLI-touching change.
- Distinctive: line 21
Before declaring a multi-PR merge wave done.
- Distinctive: line 22
When the user asks "is everything still working?".
- Very specific: line 36
Default key (no positional arg) → default
- Distinctive: line 96
when the child runs and the scope is still empty, the marker is refused (child ran, no marker written)
- Very specific: line 153
When a new feature lands in the markgate CLI:
- Very specific: line 155
Add a section to .claude/scripts/e2e.sh (mirror the existing cyan "=== feature ===" + new_repo + assert_* pattern).
- Very specific: line 157
Run bash .claude/scripts/e2e.sh once and confirm the new assertions pass.
- Very specific: line 159
Update the "what it covers" list in this SKILL.md so the description stays honest.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
verify-e2e
End-to-end smoke of the whole markgate CLI. The companion to
make lint (static) and go test ./... (unit / integration); this
one is the black-box layer that drives the built binary against
real git init sandboxes the way a user would.
When to invoke
- After a non-trivial change anywhere under
cmd/orinternal/cli/— the unit tests cover most of this, but the black-box harness catches wiring regressions (cobra command registration, flag exposure, exit-code mapping inExecute). - Before opening a PR for a CLI-touching change. Faster than waiting on CI.
- Before declaring a multi-PR merge wave done.
- When the user asks "is everything still working?".
The PreToolUse hook e2e-pre-merge.sh runs the same script
automatically before any gh pr merge ..., so you usually do not
need to invoke this skill immediately before merging — but it is
the manual entry point and a good rehearsal step before pushing.
What it covers
Three layers of assertions (the script prints the count on every run; it is deliberately not restated here, because a number copied into prose drifts):
Core primitives
set/verify/clearcycle includingclearidempotency- Default key (no positional arg) →
default --hash filesrequires--include; respects scope--state-dirflag override; marker NOT in default locationMARKGATE_STATE_DIRenv override- Precedence chain: flag > env >
state_dir:> default run: child runs on miss, skips on match, exit propagates, marker NOT advanced on child failureinitwrites.markgate.ymland is non-clobberingversionprints something
2026-05-09 batch features
completion: bash script emit, unknown-shell exit=2, dynamic gate-key completion via__completeconfig lint: clean exit=0, dirty exit=1, dead glob / unknown-field detection,--jsonshape- TTL: fresh→0, expired→1 with stderr message, set resets,
1morejected at config load --explain/-e: scope to stderr, exit code unchanged, pretty-printed JSON shape{key, scope, hasher, state}- Bare
status: header, all rows,(configured)/(unconfigured)notes, single-key backward compat, snake_case--json composes(loose): unconditional set, verify-time propagationrequires(strict): set refused exit=2 naming offending child- Config-load errors: cycle / missing child / both fields set all reject at exit=2
hash: diff
- set / verify on a branch ahead of the base;
statusrecords the base ref and the resolved merge base - unrelated base-branch change merged in -> still fresh; a change to a file the branch also touched -> stale
- uncommitted in-scope edit / untracked in-scope file -> stale; out-of-scope edit -> fresh
- clean base-branch checkout ->
verifyandsetboth exit=2 naminghash=diff; barestatusdegrades the row instead of aborting the listing - unresolvable base -> exit=2 naming the ref
--hash diff --baseflags;--hash diffwithout--baseand--basewithouthash=diffboth exit=2- config without
baserejected;baseon afilesgate lints dirty with an explanatory message
Dead include globs (both scoped modes)
- an include list matching nothing ->
setexit=2 naming the pattern, onfilesanddiffalike, and no marker is written;verifyreports it as a mismatch (exit=1), not an error - a scope cleaned away between builds still rebuilds: a second
runcycle after the scope is deleted executes its child and re-records - the candidate universe differs per mode: an include matching only
gitignored paths is live for
files(which hashes them) and dead fordiff(whose delta can never contain them) - the other empty scopes stay usable: a quiet branch with a live
include, and
excludeemptying whatincludematched - bootstrapping is preserved:
verifywith no marker is exit=1 without hashing, sorunstill executes its child and records the marker once the child creates the scope - when the child runs and the scope is still empty, the marker is refused (child ran, no marker written)
--explainstays diagnostic: it renders the empty scope, so adding the flag never suppressesrun's child — including when the scope cannot be computed at all (a malformed glob)- a rename that kills a live scope ->
verifyexit=1 andsetexit=2; barestatusdegrades that row and keeps rendering the others
clear survives an invalid config (#77)
- a validation error elsewhere in the document no longer blocks
removal, and the gate's own
state_diris still honored set/verify/statusstill refuse the same config- unparseable YAML:
clearnames the exact path it looked at, warns when nothing was there, and--state-dirstill resolves exactly - flag typos (
--hash bogus) are still refused on a valid config
How it caches
The hook wraps the script in go run ./cmd/markgate run
hook-e2e-pre-merge -- bash .claude/scripts/e2e.sh, so:
- First run after a source change: full ~10–15s execution
(build + every assertion, the script does its own
go buildto the temp dir). - Repeat run with no source change: ~0.1s skip, marker hit.
The marker lives at .git/markgate/hook-e2e-pre-merge.json
(default state-dir, git-ignored). Default git-tree hash means
any source change invalidates it.
Running it
bash .claude/scripts/e2e.sh # full run, one PASS line per assertion + summary
QUIET=1 bash .claude/scripts/e2e.sh # only print section headers + failuresExit code = number of failed assertions (0 on all-pass).
When this skill is NOT enough
- The script does not exercise marker-file atomicity under
concurrent writes — that's covered by
internal/stateunit tests, and re-testing it from a black-box harness is unreliable. - It does not run
make lintorgo test ./.... Those remain the static / unit gates and are independent. Run them separately when introducing new code (theaudit-before-doneskill is the canonical pre-push checklist). - It uses a temp sandbox under
/tmpand does not exercise the user's actual.markgate.ymlor shared state-dir. If you changed sharing / multi-host behavior, smoke that path manually too.
Adding a new assertion
When a new feature lands in the markgate CLI:
- Add a section to
.claude/scripts/e2e.sh(mirror the existingcyan "=== feature ==="+new_repo+assert_*pattern). - Run
bash .claude/scripts/e2e.shonce and confirm the new assertions pass. - Update the "what it covers" list in this SKILL.md so the description stays honest.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

