Skip to content
cccskills
FreePublished on GitHub

worktree

Work in an isolated git worktree and get CI green LOCALLY before pushing. Use at the START of any change to this repo — creating a branch, editing, building, or pushing — and whenever you are about to run a build/test command whose success you intend to believe. Covers the absolute primary-checkout rule (many agent sessions share this repo; mutating the primary clobbers their WIP), the never-git-stash rule, per-repo branch-protection strictness (mergeable is the bar, not merged), the CI flag set that promotes warnings to errors, and the eight commands that have produced a FALSE PASS on this macOS host — no timeout binary, --no-build on an unbuilt project, multi-project dotnet build, piping a build into tail, and zsh silently applying a history modifier to an unbraced $ref:path.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12 stars(GitHub 12 + cccskills 0)
Works withGitHub

Run score Not tested

See how to install

Files included (1)

  • SKILL.md13.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

/worktree — isolate your work, then prove it green before you push

Two rules that never bend, and everything else here serves them:

  1. EVERY agent session works in its OWN git worktree on a fresh branch. The primary checkout is a read-only reference.
  2. A verification step that cannot fail is not a verification step. Demand a positive, specific success signal — 0 Error(s), a fresh .trx, an elapsed time that makes sense — never "the command returned".

🚨🚨🚨 ABSOLUTE: never work on the primary checkout

The primary checkout (/Users/roland/code/MeshWeaver) is a READ-ONLY reference, not a workspace. It must stay parked on main and untouched — never edit, build, commit, checkout, switch, reset, or stash there, and never leave it on a feature branch. It is the shared base that every session's worktree is cut from; the moment you mutate it (working tree, index, or HEAD) you can clobber every concurrent session's uncommitted WIP — a reset --hard there once wiped live work across every session.

If you find yourself about to touch a file under the primary directly, STOP and create a worktree first. Many Claude/agent sessions run against this repo at once; the worktree is what keeps them isolated.

# base on origin/main for a fresh change, or on the feature branch you're extending
git worktree add -b feat/my-change /Users/roland/code/MW-my-change origin/main
cd /Users/roland/code/MW-my-change      # isolated tree + index — your edits can't touch other sessions
# …edit, commit, build with CI's flags, push, open the PR — all from here…
git worktree remove /Users/roland/code/MW-my-change   # once merged/abandoned
  • git worktree list shows every active worktree (and which branch each holds — a branch can be checked out in only one).
  • Keep the primary parked on main and clean. If you find it on a feature branch or with a dirty tree, capture any work you care about (git diff > patch) and restore it — git switch main — before continuing in a worktree. It is the cut-point for every other session; a dirty/feature-branch primary breaks the "cut a fresh worktree off origin/main" flow.
  • Never git stash — the stash stack is repo-global and collides across worktrees; use git diff > patch + git apply instead.
  • Parallel PR-building sub-agents must pass isolation: "worktree" as a tool PARAM (a prompt-only "work in a worktree" does nothing).
  • A worktree or branch another session touched in the last 30 minutes is theirs, and a patch or log in the shared session scratchpad is not yours unless you named it. Name a patch for its branch (<issue>-<slug>.patch), and after git apply grep for a marker from YOUR change: an apply of someone else's diff also exits 0. The collision rule and the other shared-session practices: /pullrequest, "Working beside other sessions".
  • Stay at the root of your worktree for every command — never the primary, never a hard-coded path. Avoid chained commands (&&, ||), for loops, and cd; they all require user confirmation.

🚨 Before you push: make CI green LOCALLY first

CI builds Release with warnings-as-errors: dotnet build --no-restore -c Release -p:CIRun=true -warnaserror. A plain local dotnet build (Debug, no -warnaserror) passes while CI fails — warnings are promoted to errors there. Pushing a red branch wastes a CI cycle and, per the green-merge gate, blocks the pull-based self-update if it reaches main.

1. The bar is MERGEABLE, not merged

A branch that is merely behind main merges fine — do NOT push just to catch up. But every push you DO make merges the latest main first (AGENTS.md merge-latest-before-push). The main pr protection ruleset has strict_required_status_checks_policy: false and exactly ONE required check, Consolidate test results. Verify rather than trust this line:

