Synergy runs a multi-layer quality system that covers formatting, linting, type-checking, monorepo hygiene, CI workflow validation, secret scanning, package publishing validation, and tests. This runbook describes each layer, when to use which command, and how CI and local checks interact.
| Layer | Local command | CI job | Tool | Pre-push |
|---|---|---|---|---|
| Bun version check | (pre-push only) | — | check-bun-version |
✅ |
| Formatting | bun run format:check |
quality |
Prettier | ✅ |
| Lint | bun run lint |
quality |
oxlint | ✅ |
| Browser crypto contract | bun test --cwd packages/app test/testing/browser-crypto-contract.test.ts |
quality |
Bun source contract | — |
| Localization | bun run localization:check |
quality |
Lingui + source contract | — |
| Type checking | bun run typecheck |
typecheck |
tsc via turbo | ✅ |
| Monorepo deps | bun run monorepo:check |
quality |
sherif | ✅ |
| Dead code | bun run deadcode |
quality |
knip | — |
| CI workflow lint | bun run workflow:check |
workflow-validation |
actionlint + zizmor | — |
| Secret scanning | bun run secrets:check |
secret-scan |
gitleaks | — |
| Package validation | bun run package:check |
package-validation |
publint + attw | — |
| Tests | bun turbo test / bun run test:ci |
test |
Turbo + sequential Bun shards | — |
| Private HTTP browser smoke | bun run --cwd packages/app build && bun packages/app/script/private-http-smoke.ts |
test |
Playwright Chromium | — |
| Desktop checks | bun run desktop:test |
desktop |
bun test + build | — |
| Server health smoke | — | smoke |
Synergy health check | — |
The pre-push hook runs these checks in sequence. If any fails, the push is blocked:
bun script/check-bun-version.ts— verify the local bun version matchespackage.jsonbun run format:check— verify all files are formattedbun run lint— run oxlint with deny-warningsbun run typecheck— type-check all packages via turbobun run monorepo:check— validate monorepo dependency consistency
The pre-push hook is intentionally fast — it covers the most common issues but does not run tests, secret scans, or workflow validation. Those run in CI.
bun run quality:quick # format + lint + Skill/package-guide/test-layout checks + localization + typecheck + monorepo/package checksbun run quality # quality:quick + all tests (turbo test)This runs the full suite locally. CI runs the same checks in parallel jobs.
CI runs on push to dev / main and on pull requests targeting those branches. Jobs run in parallel:
| Job | Purpose |
|---|---|
quality |
Formatting, lint, browser crypto contract, test layout, localization, monorepo deps, and dead code |
typecheck |
TypeScript type checking |
test |
Non-Synergy package tests, private HTTP browser smoke, and sequential fresh-process Synergy shards |
package-validation |
publint + attw for publishable packages |
workflow-validation |
actionlint + zizmor for CI workflow files |
secret-scan |
gitleaks for secrets and credentials |
desktop |
Desktop typecheck, unit tests, build config validation, runtime smoke |
smoke |
Server health check smoke test |
All jobs must pass for a PR to merge. The package-validation and workflow-validation jobs are not in the pre-push hook — they require network access or special tooling that is available in CI but may not be installed locally.
The test job excludes synergy from the Turbo package pass, builds the App, verifies it through a genuine non-loopback HTTP origin, then runs the complete Synergy suite as four sequential fresh-process shards from packages/synergy. Each attempted shard emits an uploaded JUnit report. Coverage is not collected in the required CI path.
| Tool | Responsibility | When to run |
|---|---|---|
| Prettier | Repository-wide formatting | Every change through bun run format:check; write fixes with bun run format or ./script/format.ts |
| oxlint | Fast JavaScript/TypeScript linting without style-heavy churn | Every change through bun run lint; auto-fix safe issues with bun run lint:fix |
| sherif | Workspace package and dependency consistency | Every change through bun run monorepo:check, especially package manifest edits |
| knip | Dead code, unused dependencies, unused scripts, unresolved entries, and catalog hygiene | CI and explicit local checks through bun run deadcode; configure precise entries/ignores for dynamic or generated code |
| publint | npm package manifest, exports, and publish-shape validation | Publishable package, release, SDK, plugin, util, or Synergy Link protocol changes through bun run package:check |
| attw | TypeScript package resolution validation for published tarballs | Same path as publint through bun run package:check |
| actionlint | GitHub Actions syntax and expression validation | Workflow changes through bun run workflow:check and CI workflow-validation |
| zizmor | GitHub Actions security analysis | Workflow changes through bun run workflow:check and CI workflow-validation |
| gitleaks | Secret and credential scanning | Auth/provider/channel/config example changes through bun run secrets:check; all PRs through CI secret-scan |
| Localization gate | Catalog extraction drift, complete zh-CN coverage, strict ICU compilation, and App/UI source policy | Product copy, accessibility text, locale formatting, or shared UI changes through bun run localization:check |
| Browser crypto contract | Direct browser randomness under App/UI source must use the shared ordinary or strict utility boundary | Browser capability or identifier changes; every PR through CI quality |
The package:check script validates every publishable npm package in the monorepo:
| Package | Build | publint | attw (esm-only) |
|---|---|---|---|
@ericsanchezok/synergy-sdk |
✅ | ✅ | ✅ |
@ericsanchezok/synergy-util |
✅ | ✅ | ✅ |
@ericsanchezok/synergy-link-protocol |
✅ | ✅ | — |
@ericsanchezok/synergy-plugin |
✅ | ✅ | ✅ |
@ericsanchezok/synergy-plugin-kit |
✅ | ✅ | ✅ |
@ericsanchezok/synergy (wrapper) |
— | ✅ | — |
- publint validates package.json best practices (exports, types, module resolution)
- attw (
--profile esm-only) verifies the published package works with ESM consumers - The validation builds each package from source, packs a tarball from a temp-staged copy carrying the publishable manifest, and runs both tools; tracked package.json files are never rewritten
Run locally:
bun run package:checkThe workflow:check script uses an installed actionlint binary when available, otherwise downloads the pinned actionlint release, then runs zizmor for GitHub Actions security analysis.
Run locally:
bun run workflow:check # install actionlint locally to avoid the actionlint download fallbackThe secrets:check script and CI secret-scan job run gitleaks against the repository with the default rule set plus a narrow allowlist for fixture paths and explicit fake-token markers.
Run locally (requires gitleaks installed):
brew install gitleaks # macOS
bun run secrets:check| Failure | Likely cause | Fix |
|---|---|---|
| Formatting | Unformatted files | ./script/format.ts and re-stage |
| Lint | Code style violations | bun run lint:fix or fix manually |
| Localization | Catalog drift, missing translation, invalid ICU, or unclassified source copy | Re-extract and translate catalogs, or fix/classify the source violation |
| Typecheck | Type errors | Fix type errors in affected files |
| Monorepo check | Version mismatch across workspaces | Sync catalog versions in root package.json |
| Dead code | Unused dependencies or exports | Remove or export as needed |
| Workflow check | actionlint or zizmor violation | Fix workflow file syntax or security issue |
| Secret scan | Credential leaked in code | Rotate credential, rewrite history, update allowlist |
| Package check | publint or attw failure | Fix package.json exports or module resolution |
| Test failure | Runtime regression, leaked process state, or brittle isolation | Run the focused test, then bun run test:ci from packages/synergy; inspect the uploaded per-shard JUnit reports |
bun dev prepare
bun run qualitybun run quality:quickFor a narrower edit loop before the full quick gate, run the relevant individual command such as bun run format:check, bun run lint, bun run localization:check, bun run typecheck, or a focused package test.
The pre-push hook runs automatically. If you want to verify first:
bun run quality:quick./script/generate.tsbun run package:checkbun run workflow:check # workflow syntax + security analysis
bun run secrets:check # requires local gitleaks; CI always runs secret-scanbun run package:checkcd packages/synergy
bun test <relevant test files>
cd ../..
bun run quality:quickFor the complete core-runtime CI boundary, run bun run test:ci from packages/synergy. It executes four shards sequentially in fresh Bun processes; CI uploads one JUnit report per attempted shard.
bun run --cwd packages/app test
bun run --cwd packages/app typecheck
bun run --cwd packages/ui test
bun run --cwd packages/app build
bun turbo test
bun run quality:quickBrowser capability or bootstrap changes also run the static boundary and genuine non-loopback HTTP smoke:
bun test --cwd packages/app test/testing/browser-crypto-contract.test.ts
bun run --cwd packages/app build
bun packages/app/script/private-http-smoke.tsFor product copy, accessibility text, or locale-sensitive formatting, update the catalogs before those package and root gates:
bun run --cwd packages/app i18n:extract
bun run localization:checkThe App and shared UI packages both expose standard test scripts, so bun turbo test includes their centralized test/ suites. The App runner isolates its production CSS build contract from the unit-test process; the UI runner isolates the session-turn timeline suite because its process-wide module mocks must not leak into other shared UI tests.
For theme or color-token work, regenerate and verify the checked-in artifacts before the package suites:
bun run --cwd packages/ui generate:theme
bun test --cwd packages/ui test/theme.test.ts test/theme-generation.test.ts
bun test --cwd packages/app test/testing/color-token-contract.test.tsWhen a change adds or modifies quality commands, scripts, CI jobs, or pre-push checks, update:
docs/operations/open-source-quality.md— quality model and command/CI tablesREADME.md— the### Quality commandssectionCONTRIBUTING.md— PR preflight quality flowAGENTS.md— "Testing/Verification" and "Documentation Sync Rules" sectionspackages/synergy/AGENTS.md— scoped quality commands for core runtimepackages/app/AGENTS.md— scoped frontend/app verification.github/PULL_REQUEST_TEMPLATE.md— checklist entries.synergy/command/check.md— agent check command.husky/pre-push— hook content (verify the hook script itself)llms.txt— "Source Verification" section