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
14 changes: 7 additions & 7 deletions .agents/skills/comment-and-doc-style/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ boundary before repository mounts begin. Each Docker command has a timeout and v
Lint containers disable networking and mount the checkout read-only. Persist approval only when
the executor constrains that whole shape. Never allow an unconstrained `docker run` prefix.
PSScriptAnalyzer downloads its pinned module in a separate container that has network access and
no repository mount. `GOVERNANCE.md` "Running the Linters Locally (Known-Working Invocations)"
owns the exact invocation and full authorization model.
no repository mount. `GOVERNANCE.md`'s hub-only "Running the Linters Locally (Known-Working
Invocations)" section owns the exact invocation and full authorization model.

Agent-specific authorization stays in provider-labeled bullets so one agent's configuration does
not read as a shared requirement:

- **Codex:** rules cannot safely cover changing worktree paths and digests. Smart Approvals can
prompt per task. No-prompt operation is supported only inside an external sandbox because it
removes command-wide protection.
- **Codex:** execution rules match exact argument prefixes, so they cannot safely cover changing
worktree paths and digests. Smart Approvals can prompt per task. No-prompt operation is
supported only inside an external sandbox because it removes command-wide protection.

## Markdown formatting

Expand Down Expand Up @@ -230,7 +230,7 @@ hub-hosted tool the reader runs, are in `references/carried-doc-references.md`.
- **Rules**: no vague titles (`update stuff`, `wip`). Dependabot's default `Bump X from Y to Z`
titles are fine as-is. No `Co-Authored-By:` lines unless the developer explicitly asks. No
release-bump magnitude in the title ("minor", "patch", "release v0.2.0"), Nerdbank.GitVersioning
computes the next version from `version.json` and git history, a dependency version in a
computes the next version from `version.json` and git history. A dependency version in a
dependency-bump title is fine and expected. US English spelling, and title case with lowercase
short bind words (a, an, the, and, but, or, of, in, on, at, to, by, for, from), a hyphenated
compound capitalizes both parts unless the second is a short preposition (*Built-in*,
Expand All @@ -241,7 +241,7 @@ Add Structured Logging Extensions to Library
Pin softprops/action-gh-release to Commit SHA
Drop net8.0 Multi-Targeting from Console Project
Bump xunit.v3 from 3.2.2 to 3.3.0
Clarify devcontainer Setup Steps in README
Clarify Devcontainer Setup Steps in README
```

## Quantitative claims
Expand Down
13 changes: 8 additions & 5 deletions .agents/skills/dotnet-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ All builds must complete without warnings, enforced three ways:
surfaced as a warning fails the build and must be fixed or deliberately suppressed at the
narrowest scope that fits (see Analyzer suppressions below), never left to accumulate.
- **CI lint backstop.** CI runs the clean-compile checks on every PR as the authoritative gate.
A working local hook is strongly suggested, not optional: wire Husky.Net from the canonical
`catalog/snippets/husky/` config. See GOVERNANCE.md "Running the Linters Locally" for what the
hook must cover and what its absence means.
The .NET mechanism for a local hook is Husky.Net, wired from the canonical
`catalog/snippets/husky/` config in the hub, hub-local and not carried into every fleet repo.
GOVERNANCE.md's hub-only "Running the Linters Locally (Known-Working Invocations)" section
carries the obligation itself, what the hook must cover, its audit treatment, and the
per-clone enablement steps.

**A new port is not a license to silence diagnostics.** Brownfield or just-ported status never
justifies relaxing analyzer severities or muting newly surfaced warnings. Fix them. (The only
Expand Down Expand Up @@ -95,8 +97,9 @@ updates, dependency upgrades, benchmarks) on top:
`dotnet format style --verify-no-changes --severity=info --verbosity=detailed`.
- **`dotnet-outdated-tool`** checks for dependency updates, and Nerdbank.GitVersioning owns
version management.
- CI is the authoritative lint backstop. A local pre-commit hook is strongly suggested: wire
Husky.Net from `catalog/snippets/husky/` for local enforcement, including the shared doc gates.
- CI is the authoritative lint backstop. The .NET mechanism for a local pre-commit hook is
Husky.Net, wired from `catalog/snippets/husky/` in the hub, hub-local and not carried into every
fleet repo, and covering the shared doc gates alongside the language checks.
- **Required VS Code extensions**: CSharpier, markdownlint, CSpell. Use the workspace settings
without overrides.

Expand Down
17 changes: 10 additions & 7 deletions .agents/skills/python-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ repo's type checker: `uv run pyright`, or `uv run mypy src` where mypy is the CI
where the repo runs both (see Type checking above). Run it, plus `uv run pytest`, before
committing. A **lint-only** profile's clean-compile substitutes its `uvx` and `unittest`
equivalents, per Two Profiles above, and has no such command to run before committing beyond
those. These are documented commands, and an optional VS Code tasks mirror (all `type: process`,
no `&&` shell chaining, so it runs the same on any task shell) is in the hub
`vscode-tasks-python.json` snippet. CI runs the same clean-compile commands as the authoritative
backstop. A working local hook is strongly suggested, not opt-in: wire the Python `pre-commit`
framework from the canonical `catalog/snippets/pre-commit/.pre-commit-config.yaml`. See
GOVERNANCE.md "Running the Linters Locally" for what the hook must cover and what its absence
means.
those. These are documented commands, and the hub's `vscode-tasks-python.json` snippet carries the
VS Code tasks mirror that the fleet baseline expects. Every command-executing task in it is
`type: process`, and every aggregator is `dependsOn`-only. Neither chains with `&&`, so the mirror
runs the same on any task shell. CI runs the same clean-compile commands as the authoritative
backstop. The Python mechanism for a local hook is the `pre-commit` framework, wired from the
canonical `catalog/snippets/pre-commit/` directory, hub-local and not carried into every fleet
repo. That directory's own README names the second file to copy alongside the config.
GOVERNANCE.md's hub-only "Running the Linters Locally (Known-Working Invocations)" section carries
the obligation itself, what the hook must cover, its audit treatment, and the per-clone enablement
steps.

A restricted executor gives each task a cache directory under a writable temporary root. Point
`UV_CACHE_DIR`, `RUFF_CACHE_DIR`, `MYPY_CACHE_DIR`, and `COVERAGE_FILE` into that directory before
Expand Down
55 changes: 32 additions & 23 deletions .agents/skills/repo-worktree/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,14 @@ The base clone is a fetch source, not a place to do task work. `fetch` and `work
against it for that purpose, and outside "Listing and Cleanup"'s own terminal step below, nothing
else does: never `checkout`, `pull`, `reset`, `commit`, or any other command that mutates its own
working tree, index, or HEAD while a task is in progress. That distinction is the one a real
incident missed, reusing a primary checkout as the working directory itself rather than only as
the source a worktree is created from. On Claude Code this is also a mechanical stop for most
of that list. `merge --ff-only`/`pull --ff-only` and a `checkout <ref>`/`switch <ref>` carrying no
force flag stay exempt even there, matching this skill's own cleanup step below, which needs
exactly those.
Prose remains the only enforcement for a non-Claude-Code agent, and for the shapes the hook itself
exempts.
incident missed, where an agent reused a primary checkout as the working directory itself rather
than only as the source a worktree is created from. On a machine carrying the hub's agent-safety
install, Claude Code also makes this a mechanical stop for most of that list.
`merge --ff-only`/`pull --ff-only` stay exempt even there, and so does a `checkout <ref>`/`switch <ref>`
naming exactly one positional that resolves as a ref, with no force flag and no `--` separator,
which is the shape this skill's own cleanup step runs. A `checkout -- .` or a `switch -c <new>` is
denied, being neither. Prose remains the only enforcement for a non-Claude-Code agent, for a
machine without that install, and for the shapes the hook itself exempts.

## Creating a Worktree

Expand Down Expand Up @@ -129,18 +130,26 @@ command. A declared sandbox boundary is the reason to request that approval, not
reason to skip the registered worktree.

Use the standard layout when both locations are writable or the executor approves the scoped
write. When approval is unavailable or denied, create a standalone clone under a writable
temporary root. Name it `<temporary-root>/<Repo>-<task-slug>`, fetch immediately, and create the
task branch from `origin/develop`. A standalone clone keeps its worktree and Git administrative
directory under the same writable root. It therefore supports edits, explicit-path staging,
commits, and branch updates without sharing the base clone's index.
write. When approval for the worktree path is unavailable or denied, create a standalone clone
under a writable temporary root. Name it `<temporary-root>/<Repo>-<task-slug>`, fetch immediately,
and create the task branch from `origin/develop`. On Claude Code that clone needs a grant of its
own before its git steps will run, per the paragraph below, so ask for both together rather than
meeting the second after the clone exists. A standalone clone keeps its worktree and Git
administrative directory under the same writable root. It therefore supports edits, explicit-path
staging, commits, and branch updates without sharing the base clone's index.

On Claude Code, a standalone clone is structurally a primary checkout to `gh-write-guard.py`'s own
rule 6 test (`--git-dir` equals `--git-common-dir` there too, since it is not a linked worktree of
anything), so the hook denies the very commits/edits this fallback exists to make. Set
`GH_WRITE_GUARD_ALLOW_PRIMARY_CHECKOUT` for the session before using one -- the same escape hatch
`host-setup/agent-safety/README.md`'s requirement 6 already documents -- since this fallback is
exactly the narrow, already-approval-gated case that grant exists for.
anything), so the hook denies the git commands this fallback exists to run. Its rules classify git
and gh commands only, so a plain file edit is never denied there and only the git steps need the
grant, though a compound command is judged whole, so an edit chained to a denied git write does
not run either. That grant is `GH_WRITE_GUARD_ALLOW_PRIMARY_CHECKOUT`, the same escape hatch
`host-setup/agent-safety/README.md` in the hub already documents as its requirement 6, not a
repo-relative link since that path is hub-local and not carried into every fleet repo. The
maintainer sets it before the session starts, and an agent cannot set it for itself: the guard
reads it from the environment the session was launched with, never from an inline `VAR=x` prefix
or an `export` the agent runs, so ask for it rather than trying to set it mid-session. This
fallback is exactly the narrow, already-approval-gated case that grant exists for.

