Thank you for improving the BSV TypeScript stack. This monorepo is one coordinated system: shared specifications, public packages, infrastructure, documentation, conformance vectors, quality controls, and release machinery must evolve without drifting apart.
This is the canonical contribution policy for the entire repository. Package
directories do not define separate conventions. AI agents must also read the
root AGENTS.md.
Follow the CODE_OF_CONDUCT.md. Report vulnerabilities
privately under the security policy; never put secrets,
exploit details, private keys, tokens, production data, or uncoordinated
vulnerability reports in a public issue or pull request.
Use the root issue forms for reproducible defects and proposals. Discuss a substantial new capability, new package, specification change, public API change, or migration before implementing it. A narrowly scoped compatible fix may proceed directly when its intent and evidence are clear.
The current sources of truth are:
package.json,pnpm-workspace.yaml, and package manifests for toolchain, workspace, and package metadata;governance/repository-health/projects.jsonfor project ownership, profiles, criticality, runtime targets, and release routes;specs/andconformance/for portable protocol contracts;docs/and package READMEs for supported usage and operations;governance/for machine-enforced policy, exceptions, package release notes, service contracts, and artifact ownership; and- root
.github/for all issue, pull request, dependency, analysis, CI, and release automation.
Historical planning records and imported package files are evidence, not authority, when they disagree with current code, specifications, governance, or CI.
Use a current branch from main and the exact toolchain declared at the root:
corepack enable
pnpm install --frozen-lockfile --ignore-scripts
pnpm rebuild esbuildThe install denies dependency lifecycle scripts, matching CI’s supply-chain boundary. Rebuild only a repository-audited native tool when an applicable workflow or package guide requires it.
Before editing:
- inspect the working tree and preserve unrelated changes;
- identify all affected packages, dependents, runtimes, specifications, generated artifacts, and deployed services;
- read their README and relevant docs/specs;
- inspect open issues and pull requests for overlapping work; and
- determine the project tier and required consumer profiles from governance.
Maintainer-authorized agents for sirdeggen, ty-everett, and BraydenLangley must also follow
the BotBoard and per-turn Lockfile protocol.
Other contributors do not need a BotBoard handle.
The default expectation is no consumer breakage.
- Preserve public exports, declaration shapes, import conditions, supported runtime targets, documented inputs, defaults, errors, wire formats, serialization, persistence, browser/mobile behavior, and operational contracts.
- Prefer additive changes and deprecation over removal. A breaking change requires explicit maintainer approval, the appropriate SemVer release, before/after migration instructions, cross-package coordination, and a rollback or forward-fix plan.
- Treat specifications and conformance vectors as implementation-independent contracts. A TypeScript-only convenience must not accidentally make the reference behavior incompatible with another conforming implementation.
- Do not make a behavior change solely to appease an analyzer. Determine whether the finding is real, fix it safely, and retain a governed, evidence-backed exception only when compatibility or correctness genuinely requires it.
Tier 0 changes in @bsv/sdk, @bsv/verifast, and
@bsv/wallet-toolbox receive the most rigorous self-review and evidence.
Cryptography, Script/consensus behavior, transaction encodings, WASM/worker
interfaces, wallet persistence/signing, authentication, remote input, and
release controls require explicit trust-boundary and compatibility review.
Public services intentionally support deployed applications, browsers, WUI, mobile devices, and unknown future domains. Preserve public, credential-free wildcard CORS where it is the established default. Operators may opt into allowlists, but CORS/CSP/origin filtering must not replace protocol authentication, signatures, authorization, validation, rate limits, or bounds.
Every change should leave the repository easier to verify:
- keep TypeScript strict and lint output at zero warnings;
- use the root Oxlint and Prettier policies without package-local alternatives;
- add focused regression and negative tests for changed behavior;
- add integration, consumer, conformance, property, mutation, browser, mobile, or operational evidence when the boundary warrants it;
- update public JSDoc, READMEs, examples, generated documentation, support claims, specifications, and runbooks in the same pull request; and
- regenerate owned artifacts from their source—never edit generated bytes to disguise drift.
Tests must contain meaningful assertions. Do not skip, weaken, delete, rename, or reclassify a test merely to make CI green. Manual, live, resource-intensive, property, mutation, and conformance gaps follow the governed test-quality registries and removal conditions.
Use a short edit loop, then qualify a coherent batch before pushing. While editing, run the regression/negative test for the changed behavior and lint and format the changed files. Use your package runner's focused test selector; do not restart every workspace suite after each small edit.
Preview a dependency-aware local plan without starting expensive campaigns:
node scripts/ci-local-feedback.mjs --base origin/main
# Machine-readable planning for an agent or editor:
node scripts/ci-local-feedback.mjs --base origin/main --jsonChoose the actual intended PR baseline. The plan includes the full committed branch diff plus staged, unstaged and authored untracked changes, excludes ignored build/sandbox output, and preserves both paths of moves. The commands validate working-tree bytes; align the index and working tree before treating their results as evidence for the next push. Directly changed packages run coverage; affected dependents run regressions and their declared consumer/platform checks; prerequisites build without duplicate tests. Critical boundaries retain property/mutation and compatibility requirements. The printed commands are advisory: review the changed contract and applicable service/platform profile, especially for new or unknown boundaries. The plan does not grant a remote scope skip or qualification.
Reuse a frozen install and exact-input build outputs during the edit loop. On a
cold checkout, install with pnpm install --frozen-lockfile --ignore-scripts,
rebuild only audited tools as documented by CI, and build the package graph
before typechecking consumers that require workspace declarations. Invariant
checks run once for the completed batch before opening/updating the PR:
pnpm health:check
pnpm lint
pnpm format:check
pnpm typecheck
pnpm audit:securityThen run the checks implied by the change:
# Workspace build and deterministic tests
pnpm build
pnpm test
# Affected package examples
pnpm --filter @bsv/sdk test
pnpm --filter @bsv/sdk test:coverage
pnpm --filter @bsv/sdk pack:check
# Portable behavior and documentation
pnpm conformance
pnpm docs:facts:check
pnpm docs:examples
pnpm docs:build
# Governed high-risk boundaries
pnpm test:property
pnpm test:mutation --target <target>Use the package’s declared test:browser, test:mobile, test:consumers, or
other profile command when applicable. Root toolchain, SDK, CI, or governance
changes may select the full workspace test scope. Mutation testing does not run
on pull requests; the full registry runs on a manual CI dispatch, the
scheduled Mutation quality workflow, and release qualification. Infrastructure or
container changes require their root CI matrix and runtime-contract evidence;
do not substitute a macOS image build for hosted Linux/amd64 validation.
Local checks are necessary evidence, not authority to bypass remote checks. Record the exact commands and results in the pull request.
Batch related fixes after local feedback and self-review before the next push. Run affected deep checks locally where the platform supports them, with source, configuration and property seed fixed. Measure comparable wall time and worker contention rather than assuming every developer machine is faster. Avoid nested worker pools or concurrent heavy campaigns that starve another agent. Hosted CI verifies the resulting exact head and platform-specific requirements; retain its complete required gate and investigate failures without automatic rerun loops. Full workspace/campaign checks belong at shared-control changes, affected critical boundaries and the existing scheduled/release qualification, rather than every edit. Do not use stale local reports as current-head evidence.
Dependabot identifies candidates; it does not decide that an update is safe. For every manifest, lockfile, container base, action, or generator dependency change, review and record:
- upstream release notes, security relevance, and why the change is needed;
- Node/browser/mobile/build/runtime and peer compatibility;
- the complete transitive graph and deduplicated frozen lock;
- high/critical audit results and CodeQL/security impact;
- affected package, packed-consumer, conformance, and platform tests;
- bundle-size and performance effects; and
- affected public package versions and release notes.
First-party @bsv/* dependencies are synchronized through the protected
release-aware graph. Do not re-enable generic automation for unpublished
sibling versions. Major runtime, database, compiler, React Native, build, and
container migrations are coordinated programs, not routine bumps.
Do not introduce a broad override or suppression. If no compatible upstream fix exists, register the narrowest temporary exception with an owner, evidence, review date, objective removal condition, and tests. Rehearse removal after relevant upstream releases. Elapsed documentation and exception review dates are maintenance warnings in source CI, enforced by the separate weekly Maintenance review deadlines workflow. Passing time alone must not block a PR; structural errors, generated drift, security audits, and code checks still do.
Follow docs/about/versioning.md.
When a public package’s published bytes or manifest change:
- choose the SemVer impact from the consumer-visible contract;
- bump only affected packages and dependents whose packed contract changes;
- update the exact entry in
governance/package-release-notes.json; - regenerate the package API and migration ledger with
pnpm docs:packages; - update the package README, API docs, and examples as needed; and
- update a package-local
CHANGELOG.mdwhen that package already has one.
Every release-note entry includes a migration decision. Say explicitly that no consumer migration is required when behavior is unchanged. An incompatible change needs before/after examples, deployment and persistence impact, coordination with first-party dependents and other implementations, and a rollback or forward-fix plan.
Repository-only policy or documentation that is excluded from a package artifact does not require a cosmetic version bump.
Use the root pull request template and keep the PR draft while work or evidence is incomplete.
Before pushing, self-review the complete diff for:
- correctness and root cause;
- security and trust-boundary impact;
- public API, wire, persistence, runtime, and cross-implementation compatibility;
- tests, coverage, package artifacts, bundle size, and performance;
- dependency and release implications;
- documentation, changelog, migration, and operator impact; and
- accidental generated, vendored, secret, or unrelated changes.
After every push, remain responsible for the exact head:
- wait for all applicable GitHub checks to reach a terminal state;
- fix every failure or unexpected skip and rerun it;
- resolve all review conversations;
- require zero new Sonar findings, zero unreviewed Sonar hotspots, and zero new CodeQL alerts; and
- verify that the reviewed SHA is still the PR head.
SonarCloud’s aggregate “Quality Gate passed” result is not sufficient. The repository-owned exact-head zero-finding job and complete merge gate are the authority. Reclassifying a new issue as accepted or false-positive does not make it mergeable.
Do not call a PR complete or hand it off with pending or failed CI. If a check is transient, rerun and continue monitoring. If work must genuinely transfer to another person, describe the unresolved state explicitly instead of presenting it as finished.
One qualified maintainer approval is sufficient. Maintainers and admins may merge after the exact head is green and review threads are resolved; an independent last-pusher is not required.
Source merge, package publication, image publication, and deployment are separate states. Do not publish from a workstation or create a release tag unless an operator explicitly requests that action. Protected root workflows build immutable candidates, scan them, generate SBOMs, attest provenance, and reconcile registry state.
For a release or deployed change, retain source SHA, workflow, artifact digest, version, migration/rollback evidence, and live validation as applicable. Never claim availability from a local build.