diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2f337ca --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Default owner for all paths. Adjust when collaborators are added. +* @gitcommit90 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6eb16c7..b9082d3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,18 +1,51 @@ -## External contributions are not yet accepted +## External contributions -ReRouted is licensed under the MIT License, but its external contribution process is still being finalized. Please read [CONTRIBUTING.md](../CONTRIBUTING.md) before opening a pull request. External code and documentation contributions may be closed without review until that process is published. +ReRouted is MIT licensed. **External pull requests are not accepted yet.** Read [CONTRIBUTING.md](../CONTRIBUTING.md). External code or docs PRs may be closed without review until that policy changes. Never include real API keys, gateway keys, OAuth tokens or codes, callback URLs, cookies, account identifiers, email addresses, private prompts, provider responses, or unreviewed logs. -## Maintainer change +## Summary -Describe the user-visible problem and the resulting behavior. + + +## Type of change + +- [ ] Fix +- [ ] Feature +- [ ] Docs / governance +- [ ] Refactor (no intended behavior change) +- [ ] Chore / CI + +## Release notes (required for user-visible changes) + +Paste the bullets that should land in `CHANGELOG.md` under Unreleased / the next version: + +```markdown +### Fixed +- … + +### Added +- … +``` + +- [ ] `CHANGELOG.md` updated (or N/A: internal-only with no user impact) + +## Version + +- [ ] No release this PR (docs/governance/chore only) +- [ ] Version bump included (`package.json`) — unique, not previously tagged ## Verification -- [ ] Focused validation passes. -- [ ] `npm test` passes. -- [ ] `git diff --check` passes. -- [ ] UI changes include current captures where applicable. -- [ ] No credentials, private user data, or generated release artifacts are included. -- [ ] Release/version work is left to the maintainer release process. +- [ ] Focused validation for the changed area +- [ ] `npm test` passes +- [ ] `git diff --check` passes +- [ ] UI changes inspected or captured where applicable +- [ ] No credentials, private user data, or generated release artifacts committed +- [ ] Packaging/signing left to [docs/release-checklist.md](../docs/release-checklist.md) + +## Post-merge (maintainers) + +- [ ] Head branch deleted +- [ ] CI green on `main` +- [ ] If shipping: follow [docs/release-lifecycle.md](../docs/release-lifecycle.md) end-to-end diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..4553f04 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,30 @@ +# GitHub-generated release notes categories (Settings → Releases uses this file). +changelog: + exclude: + labels: + - skip-changelog + - duplicate + - invalid + categories: + - title: Breaking changes + labels: + - breaking + - title: Features + labels: + - enhancement + - feature + - title: Fixes + labels: + - bug + - fix + - title: Documentation + labels: + - documentation + - title: Maintenance + labels: + - chore + - ci + - dependencies + - title: Other + labels: + - "*" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 836f194..2c5361c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,8 +9,13 @@ on: permissions: contents: read +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: + name: test runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -23,5 +28,15 @@ jobs: cache: npm - name: Install dependencies run: npm ci + - name: Diff whitespace check + run: git diff --check - name: Run tests run: npm test + - name: Package metadata sanity + run: | + node -e "const p=require('./package.json'); if(!p.version) process.exit(1); if(p.license!=='MIT') process.exit(1); console.log('version', p.version)" + test -f LICENSE + test -f CHANGELOG.md + test -f docs/release-checklist.md + test -f docs/release-lifecycle.md + test -f docs/GOVERNANCE.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..b427cb6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,72 @@ +# Changelog + +All notable changes to ReRouted are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +Release tags use the form `vX.Y.Z` and match `package.json`. GitHub Releases carry the installable artifacts; this file is the durable narrative for humans and agents. + +## [Unreleased] + +### Changed + +- Formalized project governance, release lifecycle, PR/release note expectations, and repository hygiene (branch cleanup, merge defaults, maintainer docs). + +## [0.5.4] - 2026-07-18 + +### Fixed + +- Classify thrown context failures so they do not poison OAuth account pools. + +## [0.5.3] - 2026-07-18 + +### Fixed + +- Pre-output stream inspection pass-through and related streaming edge cases. + +## [0.5.2] - 2026-07-18 + +### Fixed + +- Bound pre-output stream inspection so inspection cannot hang the request path. + +## [0.5.1] - 2026-07-18 + +### Fixed + +- Route exhaust / fallback until a usable upstream response is obtained. + +## [0.5.0] - 2026-07-18 + +### Added + +- Headless Linux CLI and local web dashboard (`rerouted`, `/dashboard/`). +- Linux npm-compatible release tarball on stable GitHub Releases. + +### Changed + +- Product positioning covers macOS menu bar and Linux headless control plane. + +## [0.4.18] - 2026-07-18 + +### Added + +- Anthropic Messages compatibility (`/v1/messages`, token count, Claude Code path quirks). +- Explicit adaptive thinking support for Claude adaptive requests. + +### Fixed + +- Tool-use cycles and provider translation edge cases for Claude Code workflows. + +## Earlier 0.4.x + +See [GitHub Releases](https://github.com/gitcommit90/rerouted/releases) for artifact digests and notes prior to the Keep a Changelog narrative. Notable themes in late 0.4.x included signed/notarized distribution, in-app updates, named routes, OAuth account pools, OpenAI chat completions and Responses routing, and launch hardening. + +[Unreleased]: https://github.com/gitcommit90/rerouted/compare/v0.5.4...HEAD +[0.5.4]: https://github.com/gitcommit90/rerouted/releases/tag/v0.5.4 +[0.5.3]: https://github.com/gitcommit90/rerouted/releases/tag/v0.5.3 +[0.5.2]: https://github.com/gitcommit90/rerouted/releases/tag/v0.5.2 +[0.5.1]: https://github.com/gitcommit90/rerouted/releases/tag/v0.5.1 +[0.5.0]: https://github.com/gitcommit90/rerouted/releases/tag/v0.5.0 +[0.4.18]: https://github.com/gitcommit90/rerouted/releases/tag/v0.4.18 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 245c9e1..348f4b6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,9 +4,34 @@ Thank you for helping improve ReRouted. ## Current contribution status -ReRouted is open source under the [MIT License](./LICENSE). External code contributions are not currently accepted while the maintainer finalizes a contribution review process. +ReRouted is open source under the [MIT License](./LICENSE). **External code and documentation pull requests are not accepted** while the maintainer finalizes a review process. -Please do not open a pull request with code or documentation changes yet. It may be closed without review. Focused issues, feature requests, compatibility reports, and sanitized reproduction cases are welcome. +Do not open a pull request with code or documentation changes yet. It may be closed without review. Focused issues, feature requests, compatibility reports, and sanitized reproduction cases are welcome. + +When external PRs open, this file will describe CLA/DCO (if any), coding standards, and the review SLA. Until then, assume maintainer-only merges. + +## Project governance (maintainers) + +Authoritative policy: + +| Doc | Purpose | +| --- | --- | +| [docs/GOVERNANCE.md](./docs/GOVERNANCE.md) | Authority, branch model, quality bar, repo settings | +| [docs/release-lifecycle.md](./docs/release-lifecycle.md) | Idea → branch → PR → release process | +| [docs/release-checklist.md](./docs/release-checklist.md) | Packaging, notarization, publish, install verification | +| [CHANGELOG.md](./CHANGELOG.md) | User-facing history (Keep a Changelog) | +| [docs/architecture.md](./docs/architecture.md) | Runtime and data flow | + +**Every product change that ships must:** + +1. Live on a short-lived branch off current `origin/main`. +2. Include tests for behavior changes. +3. Pass `npm test` and `git diff --check`. +4. Update `CHANGELOG.md` under Unreleased when users will notice the change. +5. Use a unique `package.json` version for each published build. +6. Complete the release checklist before anyone calls the work “done.” + +Preferred merge method: **squash merge**, with **delete branch on merge**. ## Before opening an issue @@ -42,6 +67,8 @@ git diff --check Node.js 22.13 or newer is required. The headless runtime is supported on Linux. The packaged desktop application targets Apple Silicon and macOS 12 Monterey or newer. +Canonical clone directory name matches the GitHub repo: `rerouted` (for example `/root/rerouted` on the maintainer Linux host). The product display name is **ReRouted**. + Maintainers handle package version changes, signing, notarization, release publication, and installation verification. Reproduction branches should not include generated release artifacts or real provider credentials. ## Security reports diff --git a/README.md b/README.md index 8009468..a088644 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,8 @@ See [Privacy](./PRIVACY.md) for the local files ReRouted keeps, the network serv - For questions, reproducible bugs, and feature requests, use [GitHub Issues](https://github.com/gitcommit90/rerouted/issues). - For a suspected vulnerability, follow [the security policy](./SECURITY.md) and do not post credentials or sensitive details in a public issue. - Before sharing diagnostics, remove API keys, gateway keys, OAuth callback URLs or codes, account identifiers, email addresses, and any provider response that may contain private data. +- What shipped: [CHANGELOG.md](./CHANGELOG.md) and [GitHub Releases](https://github.com/gitcommit90/rerouted/releases). +- How this repo is run: [Governance](./docs/GOVERNANCE.md), [Release lifecycle](./docs/release-lifecycle.md), and the packaging [release checklist](./docs/release-checklist.md). ReRouted is open source under the [MIT License](./LICENSE). External code contributions are not currently accepted while the contribution process is finalized; focused issues and sanitized reproduction reports are welcome. See [Contributing](./CONTRIBUTING.md) for the current policy. diff --git a/docs/GOVERNANCE.md b/docs/GOVERNANCE.md new file mode 100644 index 0000000..aa39109 --- /dev/null +++ b/docs/GOVERNANCE.md @@ -0,0 +1,96 @@ +# Project governance + +ReRouted is an independent personal project maintained by [@gitcommit90](https://github.com/gitcommit90). This document defines how the public repository is run so every change is reviewable, tested, versioned, and released the same way. + +## Authority + +| Role | Who | Authority | +| --- | --- | --- | +| Maintainer | Repository owner (`gitcommit90`) | Merge to `main`, publish releases, change policy, close issues/PRs | +| Agent / automation | Local maintainers and CI | May open branches, run tests, draft PRs; may not publish a release without following [release-checklist.md](./release-checklist.md) | +| External contributors | Anyone else | Issues and sanitized reports only until external PRs are explicitly enabled in [CONTRIBUTING.md](../CONTRIBUTING.md) | + +There is no separate legal entity, community board, or multi-maintainer vote. Policy lives in this repository. Host-local packaging credentials and machine aliases stay outside git (see maintainer handoff on the build hosts, not in this repo). + +## Source of truth + +| Artifact | Canonical location | +| --- | --- | +| Product code | `main` on `https://github.com/gitcommit90/rerouted` | +| Public site | `https://rerouted.dev` (deployed from a versioned snapshot of `main`, never a dirty worktree) | +| Version number | `package.json` `version` field | +| User-facing history | `CHANGELOG.md` plus the GitHub Release body for that tag | +| Ship procedure | [release-checklist.md](./release-checklist.md) and [release-lifecycle.md](./release-lifecycle.md) | +| Architecture | [architecture.md](./architecture.md) | +| Security contact | [SECURITY.md](../SECURITY.md) | + +## Branch model + +- **Default branch:** `main` only. There is no long-lived `develop`. +- **Work branches:** short-lived, named for intent: + - `feat/` — user-visible capability + - `fix/` — defect + - `docs/` — documentation only + - `chore/` — tooling, governance, CI, repo hygiene + - `refactor/` — internal structure without intended behavior change + - `release/` — optional packaging-only branch (usually unnecessary) +- **Merge method:** squash merge preferred for feature work so `main` stays linear and each PR becomes one reviewable commit. Merge commits are allowed when preserving multi-commit history is intentional. +- **Delete on merge:** remote head branches are deleted after merge. +- **No direct force-push to `main`.** History rewrites of published tags or releases require an explicit maintainer decision. + +## Required quality bar (every change) + +No change lands on `main` without: + +1. A focused description of the user-visible problem and outcome (PR body or commit body for direct maintainer merges). +2. Tests for behavioral changes (`tests/*.test.js`) or an explicit justification when the change is docs/governance only. +3. `npm test` green on the branch (local and GitHub Actions). +4. `git diff --check` clean. +5. No secrets, private prompts, real OAuth material, generated DMGs/ZIPs, or host-only files (`AGENTS.md` and similar). + +UI changes should include current captures when the control plane layout changes in a way users would notice. + +## Versioning and releases + +- Semantic versioning on `package.json`: **MAJOR** for breaking local API or data migrations users must handle; **MINOR** for backward-compatible features; **PATCH** for fixes and small safe improvements. +- Every shipped macOS/Linux build has a **unique** version. Never rebuild and republish the same version number with different bits. +- A release is **not** “done” when code merges. It is done only when [release-checklist.md](./release-checklist.md) is complete: signed notarized macOS DMG + updater ZIP, Linux CLI tarball, published GitHub Release, update-feed check, and install verification. +- Draft and prerelease GitHub Releases are not update channels for the stable app. + +## Communication surfaces + +| Surface | Use for | +| --- | --- | +| GitHub Issues | Bugs, feature requests, questions (sanitized) | +| GitHub Security Advisories | Vulnerabilities only | +| GitHub Releases + `CHANGELOG.md` | What shipped | +| https://rerouted.dev | Product marketing and download entry | +| Pull requests | Maintainer (and future external) code review | + +## Repository settings (expected) + +Maintainers should keep these GitHub settings true: + +- Default branch `main` +- Delete head branches on merge: **on** +- Squash merge: **on** (preferred) +- Merge commit / rebase: optional +- Wiki: **off** (docs live in-repo) +- Issues: **on** +- Secret scanning + push protection: **on** +- Actions: run tests on `push` to `main` and on pull requests +- Branch protection on `main`: require status check **Tests / test** when the plan allows required checks; disallow force-push + +## Local clone naming + +- GitHub repository name: `rerouted` (lowercase). +- Canonical maintainer clone path on ProxUI: `/root/rerouted`. +- Product display name: **ReRouted**. +- npm package name: `@gitcommit90/rerouted`. +- macOS app bundle / DMG product name: `ReRouted`. + +Do not invent alternate public product names. Side folders such as release worktrees, site snapshots, or historical sandboxes are not the product root. + +## Policy changes + +Governance changes land through the same branch + test + merge path as code (docs-only PRs still use the PR template). Material policy shifts (accepting external PRs, changing license, moving ownership) require an explicit maintainer commit message and a `CHANGELOG.md` entry under the next release. diff --git a/docs/release-checklist.md b/docs/release-checklist.md index 3639312..88e9473 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -1,12 +1,14 @@ # Release checklist -This is the required finish line for every ReRouted change, including fixes, features, refactors, UI adjustments, and documentation iterations. Releases that include the headless runtime must verify both the macOS artifacts and Linux CLI package. +This is the required finish line for every **shipped** ReRouted product build (macOS app and/or Linux CLI). Process and policy live in [release-lifecycle.md](./release-lifecycle.md) and [GOVERNANCE.md](./GOVERNANCE.md). User-facing narrative belongs in [CHANGELOG.md](../CHANGELOG.md) before you package. -**Do not say "done" until every check has passed.** +Docs-only or governance-only merges may land without a new binary, but they still use a branch, tests when applicable, and changelog Unreleased notes when users will notice. + +**Do not say "done" for a product release until every check below has passed.** ## 1. Prepare the change -Start from the current remote `main`, create a branch, and give the app a new version so the installed build is unambiguous. +Start from the current remote `main`, create a branch, implement with tests, and update `CHANGELOG.md` under Unreleased. Give the app a new version so the installed build is unambiguous before packaging. ```bash git fetch origin @@ -14,7 +16,9 @@ git switch main git pull --ff-only origin main git switch -c +# After implementation and tests, when this branch will ship: npm version patch --no-git-tag-version +# Move Unreleased notes into ## [x.y.z] - YYYY-MM-DD in CHANGELOG.md ``` Use a minor or major bump when the scope warrants it. Do not reuse an already-installed version for a new iteration. diff --git a/docs/release-lifecycle.md b/docs/release-lifecycle.md new file mode 100644 index 0000000..a2f78d0 --- /dev/null +++ b/docs/release-lifecycle.md @@ -0,0 +1,128 @@ +# Release lifecycle + +End-to-end path from idea to installed build. Command-level packaging steps live in [release-checklist.md](./release-checklist.md). This page is the **process contract** every future change is expected to follow. + +```text + issue / intent + │ + v + branch from origin/main + │ + v + implement + tests + CHANGELOG (Unreleased) + │ + v + npm test · git diff --check · PR (or maintainer review) + │ + v + squash/merge to main · delete branch · CI green on main + │ + v + version bump on release commit (if not already on the PR) + │ + v + package macOS (sign/notarize/staple) + Linux CLI from exact main SHA + │ + v + draft GitHub Release · verify asset digests · publish + │ + v + update feed check · install on macair · Linux CLI smoke + │ + v + done (evidence recorded) +``` + +## 1. Plan the change + +- Prefer a GitHub Issue for user-visible bugs and features so history is searchable. +- Scope one PR to one concern. Do not mix unrelated refactors with a hotfix. +- Decide version impact early: patch vs minor vs major ([GOVERNANCE.md](./GOVERNANCE.md)). + +## 2. Branch and implement + +```bash +git fetch origin +git switch main +git pull --ff-only origin main +git switch -c feat/short-slug # or fix/ docs/ chore/ +``` + +- Keep the worktree free of host-only files and secrets. +- Add or update tests under `tests/` for behavior changes. +- Update `CHANGELOG.md` under `## [Unreleased]` as you go (not after packaging). + +## 3. Verify before review + +```bash +npm ci # when deps changed +npm test +git diff --check +``` + +For UI: inspect real panel/dashboard states; capture when layout changes. + +## 4. Pull request + +Use the repository PR template. Maintainers fill: + +- **Maintainer change** — problem and outcome +- **Verification** — checklist items actually run +- **Release notes** — paste the Unreleased bullets that belong with this PR + +CI must be green. External PRs remain closed per CONTRIBUTING until that policy changes. + +## 5. Merge + +- Prefer **squash merge** into `main`. +- Delete the head branch (repo setting + manual cleanup of leftovers). +- Confirm Actions on `main` still pass. + +## 6. Version and changelog for a ship + +When the change will be published as a binary/CLI release: + +1. Ensure `package.json` version is unique and not already tagged. +2. Move `CHANGELOG.md` `Unreleased` notes into `## [x.y.z] - YYYY-MM-DD`. +3. Commit on `main` (or as the final squash commit of the release PR). +4. Tag only the exact commit that will be packaged: `vX.Y.Z`. + +Docs-only or governance-only merges may wait for the next product release before a version bump, but still update `CHANGELOG.md` under Unreleased so notes are not lost. + +## 7. Package and publish + +Follow [release-checklist.md](./release-checklist.md) without skipping: + +| Artifact | Required | +| --- | --- | +| `ReRouted--arm64.dmg` | Developer ID, notarized, stapled | +| `ReRouted--mac-arm64.zip` | Same app bits; update.electronjs.org channel | +| `ReRouted--linux-node.tgz` | Headless CLI + dashboard | +| `ReRouted-linux-node.tgz` | Stable alias, identical bytes to versioned tarball | + +Publish a **draft** release first, verify GitHub asset digests match local SHA-256, then undraft and mark latest. + +## 8. Post-publish verification + +- Update feed: older app version receives the ZIP; current version returns HTTP 204. +- Install public DMG on `macair`; preserve Application Support. +- Smoke Linux CLI from the public URL. +- Completion report includes version, merged SHA, all artifact digests, release URL, and verification evidence. + +## 9. What “done” means + +| Claim | Minimum evidence | +| --- | --- | +| Code landed | Commit on `origin/main`, CI green | +| Fix verified | Tests + reproduction no longer fails | +| Release shipped | Checklist §9 evidence block complete | +| Site updated | Snapshot deploy from the intended `main` commit when landing content changed | + +If packaging, notarization, publish, or install verification was skipped, say so. Do not call the iteration done. + +## Related docs + +- [release-checklist.md](./release-checklist.md) — exact commands +- [signing.md](./signing.md) — code signing notes +- [architecture.md](./architecture.md) — runtime map +- [GOVERNANCE.md](./GOVERNANCE.md) — authority and repo policy