A temporary standalone clone is a degraded handoff, not an equivalent location. The base clone
does not register it, `git worktree list` does not show it, and an IDE opened on the base clone
Expand Down Expand Up @@ -168,13 +177,13 @@ git -C ~/repos/<Repo> fetch origin <task-branch>
git -C ~/repos/<Repo> worktree add ~/repos/worktrees/<Repo>-<task-slug> <task-branch>
```

When the base clone holds only the remote-tracking ref, the same command creates the local
branch tracking `origin/<task-branch>` through git's ordinary checkout guessing, so a fresh
clone needs no separate branch setup. Git refuses to attach a branch that is already checked
out somewhere else, and that refusal is the mandate working, since the branch sitting checked
out in a shared tree is the hazard the continuation rule exists for. Return that checkout to
its own working branch first when its tree is clean, and stop when it is not, because a dirty
tree there may be another task's uncommitted work.
When the base clone holds only the remote-tracking ref, the same command creates the local branch
tracking `origin/<task-branch>` through git's ordinary checkout guessing, so a fresh clone needs
no separate branch setup. Git refuses to attach a branch that is already checked out somewhere
else, and that refusal is the mandate working, since the branch sitting checked out in a shared
tree is the hazard the continuation rule exists for. Return that checkout to its own working
branch first when its tree is clean, and stop when it is not, because a dirty tree there may be
another task's uncommitted work.

A machine not yet migrated to this layout still isolates exactly the same way, since the mandate
is the isolation rather than the path: create the worktree beside whatever layout the machine
Expand Down
37 changes: 20 additions & 17 deletions .agents/skills/resync-a-repo/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,26 @@ anything else. The finding kind names the procedure the repo is owed.

## Reach the hub and measure before changing anything

Fetch a hub checkout of your own immediately before reading it, per RESYNC.md section 1, since a
stale clone answers confidently instead of failing. Never operate against an existing checkout
already present at a known or shared path, the maintainer's own primary checkout included, even
one that looks current -- always fetch into a private worktree of your own, per `repo-worktree`.
On Claude Code this is now also a mechanical stop for most such commands (a `PreToolUse` hook
denies a mutating git operation run directly in a primary checkout), though this prose is still
the only enforcement for a non-Claude-Code agent, and for the narrow shapes the hook itself
exempts, so following it here is not optional even where no hook can catch a lapse. Verify the
host with `python3 scripts/host_gate.py --repo <path-to-target-checkout>`. Then run the audit end
to end,
RESYNC.md section 2, against the target's `main` branch, never `develop`. A finding is a snapshot,
so quote the run stamp in anything derived from it and re-run before acting on a finding read
earlier in the session.
File any hub defect this work exposes against `ptr727/ProjectTemplate`.
Examples include bugs, conflicting sources, unclear or incomplete instructions, missing capabilities, and Copilot findings about any of them.
Search open and closed issues first, then update the matching issue or file a new one.
Preserve the evidence RESYNC.md section 2 requires, and do not leave the finding only in chat, a review thread, the downstream repo, or agent memory.
Fetch a hub checkout of your own immediately before reading it, per the hub-only `RESYNC.md`
section 1, a file fetched with the hub rather than present in a carrier, since a stale clone
answers confidently instead of failing. Never do the resync's own work in a checkout another task
may be using, the maintainer's own primary checkout included, even one that looks current: for the
hub and for the target repo alike, create a worktree of your own off that base clone and work
there, per `repo-worktree`. On a machine carrying the hub's agent-safety install, Claude Code also
refuses a mutating git command run directly in a primary checkout, though its rules classify git
and gh commands only, so a plain file write is never denied and the re-vendoring this skill exists
to govern goes uncaught. A compound command is judged whole, so a copy chained to a denied git
write does not run either. Prose is the enforcement here, and following it is not optional. Verify
the host with `python3 scripts/host_gate.py --repo <path-to-target-worktree>`, run from your hub
worktree, since `scripts/` is hub-hosted and no carrier holds it. Then run the audit end to end,
`RESYNC.md` section 2, against the target's `main` branch, never `develop`. A finding is a
snapshot, so quote the run stamp in anything derived from it and re-run before acting on a finding
read earlier in the session. File any hub defect this work exposes against
`ptr727/ProjectTemplate`. Examples include bugs, conflicting sources, unclear or incomplete
instructions, missing capabilities, and Copilot findings about any of them. Search open and closed
issues first, then update the matching issue or file a new one. Preserve the evidence `RESYNC.md`
section 2 requires, and do not leave the finding only in chat, a review thread, the downstream
repo, or agent memory.

## Apply, in this order

Expand Down
25 changes: 13 additions & 12 deletions .agents/skills/shell-codestyle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,35 @@ cover general scripting style.

Bash, and only where a program cannot be Python: a bootstrap that installs the interpreter cannot
be written in it, and a host tool that must run before a development toolchain exists cannot
depend on one. Everything else is Python, with a test under the scripts tree's `tests/` directory.
depend on Python either. Everything else is Python, with a test under its own scripts tree's
`tests/` directory.

## Rules

- **`shellcheck` is the linter and `shfmt` the formatter.** The clean-compile is `shellcheck`
clean at default severity plus `shfmt -d`, both reporting nothing before a commit. CI enforces
both, per `GOVERNANCE.md` "Running the Linters Locally", and `scripts/docker_lint.py` runs the
same pair headless. Neither is scoped to the `*.sh` glob alone: a tracked, extension-less
script whose shebang names bash or sh (the shape a script meant to run as a bare command takes)
joins the target list too.
both, per `GOVERNANCE.md`'s hub-only "Running the Linters Locally (Known-Working Invocations)"
section, and the hub's `scripts/docker_lint.py` runs the same pair headless. Neither is scoped
to the `*.sh` glob alone: a tracked, extension-less script whose shebang names bash or sh (the
shape a script meant to run as a bare command takes) joins the target list too.
- **`set -Eeuo pipefail`, before the first command the script runs.** A header comment sits above
it, as `repo-config/configure.sh` and the `host-setup/` scripts do, since what matters is that
nothing executes unguarded rather than which line number it lands on. Without `-e` a failed
command in the middle of a sequence lets the rest run against a state nobody checked, and
it, as the hub's own `repo-config/configure.sh` and `host-setup/` scripts do, since what matters
is that nothing executes unguarded rather than which line number it lands on. Without `-e` a
failed command in the middle of a sequence lets the rest run against a state nobody checked, and
without `pipefail` a pipeline reports the exit of its last stage, so a fetch that failed reads
as an answer when a parser downstream succeeds on an empty input. `-E` carries an `ERR` trap
into functions and command substitutions, so a script that later adds one is not surprised by
where it does not fire.
- **A reader that stops early needs its producer read first.** Under `pipefail`, a producer
writing to a closed pipe exits non-zero, so `curl ... | grep -q` reports a successful fetch as
a failure whenever the match is found early enough. Capture the output, then search it.
writing to a closed pipe exits non-zero, so `curl ... | grep -q` reports a successful fetch as a
failure whenever the match is found early enough. Capture the output, then search it.
- **Self-locating, never dependent on the caller's directory.** A script resolves its own
directory from `BASH_SOURCE` and references its payloads through it, since the working
directory at invocation is not a property of the script.
- **`shellcheck` clean, and a deliberate exception carries its reason inline.** A
`# shellcheck disable=SCxxxx` names why the rule does not apply here, so the next reader can
tell a considered exception from an unread warning. `repo-config/configure.sh` is the worked
example, carrying five `SC2016` disables where a single-quoted `jq` program must stay
tell a considered exception from an unread warning. The hub's own `repo-config/configure.sh` is
the worked example, carrying `SC2016` disables where a single-quoted `jq` program must stay
unexpanded, each with its reason on the same line.
- **Comments say why, never what.** The code states what it does. A comment restating it goes
stale silently, where a comment carrying a reason fails visibly when the reason stops being
Expand Down
Loading