From 7ce13065e942770aa160d50d5c425d24f02b2f72 Mon Sep 17 00:00:00 2001 From: ohad6k Date: Thu, 23 Jul 2026 16:00:09 +0300 Subject: [PATCH] docs: contributor guide, privacy-safe issue templates, PR checklist Closes #16. CONTRIBUTING.md documents the real setup (stdlib-only core, unittest suite, requirements.lock only for the optional pro extra), the repo layout, what a good PR looks like, and the hard rules: verify before claiming, never publish an unrun command, minimal diffs, never widen the privacy surface quietly. The issue templates steer reporters away from pasting profiles, session transcripts, and local paths, and ask for version, OS, command, and redacted error text instead. Blank issues are disabled so every report goes through a template that carries the redaction warning. Every command in the guide was run on this machine: python -m unittest discover -s tests (396 tests, OK, 3 Windows symlink skips, Python 3.11.4), emulo.py --help, --dry-run --path, plugin --help, and mcp. Co-Authored-By: Claude Opus 4.8 --- .github/ISSUE_TEMPLATE/bug_report.md | 58 ++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 11 +++ .github/ISSUE_TEMPLATE/feature_request.md | 35 ++++++++++ .github/pull_request_template.md | 29 ++++++++ CONTRIBUTING.md | 84 +++++++++++++++++++++++ 5 files changed, 217 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/pull_request_template.md create mode 100644 CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..386e6ae --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,58 @@ +--- +name: Bug report +about: Something in Emulo behaves differently than documented +title: '' +labels: bug +assignees: '' +--- + + + +**Emulo version** + + + +**OS and Python version** + + + +**How you run Emulo** + + + +**Command you ran** + +```text +/> +``` + +**What you expected** + + +**What happened** + +```text + +``` + +**Anything else** + + + +- [ ] I checked this report contains no profile contents, session text, or personal paths. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..22b390b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Questions and setup help + url: https://discord.gg/QMnYtVcxk2 + about: Ask in Discord. Do not paste your profile, session logs, or local paths there either. + - name: Share what Emulo found + url: https://github.com/ohad6k/emulo/issues/1 + about: The one thread for results. Share the card or one short trait, never your full profile. + - name: Security issue + url: https://github.com/ohad6k/emulo/blob/main/SECURITY.md + about: Do not open a public issue with reproduction details. Read the security model and report privately. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3c3110e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,35 @@ +--- +name: Feature request +about: Propose a change to how Emulo works +title: '' +labels: enhancement +assignees: '' +--- + + + +**The problem** + + + +**What you want instead** + + +**Where it would live** + + + +**Privacy impact** + + + +**Anything you already tried** + + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..d3672bc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,29 @@ + + +**What changed** + + + +**How I verified it** + +```text + +``` + + + +**Privacy surface** + + + +**Checklist** + +- [ ] Full suite green: `python -m unittest discover -s tests` +- [ ] A test covers this change, and it fails without the change +- [ ] Minimal diff, no unrelated refactors or reformatting +- [ ] Every command in this PR and in any docs it touches was actually run as written +- [ ] Privacy surface unchanged, or the change is described above and `SECURITY.md` updated +- [ ] No profile contents, session text, real paths, or secrets in the diff or this description +- [ ] Docs updated if behavior, flags, or the boundary changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5317449 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,84 @@ +# Contributing to Emulo + +Emulo reads people's private AI coding-session logs. Every rule below comes from that. + +## Setup + +The core is one stdlib-only file, `emulo.py`. Nothing to build, no runtime dependency to install. + +```bash +git clone https://github.com/ohad6k/emulo +cd emulo +python -m unittest discover -s tests +``` + +`pyproject.toml` declares `requires-python = ">=3.8"`. CI runs 3.12 (`.github/workflows/tests.yml`). This guide was written against a local run on Python 3.11.4: 396 tests, OK, 3 skipped (Windows symlink tests that need a privilege Windows does not grant by default). Those three run on Linux and macOS. + +CI installs the one optional pin before the suite, so do the same if you touch encrypted continuity: + +```bash +python -m pip install -r requirements.lock +``` + +That pin is `cryptography`, used only by the optional `pro` extra. The mining core never imports it. + +Run the CLI straight from a checkout: + +```bash +python emulo.py --help +python emulo.py --dry-run --path +python emulo.py plugin --help +python emulo.py mcp +``` + +`--dry-run` prints counts and output paths and writes nothing. While developing, point `--path` at a scratch folder of fixture logs instead of your real history. With no logs found, the run exits non-zero and writes nothing, which is the intended behavior, not a bug. + +## Layout + +| Path | What's in it | +|---|---| +| `emulo.py` | The whole tool: discovery, extraction, redaction, the read-only plan, `plugin` subcommands, the `mcp` server, the card, and the install adapters. Stdlib only, no network calls. | +| `emulo_autopilot/` | Autopilot package: policy, sessions, store, encrypted continuity. | +| `proof/` | Emulo Proof v1 methodology code: schema, runner, evaluate, publish. | +| `skills/` | The five native plugin skills: `mine`, `work`, `design`, `write`, `video`. | +| `.agents/` | The skills.sh bootstrap and its marketplace entry. | +| `.claude-plugin/`, `.codex-plugin/`, `.github/plugin/` | Host plugin manifests. `tests/test_plugin_manifests.py` keeps them honest. | +| `compat/` | Compatibility shims for the old `ditto` name. Keep them working. | +| `cloud/worker/` | The Cloudflare Worker behind Emulo Pro. | +| `site/` | The public site. | +| `docs/`, `MINING_PROMPT.md` | Docs and the mining prompt handed to agents. | +| `tests/` | Plain `unittest`. No test-runner dependency. | + +## Hard rules + +**Verify before you claim it works.** A code edit is not evidence. Run the thing, read the output, then say what happened. If you could not run it, say that instead of implying you did. + +**Never publish a command you have not run.** Every command in a README, a doc, an issue reply, or a PR description has to have been executed as written on a real machine. If it only works on one OS, say which. + +**Fix the one thing.** Minimal diffs. No drive-by refactors, no reformatting a file you opened to change one line, no renaming things that were not in your way. A PR that rewrites code that was not the problem gets rejected. + +**Do not widen the privacy surface quietly.** New discovery paths, new fields written to `EMULO_HOME`, new text sent to a model provider, new files written outside the output directory, or anything loosening redaction: call it out explicitly in the PR and add a test. `SECURITY.md` is the boundary. If your change moves it, update `SECURITY.md` in the same PR. + +**Fail closed.** Empty or malformed input writes nothing. Corrupt caches are quarantined, not trusted. Hash checks happen before reuse. Keep it that way. + +**Never commit private data.** Session logs, mined output, `you.md` and its lens files, the receipt appendix, and Emulo caches are gitignored on purpose. Do not add exceptions and do not paste them into an issue, a PR, or a test fixture. Test fixtures must be synthetic. + +## What a good PR looks like + +- One change, described in a sentence. If you need "and" twice, split it. +- Tests: a test that fails before your change and passes after. Same `unittest` style as the rest of `tests/`. +- The full suite green: `python -m unittest discover -s tests`. Paste the tail of the output in the PR. +- Docs updated in the same PR when behavior, flags, or the privacy boundary changed. +- The PR checklist filled in honestly, including the "could not verify" cases. + +Open an issue before a large change so nobody builds the wrong thing twice. + +## Reporting bugs + +Use the issue templates. They exist because a bug report about a log miner is the easiest place in this project to leak your own data by accident. Give the Emulo version, the OS, the command, and the error text with paths and log contents redacted. Never attach a profile, a session transcript, or a chunk of your corpus. + +For a security issue, do not open a public issue with reproduction details. Report it privately to the maintainer first, through GitHub's private vulnerability reporting on the repository if it is enabled. + +## License + +MIT. By contributing you agree your contribution ships under the same license.