Skip to content

Commit 08bdc91

Browse files
committed
CI + CONTRIBUTING — lower friction for external contributors
.github/workflows/ci.yml — two-job pipeline on push/PR/tag: • validate-and-test: pytest (mcp-server + reviewer fixtures) + tools/validate_corpus.py --no-syntax-check + an inline sanity check that every index.yaml row has a reference file. ~3 min. • package-and-size-check: tools/package.sh + 5 MB budget gate from PLAN.md §6 + uploads the release tarball as a CI artifact (30-day retention). Runs after validate-and-test. Concurrency group cancels stale runs per branch. Eval is NOT in CI — it needs Claude subscription auth that CI runners don't have. Documented as a manual step in CONTRIBUTING.md. CONTRIBUTING.md — the three quick paths external contributors most often want (install confirmation, bug report, eval task suggestion) each linked to their issue template. Plus a full local-dev section (venv setup, tests, validator, plugin loading via --plugin-dir) and the workflow for adding a new deep-tier reference or anti-pattern regex (mirrors MAINTENANCE.md's promote-to-deep flow). These are the last release-prep pieces before the v1.0 gates close.
1 parent 6907c3c commit 08bdc91

2 files changed

Lines changed: 200 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ['v*']
7+
pull_request:
8+
branches: [main]
9+
10+
# Only run the latest commit per branch — cancel older in-flight jobs.
11+
concurrency:
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
validate-and-test:
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 10
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
- name: Set up Python 3.11
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: "3.11"
30+
cache: pip
31+
32+
- name: Install mcp-server (editable, with dev deps)
33+
run: |
34+
python -m pip install --upgrade pip
35+
pip install -e "mcp-server[dev]"
36+
37+
- name: pytest — MCP server + reviewer fixtures
38+
run: |
39+
pytest -q mcp-server/tests agents/tests
40+
41+
- name: validate_corpus — schema + xref (skip syntax pass; no C++26-capable clang in CI)
42+
run: |
43+
python tools/validate_corpus.py --no-syntax-check
44+
45+
- name: Sanity — every index row has a reference file
46+
run: |
47+
python - <<'PY'
48+
import yaml, sys
49+
from pathlib import Path
50+
51+
rows = yaml.safe_load(Path("corpus/index.yaml").read_text())
52+
refs = {p.stem for p in Path("corpus/references").glob("*.md")}
53+
missing = sorted({r["id"] for r in rows if r.get("id")} - refs)
54+
if missing:
55+
print(f"missing references for: {missing}", file=sys.stderr)
56+
sys.exit(1)
57+
print(f"OK — {len(rows)} index rows, {len(refs)} reference files")
58+
PY
59+
60+
package-and-size-check:
61+
runs-on: ubuntu-latest
62+
timeout-minutes: 5
63+
needs: validate-and-test
64+
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Build release tarball
69+
run: bash tools/package.sh
70+
71+
- name: Size budget (≤ 5 MB per PLAN.md §6)
72+
run: |
73+
tar=$(ls dist/cpp26-adapter-*.tgz | head -1)
74+
size_kb=$(( $(stat -c%s "$tar") / 1024 ))
75+
echo "tarball: $tar ($size_kb KB)"
76+
if (( size_kb > 5120 )); then
77+
echo "::error::tarball $size_kb KB exceeds 5 MB budget"
78+
exit 1
79+
fi
80+
81+
- name: Upload tarball as artifact
82+
uses: actions/upload-artifact@v4
83+
with:
84+
name: cpp26-adapter-release-tarball
85+
path: dist/cpp26-adapter-*.tgz
86+
retention-days: 30