gh api repos/Systemorph/MeshWeaver/rulesets/2128472 \
  --jq '.rules[] | select(.type=="required_status_checks") | .parameters | {strict: .strict_required_status_checks_policy, checks: [.required_status_checks[].context]}'

Merging main into every branch before every push costs a full CI cycle per PR and, with several PRs in flight, most of the throughput — the first merge makes every other branch stale again. Merge to main, then let main's own build recompile. What you DO owe: no conflicts, and a green required check.

🚨 strict is PER-REPO — check the repo you are actually in. This differs across the node repos, and getting it wrong wastes a cycle in one direction or blocks you in the other. As of 2026-08-12:

repostrictbehind-main merges?
MeshWeaverfalse (ruleset)yes
MeshWeaver.Education (was education)no branch protectionyes
MeshWeaver.Reinsurancefalseyes
MeshWeaver.SocialMediafalseyes
MeshWeaver.Pluginsfalse (measured 2026-09-02; was true until 2026-08-29)yes

One command answers it for any repo, and beats trusting this table:

gh api repos/Systemorph/<repo>/branches/main/protection --jq '.required_status_checks.strict'   # 404 = unprotected

Merge main only when it actually buys something, which — outside a strict repo — is exactly two cases:

  • The PR is DIRTY (real conflicts). Resolve it — and afterwards run the revert-check: git diff origin/main...HEAD --stat (THREE dots) must show only your intended files. A branch-favoured hunk silently undoing someone else's merged work is a real failure mode here, not a hypothetical.
  • CI fails on something your diff does not touch. Merge main before investigating: a stale branch re-samples flakes main has ALREADY fixed, and each one looks like a defect in your change. PR #794 burned five CI runs and most of a day that way — three different red tests, two already fixed on main, none caused by the branch.

