Contributing
Open an issue describing the user problem, observed evidence, and proposed verified behavior before broad changes. One PR per independently testable improvement. Include tests, docs, and a rollback plan for anything that might publish, schedule or access accounts.
Fresh clone: lint, tests and an offline example
Section titled “Fresh clone: lint, tests and an offline example”Requires Python 3.11+ and git. The runtime has no third-party dependencies, so there is nothing to install; no command below needs a network connection, an account or a credential.
git clone https://github.com/MSKazemi/reachweaver.gitcd reachweaver
# Offline unit tests (HTTP is mocked; tests/test_no_network.py fails on any socket attempt)python3 -m unittest discover -s tests -v
# Mirror reachweaver/ into the bundled Claude Code skill (run after every source change)python3 scripts/sync_skill.py
# Secret scan of tracked files; prints path:line:pattern-id, never the valuepython3 scripts/secret_scan.py
# Stdlib lint: syntax of every tracked .py, JSON/JSONL validity; then byte-compilepython3 scripts/lint.pypython3 -m compileall -q reachweaver scripts tests
# The runtime must stay stdlib-only; fails if pyproject.toml gains a runtime dependencypython3 scripts/check_runtime_deps.py
# Offline example run against a throwaway database (never contacts a platform).# The database directory must be private (mode 0700), so use mktemp -d rather than /tmp itself.RW_TMP=$(mktemp -d)python3 -m reachweaver --db "$RW_TMP/example.sqlite" initpython3 -m reachweaver --db "$RW_TMP/example.sqlite" --accounts config/accounts.example.json doctorpython3 -m reachweaver campaign-check --file examples/campaign.reachweaver.json --brand examples/brand.reachweaver.jsonpython3 -m reachweaver distribution-plan --region india --goal adoption --limit 3With make available, make check runs sync, secret scan, lint, the runtime-dependency guard (make deps) and tests in one go (make help lists targets; make example runs the offline example in a temporary directory). Three more targets download an exactly pinned tool through pipx and install nothing into the project:
| Target | What it runs | In CI |
|---|---|---|
make ruff |
ruff hard-error rules (E9,F63,F7,F82) |
Yes, blocking |
make typecheck |
mypy on reachweaver/, configured in pyproject.toml [tool.mypy] |
Yes, blocking |
make format-check |
ruff format --check |
No. Advisory only, never fails |
Before tagging a release, run make release-gate TAG=vX.Y.Z (offline; see the release gate). It fails unless the versions agree, CHANGELOG.md has a dated section for the version, the required documents exist, README names every CLI subcommand, relative links resolve, the skill bundle is in sync, every blocked platform has a manual alternative or explicit marker, and the unit tests pass. A new platform in either registry needs an entry in reachweaver/onboarding.py, and the table in docs/TROUBLESHOOTING.md must be regenerated with python3 scripts/release_gate.py --print-blocker-table. The maintainer checklist is in docs/SECURITY-CHECKLIST.md.
Type checking is gradual: every reachweaver module is checked, but only annotated function bodies (check_untyped_defs = false). Do not add a [[tool.mypy.overrides]] ignore_errors entry to silence a new error; fix the annotation instead. Do not reformat code with ruff format in a feature PR: whole-repository formatting is deferred to one dedicated change (see ADR-0002, decision 9). Tool versions are pinned exactly in the Makefile and .github/workflows/ci.yml. Bump both together, on purpose.
Runtime dependencies. The runtime is stdlib-only and pyproject.toml must keep dependencies = []. A PR that adds a runtime dependency must, in the same change, add a pinned pip-audit CI step and a hash-pinned lock file, update scripts/check_runtime_deps.py, and amend ADR-0002. Recorded provider responses used as test fixtures follow tests/fixtures/providers/README.md (scrubbed, synthetic ids, secret scan clean).
Tests must run with mocked HTTP and NO real social credentials, and must never perform live publishing.
Secret scanning and the allowlist
Section titled “Secret scanning and the allowlist”scripts/secret_scan.py checks every git-tracked file for private key blocks, AWS keys, GitHub/Slack/Telegram tokens, JWTs, Bluesky app-password-shaped strings (outside *example* files) and literal password/token/secret assignments. It runs in CI and exits 1 on any finding. If a finding is a deliberately fake test fixture, add a narrow entry to .secret-scan-allow:
<path-glob> <pattern-id> # mandatory reasonPrefer building fake tokens at runtime (string concatenation) so no allowlist entry is needed. Never allowlist a value that has ever been a real credential — revoke it at the provider and rewrite the fixture. python3 scripts/secret_scan.py --list-patterns shows the pattern ids.
Documentation website
Section titled “Documentation website”mskazemi.com/reachweaver is built from the Markdown in this repository; edit the Markdown, never the generated pages. scripts/build_docs_site.py copies the public guides into website/src/content/docs/ (front matter, rewritten links, one page per release, the command reference from the real parser, llms.txt), then Astro Starlight builds the site. Only website/src/content/docs/index.mdx, faq.mdx and 404.md are written by hand. A new file in docs/ gets a page automatically; add it to SECTIONS in the script to choose its sidebar group. Building needs Node.js 22.23 or newer; the Python side stays dependency-free.
make site # generate the content, npm ci, build website/dist (fails on a broken link or anchor)make site-check # titles, descriptions, canonicals, sitemap, structured data, no links to private filesmake site-dev # live preview at http://localhost:4321/reachweaver/.github/workflows/docs-site.yml runs the same steps on every pull request and deploys to GitHub Pages from main.
Pull requests and issues
Section titled “Pull requests and issues”The pull request template asks for test evidence (command and output), documentation updates, a security evaluation of the approval, dry-run, emergency-stop, credential-isolation and ambiguous-send rules, and platform-registry updates where relevant. Use the issue templates for bugs, features and platform adapters; adapters need official documentation URLs, a verification date, the account type and the platform’s approval requirements. Report vulnerabilities privately as described in docs/SECURITY.md, never in a public issue. Public PRs must not contain secrets, unlicensed third-party skill prose, browser cookies, session files, private analytics or copyrighted media.
Use original code. The upstream research directory is an attribution/citation catalog, not a vendoring directory. Postiz is AGPL-3.0 and not to be pasted into this Apache-2.0 repository. Preserve author credits for any separately permitted reused work.
Write issues and documentation in clear English. Identify API capabilities as VERIFIED/LIVE-TESTED, MOCK-TESTED or NOT IMPLEMENTED; never infer success from an attractive README.
