tiny-pki 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tiny_pki-0.1.0/.agents/rules/git-commit-identity.md +117 -0
- tiny_pki-0.1.0/.agents/rules/github-api-throttle.md +19 -0
- tiny_pki-0.1.0/.agents/rules/github-content-formatting.md +19 -0
- tiny_pki-0.1.0/.agents/rules/no-secret-exposure.md +34 -0
- tiny_pki-0.1.0/.agents/rules/pr-ship-and-review.md +102 -0
- tiny_pki-0.1.0/.agents/rules/pre-pr-checks.md +53 -0
- tiny_pki-0.1.0/.agents/rules/read-agents-and-rules.md +15 -0
- tiny_pki-0.1.0/.agents/rules/remote-timeouts-retries.md +50 -0
- tiny_pki-0.1.0/.agents/rules/repo-practices-after-config-change.md +48 -0
- tiny_pki-0.1.0/.agents/rules/stacking-tool.md +46 -0
- tiny_pki-0.1.0/.cursor/rules/git-commit-identity.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/github-api-throttle.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/github-content-formatting.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/no-secret-exposure.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/pr-ship-and-review.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/pre-pr-checks.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/read-agents-and-rules.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/remote-timeouts-retries.mdc +7 -0
- tiny_pki-0.1.0/.cursor/rules/repo-practices-after-config-change.mdc +17 -0
- tiny_pki-0.1.0/.cursor/rules/stacking-tool.mdc +7 -0
- tiny_pki-0.1.0/.github/CODEOWNERS +2 -0
- tiny_pki-0.1.0/.github/ci/assert-uv-lock-version +64 -0
- tiny_pki-0.1.0/.github/ci/packaging +59 -0
- tiny_pki-0.1.0/.github/ci/pytest-cryptography-minimum +23 -0
- tiny_pki-0.1.0/.github/ci/pytest-hermetic +7 -0
- tiny_pki-0.1.0/.github/ci/python-static +10 -0
- tiny_pki-0.1.0/.github/ci/secret-scan +375 -0
- tiny_pki-0.1.0/.github/ci/setup-python +15 -0
- tiny_pki-0.1.0/.github/copilot-instructions.md +7 -0
- tiny_pki-0.1.0/.github/dependabot.yml +25 -0
- tiny_pki-0.1.0/.github/stacking-tool +1 -0
- tiny_pki-0.1.0/.github/workflows/ci.yml +169 -0
- tiny_pki-0.1.0/.github/workflows/cleanup-branch-on-merge.yml +25 -0
- tiny_pki-0.1.0/.github/workflows/cleanup-merged-branches.yml +109 -0
- tiny_pki-0.1.0/.github/workflows/cve-check.yml +226 -0
- tiny_pki-0.1.0/.github/workflows/dependabot-auto-merge.yml +33 -0
- tiny_pki-0.1.0/.github/workflows/release-please.yml +124 -0
- tiny_pki-0.1.0/.gitignore +34 -0
- tiny_pki-0.1.0/.python-version +1 -0
- tiny_pki-0.1.0/.release-please-manifest.json +3 -0
- tiny_pki-0.1.0/AGENTS.md +96 -0
- tiny_pki-0.1.0/CHANGELOG.md +39 -0
- tiny_pki-0.1.0/CLAUDE.md +5 -0
- tiny_pki-0.1.0/LICENSE +21 -0
- tiny_pki-0.1.0/PKG-INFO +154 -0
- tiny_pki-0.1.0/README.md +125 -0
- tiny_pki-0.1.0/RELEASING.md +61 -0
- tiny_pki-0.1.0/SECURITY.md +81 -0
- tiny_pki-0.1.0/docs/api.md +177 -0
- tiny_pki-0.1.0/docs/cli.md +289 -0
- tiny_pki-0.1.0/docs/defaults.md +56 -0
- tiny_pki-0.1.0/docs/monitoring.md +151 -0
- tiny_pki-0.1.0/docs/security-review/2026-09-25-claude-review.md +130 -0
- tiny_pki-0.1.0/docs/security-review/2026-09-26-grok-poc/repro.py +501 -0
- tiny_pki-0.1.0/docs/security-review/2026-09-26-grok-review.md +233 -0
- tiny_pki-0.1.0/docs/security-review/triage.md +49 -0
- tiny_pki-0.1.0/docs/security.md +46 -0
- tiny_pki-0.1.0/docs/store.md +124 -0
- tiny_pki-0.1.0/hatch_build.py +84 -0
- tiny_pki-0.1.0/pyproject.toml +95 -0
- tiny_pki-0.1.0/release-please-config.json +20 -0
- tiny_pki-0.1.0/scripts/embed_build_metadata +85 -0
- tiny_pki-0.1.0/scripts/tiny-pki +27 -0
- tiny_pki-0.1.0/src/tiny_pki/__init__.py +110 -0
- tiny_pki-0.1.0/src/tiny_pki/_build_metadata.py +6 -0
- tiny_pki-0.1.0/src/tiny_pki/_fsutil.py +55 -0
- tiny_pki-0.1.0/src/tiny_pki/_keys.py +74 -0
- tiny_pki-0.1.0/src/tiny_pki/bundle.py +59 -0
- tiny_pki-0.1.0/src/tiny_pki/check.py +318 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/__init__.py +1 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/commands.py +176 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/completer.py +91 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/completion.py +368 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/entry.py +27 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/handlers.py +969 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/main.py +281 -0
- tiny_pki-0.1.0/src/tiny_pki/cli/theme.py +51 -0
- tiny_pki-0.1.0/src/tiny_pki/constants.py +48 -0
- tiny_pki-0.1.0/src/tiny_pki/errors.py +16 -0
- tiny_pki-0.1.0/src/tiny_pki/inspect.py +99 -0
- tiny_pki-0.1.0/src/tiny_pki/issue.py +613 -0
- tiny_pki-0.1.0/src/tiny_pki/names.py +158 -0
- tiny_pki-0.1.0/src/tiny_pki/py.typed +0 -0
- tiny_pki-0.1.0/src/tiny_pki/revoke.py +88 -0
- tiny_pki-0.1.0/src/tiny_pki/secrets.py +87 -0
- tiny_pki-0.1.0/src/tiny_pki/store.py +1116 -0
- tiny_pki-0.1.0/src/tiny_pki/version.py +111 -0
- tiny_pki-0.1.0/tests/test_ca_constraints.py +316 -0
- tiny_pki-0.1.0/tests/test_check.py +389 -0
- tiny_pki-0.1.0/tests/test_cli_check.py +188 -0
- tiny_pki-0.1.0/tests/test_cli_check_files.py +232 -0
- tiny_pki-0.1.0/tests/test_cli_commands.py +366 -0
- tiny_pki-0.1.0/tests/test_cli_entry.py +31 -0
- tiny_pki-0.1.0/tests/test_cli_flag_completion.py +203 -0
- tiny_pki-0.1.0/tests/test_cli_shell.py +196 -0
- tiny_pki-0.1.0/tests/test_cli_strict_flags.py +118 -0
- tiny_pki-0.1.0/tests/test_completion.py +163 -0
- tiny_pki-0.1.0/tests/test_core.py +281 -0
- tiny_pki-0.1.0/tests/test_crl_days.py +168 -0
- tiny_pki-0.1.0/tests/test_crl_durability.py +125 -0
- tiny_pki-0.1.0/tests/test_crl_extensions.py +80 -0
- tiny_pki-0.1.0/tests/test_crl_rollback.py +139 -0
- tiny_pki-0.1.0/tests/test_crl_window.py +48 -0
- tiny_pki-0.1.0/tests/test_defaults_validity.py +206 -0
- tiny_pki-0.1.0/tests/test_dn_chars.py +99 -0
- tiny_pki-0.1.0/tests/test_docs.py +87 -0
- tiny_pki-0.1.0/tests/test_e2e_mtls_lifecycle.py +849 -0
- tiny_pki-0.1.0/tests/test_errors.py +66 -0
- tiny_pki-0.1.0/tests/test_export_symlink.py +122 -0
- tiny_pki-0.1.0/tests/test_inspect_fallbacks.py +74 -0
- tiny_pki-0.1.0/tests/test_key_types.py +217 -0
- tiny_pki-0.1.0/tests/test_leaf_profile.py +85 -0
- tiny_pki-0.1.0/tests/test_lookup_delete.py +111 -0
- tiny_pki-0.1.0/tests/test_max_leaf_validity.py +78 -0
- tiny_pki-0.1.0/tests/test_names.py +259 -0
- tiny_pki-0.1.0/tests/test_pkcs12.py +218 -0
- tiny_pki-0.1.0/tests/test_public_dir.py +134 -0
- tiny_pki-0.1.0/tests/test_readme.py +82 -0
- tiny_pki-0.1.0/tests/test_rotation.py +161 -0
- tiny_pki-0.1.0/tests/test_scaffold.py +53 -0
- tiny_pki-0.1.0/tests/test_secrets.py +150 -0
- tiny_pki-0.1.0/tests/test_store.py +905 -0
- tiny_pki-0.1.0/tests/test_store_api.py +141 -0
- tiny_pki-0.1.0/tests/test_store_hardening.py +214 -0
- tiny_pki-0.1.0/tests/test_store_lock.py +206 -0
- tiny_pki-0.1.0/tests/test_version.py +100 -0
- tiny_pki-0.1.0/uv.lock +392 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Commits and PRs attribute only the committer — no agent or machine co-authors
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Git commit identity
|
|
7
|
+
|
|
8
|
+
Commits and pull requests must attribute **only** whoever is making the commit — their configured git `user.name` and `user.email`. Do not leak hostnames, Cursor, or other co-authors.
|
|
9
|
+
|
|
10
|
+
## Commits
|
|
11
|
+
|
|
12
|
+
- Use plain `git commit -m "…"` or a HEREDOC with **subject and body only**.
|
|
13
|
+
- Do **not** add `Co-authored-by`, `Made-with: Cursor`, or any `--trailer` flags.
|
|
14
|
+
- Do **not** append attribution lines to commit messages, even if Cursor defaults would add them.
|
|
15
|
+
- Do **not** pass `--no-gpg-sign` (or otherwise skip signing) when `commit.gpgsign` is enabled.
|
|
16
|
+
- After any commit (hooks / tooling may rewrite the message), inspect `git show -s --format=%B HEAD` before push. If it contains `Co-authored-by:` or `Made-with:`, **stop**, fix the message, and do not push until clean.
|
|
17
|
+
- Prefer `git verify-commit HEAD` after signing commits; confirm GitHub shows the commit as Verified once pushed.
|
|
18
|
+
|
|
19
|
+
## Pre-submit verification
|
|
20
|
+
|
|
21
|
+
Before **`submit-stack`** / **`ship-and-review`**, every non-merge commit on the stack branch ahead of `main` / `origin/main` must pass local **`git verify-commit`**. After push, confirm GitHub shows **Verified** on the PR commits tab (or `gh api repos/{owner}/{repo}/commits/<sha> --jq .commit.verification.verified`).
|
|
22
|
+
|
|
23
|
+
`scripts/dev/pre-pr-checks` runs the **`verified-commits`** job for that range. It checks both the **signature** (`reason=local` / `reason=github`) and the **message attribution** (`reason=trailer`, matched case-insensitively): a `Co-authored-by:`, `Made-with:`, or non-committer `Signed-off-by:` trailer, or a whole-line `[🤖 ]Generated with [Name](url)` footer (anchored to that exact shape — prose elsewhere in the body that merely discusses the phrase or emoji is not flagged); or an author email matching a known agent identity — `opencode@users.noreply.github.com`, the `claude`/`cursoragent`/`devin` localparts and their known domains (bounded so real human names like "claudette" don't collide), or any other `*@users.noreply.github.com` address that differs from the committer's own (a fully agent-authored-and-committed commit is still caught: the specific agent patterns are not exempted just because author equals committer). Do not submit if it fails with `ERROR: UNVERIFIED_COMMIT`. Fix signing setup (see below) or amend the message and recommit. Escape hatches: `PRE_PR_CHECKS_SKIP=verified-commits` skips the whole job; `PRE_PR_CHECKS_ALLOW_COAUTHOR=email1,email2` allowlists a specific email as a real human identity for the rare case the operator explicitly wants it — a `Co-authored-by:` trailer, or an author email from a rebased/cherry-picked teammate commit — use only when the operator asked for it, not to bypass a failing check.
|
|
24
|
+
|
|
25
|
+
## Pull requests
|
|
26
|
+
|
|
27
|
+
- Do **not** add `Co-authored-by` or `Made-with: Cursor` to `gh pr create --body` or `gh pr edit --body`.
|
|
28
|
+
|
|
29
|
+
## Git identity
|
|
30
|
+
|
|
31
|
+
- Rely on git's configured author for the current committer (`git config user.name` and `git config user.email`). Do not hardcode a specific name or email.
|
|
32
|
+
- If `user.email` is unset, stop and ask the committer to configure git before committing (avoid hostname fallback addresses like `user@machine.local`).
|
|
33
|
+
- Also survey **effective** identity (env overrides beat config): compare `git var GIT_AUTHOR_IDENT` and `git var GIT_COMMITTER_IDENT` to the approved GitHub name/email. Reject machine-local addresses (e.g. `*.local`) and stop if `GIT_AUTHOR_*`, `GIT_COMMITTER_*`, `EMAIL`, or `git commit --author` would produce a different identity than configured.
|
|
34
|
+
|
|
35
|
+
## Commit signing (GPG / SSH)
|
|
36
|
+
|
|
37
|
+
At the **start of any session where the agent may commit**, survey whether commit signing is set up for the committer:
|
|
38
|
+
|
|
39
|
+
1. `git config --get commit.gpgsign` should be `true` (global or local, as they intend).
|
|
40
|
+
2. `git config --get user.signingkey` should be set (GPG key id, or SSH public key path when `gpg.format` is `ssh`).
|
|
41
|
+
3. Check `git config --get gpg.format` (and any repo-local override). For GPG signing, prefer `openpgp` (or unset). If a leftover `gpg.format=ssh` is set while `user.signingkey` is a GPG key id, Git will mis-treat the key — set `gpg.format` to `openpgp` (or unset ssh) before committing.
|
|
42
|
+
4. If `gpg.format` is `ssh`, confirm the public key path exists **and** the matching private key is loaded (`ssh-add -L` should list it), or run a real signed-commit probe. Otherwise confirm `gpg --list-secret-keys --keyid-format=long <signingkey>` succeeds (secret present on **this** host).
|
|
43
|
+
5. On Darwin (GPG): `pinentry-program` in `~/.gnupg/gpg-agent.conf` should point at an existing binary (prefer `pinentry-mac` from Homebrew).
|
|
44
|
+
6. Optional one-shot probe: `echo test | gpg --clearsign -u <KEYID>`. If it hangs or fails in the agent TTY, tell the operator to unlock via GUI pinentry or finish the commit in Terminal.app — agent terminals often cannot drive curses pinentry.
|
|
45
|
+
7. GitHub Verified checks depend on signing format:
|
|
46
|
+
- **OpenPGP** (`gpg.format` is `openpgp` or unset): the **committer email** must appear on the GPG key UID and be a **verified** email on the GitHub account (same value as `git config user.email`). Optional list check: `gh api user/gpg_keys` (needs `read:gpg_key`; `admin:gpg_key` also works). If the API is unavailable, guide manual paste of `gpg --armor --export <KEYID>`.
|
|
47
|
+
- **SSH** (`gpg.format=ssh`): UID / `user/gpg_keys` do **not** apply. Confirm the configured public key is registered on GitHub as a **Signing Key** (not only Authentication) and that `ssh-add -L` lists the matching private key.
|
|
48
|
+
|
|
49
|
+
If signing is missing or incomplete, **alert the committer** and surface setup instructions before committing (unless they explicitly opt out for a one-off).
|
|
50
|
+
|
|
51
|
+
### Per-machine / personal vs work keys
|
|
52
|
+
|
|
53
|
+
- Prefer a **separate signing key per machine** (or at least personal vs work). Do **not** export a personal laptop’s secret key onto a corporate device.
|
|
54
|
+
- Match `user.name` / `user.email` to the GitHub identity. For OpenPGP, put that same verified email in the GPG UID; upload **that** public key to GitHub → Settings → SSH and GPG keys. For SSH signing, upload the public key as a Signing Key.
|
|
55
|
+
- When a work machine is retired, revoke/rotate that machine’s key on GitHub and remove the local secret.
|
|
56
|
+
|
|
57
|
+
### Passphrase
|
|
58
|
+
|
|
59
|
+
- **Recommend using a passphrase** on the signing key (protects the secret at rest; `gpg-agent` can cache it with `default-cache-ttl` / `max-cache-ttl`).
|
|
60
|
+
- Do **not** suggest empty-passphrase keys “for agent convenience.”
|
|
61
|
+
- Agent / non-TTY sessions usually cannot drive curses pinentry — use GUI `pinentry-mac` (macOS) or commit from Terminal.app after unlocking once.
|
|
62
|
+
|
|
63
|
+
### GPG key (macOS / Homebrew)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
brew install gnupg pinentry-mac
|
|
67
|
+
# If brew cannot link into /opt/homebrew/bin (ownership / permissions), fix Homebrew
|
|
68
|
+
# ownership for that prefix or use the full $(brew --prefix)/bin path below.
|
|
69
|
+
|
|
70
|
+
mkdir -p ~/.gnupg
|
|
71
|
+
chmod 700 ~/.gnupg
|
|
72
|
+
echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf
|
|
73
|
+
# optional passphrase cache (seconds), so you are not prompted every commit:
|
|
74
|
+
# echo "default-cache-ttl 28800" >> ~/.gnupg/gpg-agent.conf
|
|
75
|
+
# echo "max-cache-ttl 86400" >> ~/.gnupg/gpg-agent.conf
|
|
76
|
+
gpgconf --kill gpg-agent
|
|
77
|
+
|
|
78
|
+
gpg --full-generate-key
|
|
79
|
+
# Choose RSA (or default), key size ≥ 3072, set an expiration, and use a passphrase.
|
|
80
|
+
# UID email must be a GitHub-verified address matching git config user.email.
|
|
81
|
+
gpg --list-secret-keys --keyid-format=long
|
|
82
|
+
git config --global gpg.format openpgp
|
|
83
|
+
git config --global user.signingkey <KEYID>
|
|
84
|
+
git config --global commit.gpgsign true
|
|
85
|
+
# Clear a leftover repo-local ssh signing override if present:
|
|
86
|
+
# git config --unset gpg.format # run inside the repo if it forced ssh
|
|
87
|
+
gpg --armor --export <KEYID>
|
|
88
|
+
# Upload the armored public key: GitHub → Settings → SSH and GPG keys → New GPG key
|
|
89
|
+
|
|
90
|
+
# Sanity check (GUI pinentry should appear if the agent needs the passphrase):
|
|
91
|
+
echo test | gpg --clearsign -u <KEYID>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### SSH signing (alternative)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git config --global gpg.format ssh
|
|
98
|
+
git config --global user.signingkey ~/.ssh/id_ed25519.pub
|
|
99
|
+
git config --global commit.gpgsign true
|
|
100
|
+
ssh-add -L # private key must be available via ssh-agent
|
|
101
|
+
# Add the same public key on GitHub as a Signing Key (not only Authentication)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Cursor CLI attribution (per machine)
|
|
105
|
+
|
|
106
|
+
At the **start of any session where the agent may commit or open PRs**, read `~/.cursor/cli-config.json` (if present) and verify attribution is disabled:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
"attribution": {
|
|
110
|
+
"attributeCommitsToAgent": false,
|
|
111
|
+
"attributePRsToAgent": false
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If the file is missing, unreadable, or either flag is not `false`, **alert the committer** before committing and surface setup instructions — explain that Cursor will inject co-author trailers unless they fix their local config. Provide the exact keys to set (or create the file with the block above). Also remind them to disable **Settings → Git & PRs → Attribution** in the Cursor IDE (IDE and CLI settings are separate).
|
|
116
|
+
|
|
117
|
+
Do not commit on their behalf until they acknowledge or fix the config (unless they explicitly opt out for a one-off commit).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Every gh call site, agent or first-party code, must run through scripts/gh-api
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GitHub API rate-limit throttle
|
|
7
|
+
|
|
8
|
+
Every `gh` call site — PR / issue triage, review replies, CI polling, `gh api`, `gh pr` / `gh issue` reads and writes, and any first-party script or library function in this repo that shells out to `gh` — **must** run through the throttled wrapper, never `gh` directly:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
"${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}/scripts/gh-api" <gh args…>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
so GitHub primary **and** secondary rate-limit backoff is automatic. A direct `gh` call 403s hard once the secondary limiter trips. First-party library code that already runs inside a bash process may instead source `scripts/lib/github-api-rate-limit` and call `github_api_exec_with_rate_limit_retry` directly — the same underlying backoff, without a redundant child-script fork per call.
|
|
15
|
+
|
|
16
|
+
Full rationale, the two conforming shapes, the known cross-process quota gap (repository-helpers#664), exemptions (`auth`, prompts, `--web`), and `scripts/gh-api --help` (the SSOT) — the canonical rule in repository-helpers:
|
|
17
|
+
|
|
18
|
+
<!-- github-api-throttle-canonical: https://github.com/the-hcma/repository-helpers/blob/main/.agents/rules/github-api-throttle.md -->
|
|
19
|
+
https://github.com/the-hcma/repository-helpers/blob/main/.agents/rules/github-api-throttle.md
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Format agent-authored GitHub issue/PR bodies and comments so they render correctly (blank lines + no hand-wrapped paragraphs)
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GitHub content formatting (agent-authored)
|
|
7
|
+
|
|
8
|
+
Agent-authored issue bodies, PR descriptions, and PR/review comments must render correctly on GitHub: separate paragraphs and list items with a blank line, and write one physical line per paragraph — GitHub's issue/PR/comment renderer treats a lone `\n` as a **visible hard break**, unlike the file/blob renderer's soft-break-as-space.
|
|
9
|
+
|
|
10
|
+
Write multi-paragraph or multi-line-list bodies to a temp file and post with `--body-file <path>`, never an inline `--body "..."` string with embedded `\n` escapes. Lint before posting:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
"${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}/scripts/lint-github-markdown" <path>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Full authoring rules, the pre-flight linter, and `scripts/gh-issue` — the canonical rule in repository-helpers:
|
|
17
|
+
|
|
18
|
+
<!-- github-content-formatting-canonical: https://github.com/the-hcma/repository-helpers/blob/main/.agents/rules/github-content-formatting.md -->
|
|
19
|
+
https://github.com/the-hcma/repository-helpers/blob/main/.agents/rules/github-content-formatting.md
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Never leak secrets into logs, transcripts, PRs, commits, or fixtures
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# No secret exposure
|
|
7
|
+
|
|
8
|
+
Never leak secrets into shell/tool/transcript logs, PR/issue text, review replies, commits, fixtures, or docs. Complements CI secret-scan (prevention vs detection). See repository-helpers#566.
|
|
9
|
+
|
|
10
|
+
## Never print or paste
|
|
11
|
+
|
|
12
|
+
Do **not** print passwords, API keys, PATs, webhook/client secrets, tokens, private keys, Fernet/master keys; full `.env` / `config.toml` / token-cache / auth-record dumps; or `Authorization` headers with tokens.
|
|
13
|
+
|
|
14
|
+
## Inspecting config
|
|
15
|
+
|
|
16
|
+
Prefer allowlisted non-secret keys **or** path-existence only; redact sensitive values. Do **not** `cat` whole configs.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# bad
|
|
20
|
+
cat .env
|
|
21
|
+
# good
|
|
22
|
+
test -f .env
|
|
23
|
+
rg -n '^(APP_ENV|LOG_LEVEL)=' .env
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Same idea for `~/.config/*/config.toml`, token-cache, and auth-record files: existence or allowlisted keys only — not denylist `sed` of a full dump.
|
|
27
|
+
|
|
28
|
+
## Commits and fixtures
|
|
29
|
+
|
|
30
|
+
Never commit secrets, `.env`, or private config. Never put secrets in PR text. Fixtures use obvious fakes only.
|
|
31
|
+
|
|
32
|
+
## If leaked
|
|
33
|
+
|
|
34
|
+
Tell the operator to **rotate** the credential. Do **not** repeat the secret in logs, replies, or follow-ups.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Ship a PR end-to-end — local gates, submit, agent review loop, operator email
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PR ship, agent review, and operator email
|
|
7
|
+
|
|
8
|
+
When the user asks to **ship**, **submit**, **open a PR**, or **follow the flow**, run this sequence in a **stack worktree** (never the primary clone). Read `.github/stacking-tool` and `.cursor/rules/stacking-tool.mdc` before creating branches or submitting.
|
|
9
|
+
|
|
10
|
+
Helper scripts live in **repository-helpers** (canonical agent review loop):
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
rh="${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}"
|
|
14
|
+
"${rh}/scripts/wait-for-agent-review" …
|
|
15
|
+
"${rh}/scripts/trigger-agent-review" …
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Configure `~/.config/agent-review.env` from `${rh}/etc/agent-review.env.example` (`AGENT_REVIEW_REPORT_TO`, SMTP).
|
|
19
|
+
|
|
20
|
+
<!-- pr-ship-canonical-skill: https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/ship-and-review/SKILL.md -->
|
|
21
|
+
<!-- pr-ship-canonical-rule: https://github.com/the-hcma/repository-helpers/blob/main/.agents/rules/pr-ship-and-review.md -->
|
|
22
|
+
|
|
23
|
+
**Canonical playbook (read first):** This file is a consumer summary. Exit codes, early-complete semantics, quota chains, and triage details are maintained in repository-helpers and may change between releases.
|
|
24
|
+
|
|
25
|
+
Agents **must** read the canonical Skill before running the agent review loop:
|
|
26
|
+
|
|
27
|
+
- **GitHub (`main`):** https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/ship-and-review/SKILL.md
|
|
28
|
+
- **Local clone (when `${rh}` is synced to `main`):** `${rh}/.agents/skills/ship-and-review/SKILL.md`
|
|
29
|
+
|
|
30
|
+
When this summary and the canonical Skill disagree, follow the canonical Skill.
|
|
31
|
+
|
|
32
|
+
## 1. Local quality gates (all must pass before submit)
|
|
33
|
+
|
|
34
|
+
Run this repository's quality gates from the stack worktree (tests, linters, etc.).
|
|
35
|
+
|
|
36
|
+
## 2. Commit and submit
|
|
37
|
+
|
|
38
|
+
Only after §1 quality gates pass. **Read** `.github/stacking-tool` (`graphite` or `gh-stack`) and follow `.cursor/rules/stacking-tool.mdc` — do not mix backends on the same stack.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# When marker is graphite (apply-fix comments the inactive backend):
|
|
42
|
+
# gt create <stack>/<topic> -m 'feat: …' # or gt modify -m '…'
|
|
43
|
+
# gt submit --publish --no-interactive
|
|
44
|
+
|
|
45
|
+
# When marker is gh-stack:
|
|
46
|
+
gh stack init <stack>/<topic> # or gh stack add for a higher layer
|
|
47
|
+
git add -A && git commit -m 'feat: …'
|
|
48
|
+
gh stack submit --auto --open --remote origin
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Wait for CI:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
"${rh}/scripts/dev/post-pr-submission-checks" --pr <n>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If stderr shows `NOTE: GITHUB_RATE_LIMIT_*`, the helpers are waiting on GitHub API quota reset — let them finish (do not treat as a hard local failure mid-wait).
|
|
58
|
+
|
|
59
|
+
Patch title/body if stale: `gh pr edit <n> --title … --body …`
|
|
60
|
+
|
|
61
|
+
## 3. Agent review loop
|
|
62
|
+
|
|
63
|
+
> **Reply before resolve (required):** For every valid agent review thread (Copilot, Bugbot, CodeRabbit, …), post an **on-thread human reply** as the authenticated operator **before** resolving. Exit code **3** means threads **lack a human reply** — resolving without replying is non-compliant.
|
|
64
|
+
|
|
65
|
+
**Prerequisites:** `gh auth` must be set up for the operator running the loop. Copy `${rh}/etc/agent-review.env.example` to `~/.config/agent-review.env` with `AGENT_REVIEW_REPORT_TO` and SMTP before `complete`. `complete_ready: true` is reported by `"${rh}/scripts/wait-for-agent-review" check --pr <n>` (or `status`) JSON when CI is green and agent review threads are clear.
|
|
66
|
+
|
|
67
|
+
Prefer the built-in loop:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
"${rh}/scripts/wait-for-agent-review" loop --pr <n>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Early complete:** when all threads are addressed, CI is green, there is **no** pending requested Copilot/Bugbot review, and CodeRabbit’s workflow is **not** running, the loop finishes — no mandatory idle dwell. **12h PR cap** (`AGENT_REVIEW_PR_TIMEOUT`) when review cycles never converge (exit **6** give-up). Per-agent quota caches skip exhausted agents (CodeRabbit, Copilot, Bugbot).
|
|
74
|
+
|
|
75
|
+
**CodeRabbit is on_push:** a new push starts CodeRabbit — never post `@coderabbitai review`. If quota-limited, wait the cooldown with feedback polls (issue #369; default poll **60s**) + grace (default **60s**); only then, if still no real review on head, the loop may post a one-shot `@coderabbitai full review`. When CodeRabbit says wait, do not re-ask until `retry_after`. Rate-limit stubs are not reviews. Mid-cooldown pending feedback wakes the loop (exit **3**).
|
|
76
|
+
|
|
77
|
+
When `loop` exits **3**, triage each unaddressed agent thread:
|
|
78
|
+
|
|
79
|
+
1. Fix in the worktree when actionable (or skip with a brief on-thread reason).
|
|
80
|
+
2. **Reply on-thread** as the authenticated human:
|
|
81
|
+
```bash
|
|
82
|
+
"${rh}/scripts/wait-for-agent-review" reply-thread --thread-id <PRRT_…> --body 'Fixed in abc1234: …'
|
|
83
|
+
```
|
|
84
|
+
3. **Resolve only after step 2:**
|
|
85
|
+
```bash
|
|
86
|
+
"${rh}/scripts/wait-for-agent-review" resolve-thread --thread-id <PRRT_…>
|
|
87
|
+
```
|
|
88
|
+
Or batch: `"${rh}/scripts/wait-for-agent-review" resolve-addressed --pr <n>` (requires an existing human reply per thread).
|
|
89
|
+
|
|
90
|
+
**Never** resolve via raw GraphQL/API without an on-thread human reply first.
|
|
91
|
+
|
|
92
|
+
Then push fixes, re-run `"${rh}/scripts/dev/post-pr-submission-checks" --pr <n>`, and start the next loop iteration.
|
|
93
|
+
|
|
94
|
+
When `check` reports `complete_ready: true`:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
"${rh}/scripts/wait-for-agent-review" complete --pr <n>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`complete_ready` requires an agent sign-off on the current head (not a bare CodeRabbit commit status / rate-limit stub). This emails `AGENT_REVIEW_REPORT_TO`. It does **not** run `gh pr review --approve` (self-approve is skipped; merge stays an explicit operator step).
|
|
101
|
+
|
|
102
|
+
Do **not** add `merge-it` unless the user explicitly confirms. Org merge path is GitHub auto-merge (`gh pr merge --auto --squash` / Enable auto-merge) when the operator asks to merge.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Block PR submit until pre-pr-checks pass; format before check; no truncated output
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pre-PR checks (required)
|
|
7
|
+
|
|
8
|
+
`pre-pr-checks` lives in **repository-helpers**, not in this repo. Resolve the clone once:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
rh="${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`pre-pr-checks` resolves its target from `$PWD`, so it audits **this** repo when run from a feature worktree here. The `submit-stack` wrapper does **not** — it resolves the repo from its own path and would submit the repository-helpers clone, so consumers submit with a bare marker-aware command (not `"${rh}/scripts/dev/submit-stack"`).
|
|
15
|
+
|
|
16
|
+
Before submitting a PR:
|
|
17
|
+
|
|
18
|
+
1. Run **`"${rh}/scripts/dev/pre-pr-checks"`** from this repo's feature worktree (must exit 0), then submit from the same worktree with the marker-aware bare command: **`gh stack submit --auto`** when `.github/stacking-tool` is `gh-stack`. When the marker is `graphite`, follow `.agents/rules/stacking-tool.md` / the Graphite skill (do not paste a Graphite-only submit into this rule). Do **not** use `"${rh}/scripts/dev/submit-stack"` from here.
|
|
19
|
+
|
|
20
|
+
2. Do **not** submit if pre-pr-checks failed or was skipped. A skipped job is allowed **only** when the user has approved it for this PR: pass `PRE_PR_CHECKS_SKIP=job1,job2` (never a silent skip) and record the skipped jobs and the reason in the PR **Test plan**.
|
|
21
|
+
|
|
22
|
+
3. In the PR **Test plan**, note that `"${rh}/scripts/dev/pre-pr-checks"` passed (paste the final `==> pre-pr-checks passed` line from the full run).
|
|
23
|
+
|
|
24
|
+
4. Scripts must not leave changes on the **primary (main) worktree**.
|
|
25
|
+
|
|
26
|
+
## Apply formatters before check (required)
|
|
27
|
+
|
|
28
|
+
`pre-pr-checks` is **check-only** by default (e.g. `ruff format --check`, `cargo fmt -- --check`). After review-fix edits — especially string literals — **apply** formatters first, then run the gate:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Python (match CI paths; adjust for the repo)
|
|
32
|
+
uv run ruff format .
|
|
33
|
+
# Rust
|
|
34
|
+
cargo fmt --all
|
|
35
|
+
# Then the gate
|
|
36
|
+
"${rh}/scripts/dev/pre-pr-checks"
|
|
37
|
+
# Or apply + check in one shot (mutates the worktree):
|
|
38
|
+
"${rh}/scripts/dev/pre-pr-checks" --fix
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Commit any format-only diff before submit. Do **not** treat a green `pytest` / `ruff check` / partial job as a pre-PR pass.
|
|
42
|
+
|
|
43
|
+
## No truncated pre-PR output
|
|
44
|
+
|
|
45
|
+
Do **not** pipe `pre-pr-checks` to `tail` / `head`. Require exit **0** and the final `==> pre-pr-checks passed` line from the full run.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# ❌ Truncated — hides failures above the last few lines
|
|
49
|
+
"${rh}/scripts/dev/pre-pr-checks" 2>&1 | tail -8
|
|
50
|
+
|
|
51
|
+
# ✅ Full output + exit status
|
|
52
|
+
"${rh}/scripts/dev/pre-pr-checks"
|
|
53
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: On every new agent session, read AGENTS.md and .agents/rules before acting
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Session start: read AGENTS.md and project rules
|
|
7
|
+
|
|
8
|
+
At the **start of every new agent session** (before implementing, editing, or answering from assumed conventions), actively load project guidance:
|
|
9
|
+
|
|
10
|
+
1. **Read** `AGENTS.md` at the repository root when it exists (use the Read tool; do not rely only on auto-injected snippets).
|
|
11
|
+
2. **List** `.agents/rules/*.md` and **read** each rule that applies to this session — at minimum every `alwaysApply: true` rule, plus any glob-matched rules for files you will touch. `.cursor/rules/*.mdc` files are Cursor injection shims only (frontmatter + pointer to the matching `.agents/rules/` file); do not treat the shim body as the rule.
|
|
12
|
+
|
|
13
|
+
Do this on the first turn of a new conversation even if some guidance already appears in context — confirm the on-disk files are what you follow.
|
|
14
|
+
|
|
15
|
+
If `AGENTS.md` is missing, note that and continue with `.agents/rules/` only. Do not invent org conventions that are not in those files.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: All remote/network I/O must use explicit timeouts and bounded retries
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Remote timeouts and retries
|
|
7
|
+
|
|
8
|
+
Any code that talks to a network peer (HTTP APIs, OAuth token endpoints, webhooks, package indexes, `gh`/`curl` helpers, cloud SDKs, etc.) must not hang indefinitely and must not retry without a bound. See repository-helpers#570.
|
|
9
|
+
|
|
10
|
+
## Timeouts (required)
|
|
11
|
+
|
|
12
|
+
- Set an **explicit timeout** on every remote call (connect + read, or a single overall deadline the library supports).
|
|
13
|
+
- Prefer the product's shared HTTP client / config timeout knob when one exists. Defaults must be finite and documented. Never leave library defaults that mean "wait forever."
|
|
14
|
+
- Agent / shell wrappers that hit the network should use the helpers' `--timeout` / `run_command … --timeout` patterns when available.
|
|
15
|
+
- For GitHub API work, honor rate-limit / secondary-limit waits (`GITHUB_API_RATE_LIMIT` / documented cooldown helpers) rather than spinning.
|
|
16
|
+
|
|
17
|
+
## Retries (required when retrying)
|
|
18
|
+
|
|
19
|
+
- Retries are for **transient** failures only (timeouts, 429, 502/503/504, reset).
|
|
20
|
+
- Cap attempts (small fixed `N`, typically 2–5) **or** a total retry budget.
|
|
21
|
+
- Back off between attempts (exponential with jitter when practical). Honor `Retry-After` when the peer sends it.
|
|
22
|
+
- Do **not** retry non-idempotent writes unless the API contract is safe (dedupe keys / explicit idempotency). Prefer fail fast on 4xx except 408/429.
|
|
23
|
+
- Log or surface a clear timeout/retry exhaustion error — never spin silently.
|
|
24
|
+
|
|
25
|
+
## Product-specific
|
|
26
|
+
|
|
27
|
+
Wire timeouts through the repo's shared HTTP client / config knob. Do not add one-off unbounded clients beside that shared path.
|
|
28
|
+
|
|
29
|
+
## Anti-patterns
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
# bad — no timeout
|
|
33
|
+
requests.get(url)
|
|
34
|
+
httpx.get(url)
|
|
35
|
+
client.execute() # SDK call with no timeout / retry policy
|
|
36
|
+
|
|
37
|
+
# bad — unbounded retry
|
|
38
|
+
while True:
|
|
39
|
+
try:
|
|
40
|
+
return call()
|
|
41
|
+
except TimeoutError:
|
|
42
|
+
continue
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# good — timeout from config + bounded retries
|
|
47
|
+
http.timeout = httpx.Timeout(timeout_s, connect=min(30.0, timeout_s))
|
|
48
|
+
# or: run_command "label" --timeout 20 -- curl …
|
|
49
|
+
request_with_retries(call, max_attempts=3, retry_after_header=True)
|
|
50
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run github-repo-lint after repo config or workflow changes
|
|
3
|
+
globs:
|
|
4
|
+
- .agents/rules/**
|
|
5
|
+
- .agents/skills/**
|
|
6
|
+
- .cursor/rules/**
|
|
7
|
+
- .github/**
|
|
8
|
+
- pnpm-workspace.yaml
|
|
9
|
+
- release-please-config.json
|
|
10
|
+
- .release-please-manifest.json
|
|
11
|
+
- scripts/lib/repo-practices-workflows/**
|
|
12
|
+
- web/pnpm-workspace.yaml
|
|
13
|
+
alwaysApply: false
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Repo practices lint after config changes
|
|
17
|
+
|
|
18
|
+
When you edit **repo-practices-sensitive** paths — workflows, dependabot, Release Please config, pnpm release age, org agent rules/skills, `.github/ci/*`, or canonical workflow templates under `scripts/lib/repo-practices-workflows/` — **before submit**:
|
|
19
|
+
|
|
20
|
+
## 1. Audit (required)
|
|
21
|
+
|
|
22
|
+
From a synced **repository-helpers** clone (or this repo when you are in it):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
scripts/github-repo-lint --repo OWNER/NAME --suggest --strict-onboarding
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Resolve `OWNER/NAME` from `git remote get-url origin`. When not in repository-helpers, use `${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}/scripts/github-repo-lint`.
|
|
29
|
+
|
|
30
|
+
Fix every `FAIL` before merge. Treat `SUGGEST` lines as follow-ups unless they block your change (e.g. missing `--apply-fix` merge settings when adding Release Please).
|
|
31
|
+
|
|
32
|
+
## 2. GitHub-side fixes
|
|
33
|
+
|
|
34
|
+
When adding **Release Please**, changing **merge/release settings**, or adopting org workflow templates, also run (mutates GitHub repo settings; run from the target clone when queuing workflow PRs):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
scripts/github-repo-lint --repo OWNER/NAME --apply-fix
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 3. uv + Release Please jsonpath
|
|
41
|
+
|
|
42
|
+
Copy `scripts/lib/repo-practices-workflows/release-please-uv-lock-extra-files.snippet.json` into `release-please-config.json` `extra-files`. The jsonpath **must** use `@.name.value`, not plain `@.name` — otherwise Release Please silently skips `uv.lock` ([release-please#2561](https://github.com/googleapis/release-please/issues/2561)).
|
|
43
|
+
|
|
44
|
+
## 4. PR test plan
|
|
45
|
+
|
|
46
|
+
Note that repo-practices lint passed (or list `--apply-fix` steps taken) in the PR **Test plan**.
|
|
47
|
+
|
|
48
|
+
`scripts/dev/pre-pr-checks` runs this audit automatically when the branch diff touches workflow/config paths (detect-first `repo-practices-lint` job). Cursor rule edits alone do not trigger pre-pr (the audit reads GitHub, not your local tree).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Choose Graphite vs GitHub Stacked PRs from .github/stacking-tool
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Stacking tool preference
|
|
7
|
+
|
|
8
|
+
Before creating branches or submitting/restacking PRs, **read** `.github/stacking-tool` (single line: `graphite` or `gh-stack`). Missing or invalid values: **stop and ask** — do not guess.
|
|
9
|
+
|
|
10
|
+
<!-- stacking-tool-canonical-graphite-skill: https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/graphite/SKILL.md -->
|
|
11
|
+
<!-- stacking-tool-canonical-gh-stack-skill: https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/gh-stack/SKILL.md -->
|
|
12
|
+
|
|
13
|
+
Canonical skills live in **repository-helpers** (not copied into this repo):
|
|
14
|
+
|
|
15
|
+
- **Graphite:** https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/graphite/SKILL.md
|
|
16
|
+
- **gh-stack:** https://github.com/the-hcma/repository-helpers/blob/main/.agents/skills/gh-stack/SKILL.md
|
|
17
|
+
|
|
18
|
+
Local clone (when `${REPOSITORY_HELPERS_DIR:-$HOME/work/ai/repository-helpers}` is synced):
|
|
19
|
+
|
|
20
|
+
- `${REPOSITORY_HELPERS_DIR}/.agents/skills/graphite/SKILL.md`
|
|
21
|
+
- `${REPOSITORY_HELPERS_DIR}/.agents/skills/gh-stack/SKILL.md`
|
|
22
|
+
|
|
23
|
+
## `graphite`
|
|
24
|
+
|
|
25
|
+
- Follow the Graphite skill above (`gt create` / `gt submit` / `gt restack`).
|
|
26
|
+
- Prefer repository-helpers `scripts/dev/submit-stack` when available in that clone.
|
|
27
|
+
|
|
28
|
+
## `gh-stack`
|
|
29
|
+
|
|
30
|
+
- Follow the gh-stack skill (non-interactive: `view --json`, `submit --auto --open`, named `init`/`add`).
|
|
31
|
+
- Prefer repository-helpers `scripts/dev/submit-stack` / `scripts/dev/ship-and-review` when available (they dispatch via `scripts/lib/stacking-tool`).
|
|
32
|
+
- **Do not** mix with `gt create` / `gt submit` / `gt restack` on the same stack.
|
|
33
|
+
|
|
34
|
+
## Marker cutover checklist
|
|
35
|
+
|
|
36
|
+
When flipping `.github/stacking-tool` (or landing an MQ/`gh-stack` cutover PR):
|
|
37
|
+
|
|
38
|
+
1. Update `AGENTS.md` stacking/merge guidance to match the new marker (and GitHub auto-merge: `gh pr merge --auto --squash` — not `merge-it`).
|
|
39
|
+
2. Rewrite `.agents/rules/pr-ship-and-review.md` submit block to the marker-aware template (copy via `github-repo-lint --apply-fix`, or from `${REPOSITORY_HELPERS_DIR}/scripts/lib/repo-practices-agents/rules/pr-ship-and-review.md` / https://github.com/the-hcma/repository-helpers/blob/main/scripts/lib/repo-practices-agents/rules/pr-ship-and-review.md; or ensure it documents both backends gated on the marker; keep a thin `.cursor/rules/pr-ship-and-review.mdc` shim).
|
|
40
|
+
3. Delete root `GRAPHITE.md` when switching to `gh-stack` (canonical skill lives in repository-helpers).
|
|
41
|
+
4. Keep `.agents/rules/stacking-tool.md` (+ Cursor shim) in sync with the consumer template.
|
|
42
|
+
5. Re-run `scripts/github-repo-lint --repo OWNER/NAME --suggest --strict-onboarding` and fix stacking-docs consistency findings.
|
|
43
|
+
|
|
44
|
+
## Unchanged regardless of marker
|
|
45
|
+
|
|
46
|
+
Agent review, CI wait, and reply-before-resolve still follow `.agents/rules/pr-ship-and-review.md` and the canonical ship-and-review skill in repository-helpers.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Commits and PRs attribute only the committer — no agent or machine co-authors
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: git-commit-identity -->
|
|
7
|
+
Canonical rule: [`.agents/rules/git-commit-identity.md`](../../.agents/rules/git-commit-identity.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Every gh call site, agent or first-party code, must run through scripts/gh-api
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: github-api-throttle -->
|
|
7
|
+
Canonical rule: [`.agents/rules/github-api-throttle.md`](../../.agents/rules/github-api-throttle.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Format agent-authored GitHub issue/PR bodies and comments so they render correctly (blank lines + no hand-wrapped paragraphs)
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: github-content-formatting -->
|
|
7
|
+
Canonical rule: [`.agents/rules/github-content-formatting.md`](../../.agents/rules/github-content-formatting.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Ship a PR end-to-end — local gates, submit, agent review loop, operator email
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: pr-ship-and-review -->
|
|
7
|
+
Canonical rule: [`.agents/rules/pr-ship-and-review.md`](../../.agents/rules/pr-ship-and-review.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: On every new agent session, read AGENTS.md and .agents/rules before acting
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: read-agents-and-rules -->
|
|
7
|
+
Canonical rule: [`.agents/rules/read-agents-and-rules.md`](../../.agents/rules/read-agents-and-rules.md)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: All remote/network I/O must use explicit timeouts and bounded retries
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- agents-rule-shim: remote-timeouts-retries -->
|
|
7
|
+
Canonical rule: [`.agents/rules/remote-timeouts-retries.md`](../../.agents/rules/remote-timeouts-retries.md)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run github-repo-lint after repo config or workflow changes
|
|
3
|
+
globs:
|
|
4
|
+
- .agents/rules/**
|
|
5
|
+
- .agents/skills/**
|
|
6
|
+
- .cursor/rules/**
|
|
7
|
+
- .github/**
|
|
8
|
+
- pnpm-workspace.yaml
|
|
9
|
+
- release-please-config.json
|
|
10
|
+
- .release-please-manifest.json
|
|
11
|
+
- scripts/lib/repo-practices-workflows/**
|
|
12
|
+
- web/pnpm-workspace.yaml
|
|
13
|
+
alwaysApply: false
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<!-- agents-rule-shim: repo-practices-after-config-change -->
|
|
17
|
+
Canonical rule: [`.agents/rules/repo-practices-after-config-change.md`](../../.agents/rules/repo-practices-after-config-change.md)
|