🚨 But do not let that second case become a blanket excuse. Before attributing a red to main, check whether your diff can actually reach the failing test. "It's only markdown" is NOT such a check. Markdown in this repo is shipped, loadable content with guards over it — src/MeshWeaver.Documentation/Data/** ships as <EmbeddedResource> and is scanned by WhatsNewEntryIntegrityTest and MigrationWorkloadModelGuard, and .claude/skills/** is scanned by the latter too. Front matter is YAML: an unquoted : or # inside a scalar stops the node loading altogether (this took down Skill nodes on 2026-08-12).

2. Build with CI's flags

dotnet build -c Release -warnaserror for at least the projects you touched and their dependents. Green here ⇒ green there for compile/warning errors. The classic miss: CS9107 — a primary-constructor parameter captured and passed to a base ctor (warning in Debug, ERROR under -warnaserror). Fix it at the root: use the base's exposed member (e.g. protected Output) instead of capturing the param; do NOT just NoWarn it.

3. Only push when that Release/-warnaserror build is clean

Then verify the PR check went green (gh pr checks) before declaring done. Full PR/merge gate: /pullrequest.

🚨 A verification step that cannot fail is not a verification step

Every command below has produced a false pass on this repo — it looked like it succeeded and it did nothing.

TrapWhat you seeWhat actually happenedInstead
timeout / gtimeoutcommand not found, lost in a long logNeither binary exists on this macOS host — the wrapped command never ranBackground it and enforce your own deadline (below)
dotnet test --no-restore on a project never built in this worktreeZero output, exit 0, no .trxNothing was built, so no test ran. A fresh worktree has no bin/ — this is its default state, and --no-build behaves the samedotnet build <project>.csproj first, then require a fresh .trx
dotnet build a.csproj b.csproj (several project args)MSB1008: Only one project can be specified, exit 1Nothing built. Reads like a transient and gets retried instead of fixedOne project per invocation
Piping a build into tail/headA tidy tail with no error linesBuild FAILED scrolled off, and $? is the pager's status, not the build'sDon't pipe it; capture the build's own exit code and grep the 0 Error(s) summary
A build that finishes suspiciously fastBuild succeeded in ~2 sUp-to-date no-op — your edit may not be in it at allRe-run with --no-incremental to prove a real compile happened
--no-build after editing a doc / non-.cs assetTests pass, so the edit is finesrc/MeshWeaver.Documentation/Data/** ships as <EmbeddedResource>; a stale DLL still holds the old file, so the test never saw your change. Caught while writing this table — the run predated the edit by 54 sRebuild after editing embedded content, and check the DLL's mtime is newer than the file's
Reading a background task's output file right after launching itPlausible contents, so "the wait completed"You read a stale, empty, or partial file. One session's "29 minutes of sleeps" had actually elapsed 2 minutesCompare wall-clock elapsed against the expected duration, not just the contents
git cat-file -e "$ref:src/…" — the UNBRACED $ref:path form, in zshA confident present/absent verdict about a file on a refzsh applies a history modifier to unbraced $var:x. The path's FIRST CHARACTER picks which one, so the same typo fails in OPPOSITE directionsAlways brace BOTH: "${ref}:${path}"

🚨 The $ref:path trap deserves its own paragraph, because it fails in both directions and the direction depends on the path. This host's shell is zsh 5.9, and "$ref:src/Foo.cs" is not the string you wrote. Measured here, 2026-09-11, with ref=origin/main:

You wrotezsh expands it togit cat-file -eYou read
"$ref:src/…"origin/main — :s (substitute) swallowed the whole pathexit 0 (a commit object exists)PRESENT — falsely
"$ref:scripts/…"same :sexit 0PRESENT — falsely
"$ref:test/…"mainest/Foo.cs — :t (tail)exit 128ABSENT — falsely
"$ref:helm/…"originelm/values.yaml — :h (head)exit 128ABSENT — falsely
"$ref:deploy/…"unchangedcorrectcorrect, by luck — there is no :d modifier
"${ref}:${path}"origin/main:src/…correctcorrect, always

bash expands all six correctly, which is exactly why the shape survives review: it is right everywhere except the shell this host actually runs. src/ — the prefix a core session reaches for most — is the FALSE PRESENT, and a false present on "does main already carry this?" means skipping work that was never done. Pair it with the other half of that check: gate every gh api contents fetch on HTTP status and byte size, because an abbreviated sha 404s and the empty body greps to zero, which reads as absence.

Capping a run without timeout — timeout exists on CI's Linux runners, NOT on this macOS host. Locally: start the run in the background, hold the deadline yourself, and finish on the positive signal.

date -u                                                       # 1. record the start — UTC, so it compares with CI
dotnet build test/MeshWeaver.Data.Test/MeshWeaver.Data.Test.csproj   # 2. never skip: --no-restore alone runs nothing
dotnet test test/MeshWeaver.Data.Test --no-build \
  --report-xunit-trx --report-xunit-trx-filename run.trx \
  --results-directory "$PWD/.trx"                             # 3. run_in_background: true — MTP flags,
                                                              #    NOT --logger: the repo opts into
                                                              #    Microsoft.Testing.Platform in
                                                              #    global.json, and --logger there ends
                                                              #    the run as `Zero tests ran`, exit 5
date -u                                                       # 4. poll; over budget ⇒ WEDGED, not slow
ls -la .trx/run.trx                                           # 5. the pass signal: a .trx newer than step 1

Over budget means stuck — find what is not completing, never raise the bound (AGENTS.md → "No band-aids").

Checklist

  • I am in a worktree, not /Users/roland/code/MeshWeaver.
  • No git stash — patches instead.
  • dotnet build -c Release -warnaserror on every touched project + dependents, one project per invocation, unpiped, and it printed 0 Error(s).
  • Test runs were built first and produced a .trx newer than the run's start time.
  • The PR is not DIRTY; I have not merged main "just to catch up".

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

async

Free

Forwarding AccessContext through async/reactive boundaries, and the no-async rule on the actor-model mesh. Use when writing or reviewing any hub-reachable / Blazor-view / agent-round / IIoPool code that creates, reads, or updates a mesh node, OR when a write "silently does nothing" / "Access denied" appears after a .Subscribe / IIoPool / Observable.Create hop. The async/await/ToTask/.Wait/.Result/.GetAwaiter/FirstAsync family and lost AccessContext are the two ways async boundaries cause wedges and storms. Grounded in AsynchronousCalls.md, SyncedMeshNodeQueries.md, AccessContextPropagation.md.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

ci

Free

What CI proves, what it cannot prove, and how to write a gate that cannot pass on no evidence. Use when authoring or changing a GitHub Actions workflow, adding a required check, wiring a satellite repo CI, or reasoning about whether a green run actually covers your change. Covers the absolute no-skip-trapdoor rule (a gate must never carry continue-on-error on its input step nor an if that asks whether a secret is set — GitHub paints a skipped job the same colour as a passed one), the reusable workflow_call jobs satellite repos must call instead of hand-rolling, why runs on main are deliberately never cancelled, and the large body of in-mesh C# that no dotnet build or test ever type-checks.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

debug

Free

Debug a deadlock / hang / timeout in the mesh — a test that times out, a hub handler whose response never arrives, a GetRemoteStream / GetMeshNodeStream / GetQuery that never emits, an agent round or per-instance-hub activation that parks forever. Use whenever something times out and you need to find WHERE the message flow breaks down. The timeout is the symptom, never the bug — raising it just hangs longer. Grounded in DebuggingMessageFlow.md.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

Remove / reset a user (and their partition) on a running MeshWeaver portal (AKS). Use when you need to kick out a user — e.g. a throwaway test account — so they re-onboard from scratch. The normal delete API REFUSES a user's home ("user partition root … cannot be deleted"), so deletion is a Postgres-schema drop, not an MCP call. Covers where a user's data actually lives (per-user PG schemas named by BOTH id AND email, e.g. `rbuergi` + `rbuergi@systemorph.com`), how to reach PG (the connection string is inline in the portal's `ConnectionStrings__memex` env — NOT the `POSTGRES_PASSWORD` secret), the substring-match footgun (`buergi` also matches admin `rbuergi`), the in-memory resurrection gotcha (a recycle re-saves the node — a portal restart is what actually clears it), and the half-onboarded case where the user has NO schema at all (in-memory only → restart is the whole fix).

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

deploy

Free

Deploy MeshWeaver — the two routes (shared AKS cluster, and Azure Container Apps via the Aspire test/prod modes) and the traps that make a deploy look done when it is not. Use when rolling a code change onto a portal, standing up or patching an environment, or verifying that what is running is what you built. FIRST RULE (maintainer, 2026-09-08): on AKS an operation is a Hosting/InstanceAction on the control instance (Roll, Restart, Suspend, Audit, Reconcile, …) executed by the in-cluster operator — az aks command invoke / kubectl are break-glass, never the procedure. Also covers the bootstrap build-image / set-image / restart sequence the operator runs for you, why an env deploy.sh is first-time setup and not a code-update path, why the database migration is a run-once Job that a helm upgrade runs — never a Deployment to roll — and the DbVersionGate that makes a portal refuse to serve ahead of its schema.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

gui

Free

Build or review ANY MeshWeaver UI — layout areas, editable views, forms, tables, content editing, side-panel composers — by wiring the framework's EXISTING data-binding pieces, NEVER hand-rolling. The one rule is ALWAYS DATA-BIND, especially editable views: the backend layout area declares WHAT to render (a UiControl tree + node PATHS), and every value read / write-back happens on the GUI side through the per-node IMeshNodeStreamCache. Hand-woven binding — replicating a node into a /data/{id} copy + a save subscription, emitting HTML strings, hand-built selects/checkboxes, .Take(1) on a live stream, async/await/QueryAsync in a layout area — is the bug class behind "awaiting first data" / "renders empty" / a stuck editable view. Use when writing or reviewing a layout area, control, editor, form, table, or any data-bound view. Grounded in src/MeshWeaver.Layout/DataBinding/, Doc/GUI/DataBinding.md + Editor.md, the Edit extension (EditorExtensions.cs), and the node-bound editor controls.

The English summary is being prepared. Showing the original description.

Systemorph/MeshWeaver12Updated Oct 29, 2026

See all skills by Systemorph

Report a problem with this skill