CONTRIBUTING.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Contributing to cpp26-adapter
2+
3+
Bug reports, eval-task suggestions, and install confirmations are all
4+
welcome. The repo carries the full build history (16 commits across
5+
the 9 binding-plan phases), so reading [`PLAN.md`](PLAN.md) and the
6+
commit log gives a clean picture of why every component exists.
7+
8+
## Quick paths
9+
10+
- **Just confirming the install works?**
11+
Use the [install confirmation](.github/ISSUE_TEMPLATE/install_works.md)
12+
template. It closes part of the v1.0 gate.
13+
14+
- **Spot a wrong suggestion or classification?**
15+
Use the [bug report](.github/ISSUE_TEMPLATE/bug.md) template — pick
16+
the classification (wrong suggestion / wrong reviewer classification
17+
/ activation failure / MCP failure) so the maintainer can route fast.
18+
19+
- **Have a prompt that should pass and doesn't?**
20+
Open an [eval task suggestion](.github/ISSUE_TEMPLATE/eval_task_suggestion.md).
21+
The held suite at `eval/tasks.yaml` gates every release.
22+
23+
## Local development
24+
25+
```bash
26+
git clone https://github.com/parasxos/cpp26-adapter.git
27+
cd cpp26-adapter
28+
python3 -m venv mcp-server/.venv
29+
mcp-server/.venv/bin/pip install -e "mcp-server[dev]"
30+
31+
# Run the test suites
32+
mcp-server/.venv/bin/pytest -q mcp-server/tests agents/tests
33+
34+
# Run the validator (schema + xref; syntax check needs clang ≥ 22)
35+
mcp-server/.venv/bin/python tools/validate_corpus.py
36+
37+
# Load the plugin in a fresh Claude Code session
38+
claude --plugin-dir .
39+
```
40+
41+
## Running the eval
42+
43+
The 39-task held suite at `eval/tasks.yaml` gates every release.
44+
45+
```bash
46+
# Smoke test (3 tasks, no judge, no baseline — verifies the harness)
47+
mcp-server/.venv/bin/python eval/run.py --tasks 3 --skip-judge --no-off
48+
49+
# Full run (~50 min on subscription auth, ~$15-25 on API auth)
50+
mcp-server/.venv/bin/python eval/run.py
51+
```
52+
53+
By default the harness strips `ANTHROPIC_API_KEY` from the subprocess
54+
env so `claude -p` uses your Claude subscription quota. Set
55+
`CPP26_EVAL_USE_API=1` to opt back into per-token API billing.
56+
57+
The bar is **≥85% standard-compliance** (axis-1). v1.0 is gated on
58+
two successive eval-passing refreshes per [`MAINTENANCE.md`](MAINTENANCE.md).
59+
60+
## Adding a new deep-tier reference
61+
62+
When a new C++26 paper warrants a hand-curated reference (e.g., a
63+
late-DR feature that landed in the IS):
64+
65+
1. Add the paper id to `DEEP_TIER` in `corpus/scripts/fetch_index.py`.
66+
2. Re-run `fetch_index.py` so the tier flips to `deep` in `index.yaml`.
67+
3. Author `corpus/references/<id>.md` following the structure of any
68+
of the 16 existing deep refs (frontmatter + Problem + Key syntax
69+
+ Canonical example + Pre-C++26 equivalent + Gotchas + Related).
70+
4. Add the paper to `corpus/status.yaml` with at-least clang-22 /
71+
clang-p2996 / gcc-16 / msvc-19.40 entries.
72+
5. Add a row to the SKILL.md decision table referencing the new ref.
73+
6. Add 1+ task to `eval/tasks.yaml` exercising the canonical idiom.
74+
7. Re-run validator + eval; commit.
75+
76+
The bookkeeping is captured in [`MAINTENANCE.md`](MAINTENANCE.md).
77+
78+
## Adding a new anti-pattern regex
79+
80+
When the eval surfaces a class of failures that's deterministically
81+
catchable (the model keeps emitting `assert(` instead of
82+
`contract_assert`, say), add a regex to
83+
`tools/cpp26_lint/patterns.yaml`:
84+
85+
```yaml
86+
- pattern: '\bassert\s*\('
87+
suggest: "use contract_assert(...)"
88+
paper: P2900
89+
severity: warning # or info, info-only triggers if no warnings present
90+
```
91+
92+
The regex is shared between the PostToolUse hook (surfaces findings
93+
inline) and the cpp26-reviewer Pass 1 (classification).
94+
95+
## Coding conventions
96+
97+
- **Python**: 3.11+, type-hinted, ruff-clean. Line length 100.
98+
- **C++ code in references / fixtures**: must be syntactically credible
99+
C++26. No made-up syntax (compile against `clang-p2996` or the
100+
current revision of P2996 if unsure).
101+
- **Markdown**: GitHub-flavoured. Mermaid diagrams are fine (GitHub
102+
renders them). No raw HTML.
103+
- **Commits**: imperative mood, prefixed with the phase or component
104+
where applicable (e.g. `Phase 4:` or `eval:`). Match the existing
105+
log style.
106+
107+
## License
108+
109+
Contributions are dual-licensed:
110+
- Code (everything outside `corpus/`) under MIT.
111+
- Knowledge corpus contributions under CC-BY-SA-4.0.
112+
113+
By submitting a PR you assert you have the right to license your
114+
contribution under these terms.

0 commit comments

Comments
 (0)