Skip to content

Commit fa5df79

Browse files
fix: add public repo hygiene checks and tighten agent rules
Block tracked local paths and secret-like files in CI, expand gitignore, and remove localhost URL from contributor docs. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent cfa3d48 commit fa5df79

7 files changed

Lines changed: 110 additions & 3 deletions

File tree

‎.github/AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CI, deployment, and repository automation under `.github/`.
66

77
| Workflow | Trigger | Purpose |
88
|----------|---------|---------|
9-
| [workflows/ci.yml](workflows/ci.yml) | Push/PR to `main` | Markdown lint, internal link check, MkDocs build |
9+
| [workflows/ci.yml](workflows/ci.yml) | Push/PR to `main` | Markdown lint, repo hygiene, internal links, MkDocs build |
1010
| [workflows/pages.yml](workflows/pages.yml) | Push to `main` | Build MkDocs site and deploy to GitHub Pages |
1111
| [workflows/link-check-scheduled.yml](workflows/link-check-scheduled.yml) | Weekly + manual | External link check via Lychee |
1212

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ jobs:
3535
python-version: "3.12"
3636
- run: python scripts/check-internal-links.py
3737

38+
repo-hygiene:
39+
name: Public repo hygiene
40+
runs-on: ubuntu-latest
41+
steps:
42+
- uses: actions/checkout@v7
43+
- run: python scripts/check-public-repo-hygiene.py
44+
3845
mkdocs:
3946
name: MkDocs build
4047
runs-on: ubuntu-latest

‎.gitignore‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,11 @@ research/
44
# MkDocs build output and generated site files
55
site/
66
docs/CONTRIBUTING.md
7+
8+
# Secrets and local environment files
9+
.env
10+
.env.*
11+
*.pem
12+
*.key
13+
*.p12
14+
*.pfx

‎AGENTS.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Run before opening a PR:
4646

4747
```bash
4848
npx markdownlint-cli2 "**/*.md"
49+
python scripts/check-public-repo-hygiene.py
4950
python scripts/check-internal-links.py
5051
python scripts/prepare-mkdocs.py
5152
mkdocs build --strict
@@ -59,10 +60,14 @@ Site config lives in [mkdocs.yml](mkdocs.yml). The [Deploy GitHub Pages](.github
5960

6061
## Do not
6162

62-
- Commit secrets or credentials.
63+
- Commit secrets, credentials, API keys, tokens, or private keys.
64+
- Commit local-only paths: `research/`, `site/`, `docs/CONTRIBUTING.md`, `.env`, or other generated build output.
65+
- Commit draft research, internal notes, or machine-local paths unless the user explicitly asks to publish them.
66+
- Use `git add -A` or `git add .` without reviewing the staged file list first.
6367
- Add unrelated tooling (frameworks, package.json, etc.) without explicit request.
6468
- Break relative links or leave orphaned files out of the table of contents.
6569
- Run destructive git commands unless the user explicitly asks.
70+
- Push to the remote unless the user explicitly asks.
6671

6772
## Related files
6873

‎CONTRIBUTING.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Add new channel guides under `docs/channels/`. Add cross-cutting topics under `d
3232
5. **Verify locally**
3333
```bash
3434
npx markdownlint-cli2 "**/*.md"
35+
python scripts/check-public-repo-hygiene.py
3536
python scripts/check-internal-links.py
3637
python scripts/prepare-mkdocs.py
3738
mkdocs build --strict
@@ -53,7 +54,7 @@ python scripts/prepare-mkdocs.py
5354
mkdocs serve
5455
```
5556

56-
Open [http://127.0.0.1:8000/Awesome-Ads/](http://127.0.0.1:8000/Awesome-Ads/) in your browser.
57+
Open the local URL printed by `mkdocs serve` (typically port 8000).
5758

5859
## Standards
5960

‎scripts/AGENTS.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Maintenance utilities for repository quality checks.
77
| File | Purpose |
88
|------|---------|
99
| `check-internal-links.py` | Validates that relative `markdown` links resolve to existing files |
10+
| `check-public-repo-hygiene.py` | Fails if local-only paths or secret-like content are tracked in git |
1011
| `prepare-mkdocs.py` | Generates `docs/CONTRIBUTING.md` with site-relative links for MkDocs builds |
1112

1213
## check-internal-links.py
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
"""Fail if local-only or generated paths are tracked in git."""
3+
4+
from __future__ import annotations
5+
6+
import re
7+
import subprocess
8+
import sys
9+
from pathlib import Path
10+
11+
ROOT = Path(__file__).resolve().parent.parent
12+
13+
FORBIDDEN_TRACKED_PATHS = (
14+
"research/",
15+
"site/",
16+
"docs/CONTRIBUTING.md",
17+
)
18+
19+
FORBIDDEN_TRACKED_SUFFIXES = (
20+
".env",
21+
".pem",
22+
".key",
23+
".p12",
24+
".pfx",
25+
)
26+
27+
SENSITIVE_CONTENT_PATTERNS = (
28+
re.compile(r"-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----"),
29+
re.compile(r"\bAKIA[0-9A-Z]{16}\b"),
30+
re.compile(r"\bghp_[A-Za-z0-9]{20,}\b"),
31+
re.compile(r"\bgithub_pat_[A-Za-z0-9_]{20,}\b"),
32+
re.compile(r"\bsk_(?:live|test)_[A-Za-z0-9]{10,}\b"),
33+
)
34+
35+
36+
def tracked_files() -> list[str]:
37+
result = subprocess.run(
38+
["git", "ls-files", "-z"],
39+
cwd=ROOT,
40+
check=True,
41+
capture_output=True,
42+
)
43+
return [entry for entry in result.stdout.decode("utf-8").split("\0") if entry]
44+
45+
46+
def main() -> int:
47+
errors: list[str] = []
48+
49+
for path in tracked_files():
50+
if path.startswith(FORBIDDEN_TRACKED_PATHS) or path in FORBIDDEN_TRACKED_PATHS:
51+
errors.append(f"Tracked local-only path must not be committed: {path}")
52+
continue
53+
54+
if path.endswith(FORBIDDEN_TRACKED_SUFFIXES):
55+
errors.append(f"Tracked secret-like file must not be committed: {path}")
56+
continue
57+
58+
file_path = ROOT / path
59+
if not file_path.is_file():
60+
continue
61+
62+
try:
63+
content = file_path.read_text(encoding="utf-8")
64+
except UnicodeDecodeError:
65+
continue
66+
67+
for pattern in SENSITIVE_CONTENT_PATTERNS:
68+
if pattern.search(content):
69+
errors.append(
70+
f"Possible secret pattern in tracked file: {path} ({pattern.pattern})"
71+
)
72+
break
73+
74+
if errors:
75+
print("Public repo hygiene check failed:\n", file=sys.stderr)
76+
for error in errors:
77+
print(f" - {error}", file=sys.stderr)
78+
return 1
79+
80+
print("Public repo hygiene check passed.")
81+
return 0
82+
83+
84+
if __name__ == "__main__":
85+
raise SystemExit(main())

0 commit comments

Comments
 (0)