pleach
Reference

Contributing

How to file bugs, propose features, and submit PRs against `@pleach/core` and the sibling SKUs.

Every shipping @pleach/* package ships under FSL-1.1-Apache-2.0 (Functional Source License with Apache 2.0 as the future license, auto-transitions to Apache 2.0 two years after first stable publish): @pleach/core, @pleach/tools, @pleach/react, @pleach/replay, @pleach/sandbox, @pleach/base-tools, @pleach/langchain, @pleach/compliance, @pleach/eval, @pleach/gateway, @pleach/mcp, @pleach/coding-agent, @pleach/observe, and @pleach/recipes. @pleach/trust-pack alone remains a reserved npm name at 0.0.1 · UNLICENSED. Contributions land through the standard GitHub workflow on each package's repository. This page is the short version; the upstream CONTRIBUTING.md in each package is the canonical source.

Where each package lives

PackageRepository
@pleach/coregithub.com/pleachhq/core
@pleach/toolsgithub.com/pleachhq/tools
Other @pleach/* siblingsRepositories land as each SKU ships its first cut

Issues and PRs land on the relevant package's repository. Cross-cutting issues (something that spans two packages, or something about the docs site itself) land on pleachhq/core with a label indicating scope.

Filing a bug

A useful bug report has four sections:

  1. What you did — minimal reproduction. A failing test case in defineTool shape is ideal; a code snippet that constructs a SessionRuntime and reproduces the issue is fine.
  2. What you expected — what the contract says should happen.
  3. What actually happened — observed behavior, including stack trace and any structured error code (1xxx–7xxx).
  4. Environment@pleach/core version, Node version, runtime (Node / Edge / Browser), provider, storage adapter.

Bugs without a reproduction are hard to fix. If the bug is non-deterministic, say so explicitly — the substrate's determinism contracts exist so non-determinism is unusual, and calling it out helps triage.

Proposing a feature

A feature proposal is an issue with a feature label that answers four questions:

  1. What problem are you solving? Not "I want X" — "X solves Y, which I can't solve today because Z."
  2. What does the API surface look like? A type signature is enough; a code sample is better.
  3. What does it interact with? Which existing primitives (SessionRuntime, channels, the audit ledger) does the feature touch?
  4. What can't you build today without this? Concrete; the substrate is intentionally small and resists scope creep.

Features that fit the existing contracts (a new built-in tool, a new prompt section primitive, a new stream observer verdict for an existing concern) land quickly. Features that change the substrate's structural commitments (the lattice, the singleton seam, the family lock) get deep design discussion first.

Submitting a PR

Three checks every PR runs through:

  1. npm test — the substrate's test suite, including determinism fixtures.
  2. npm run lint — the lint rules that enforce structural invariants (lint:harness-boundary, lint:callclass-literals, etc.).
  3. npm run audit:* — the audit gates that catch wire-format drift and out-of-lattice edges.

A PR that fails any of these is in the wrong shape. The lint rules are the substrate's invariants in CI form — adjust the code, not the lint config.

Commit shape

The upstream uses conventional commit prefixes. Common ones:

PrefixUse
feat:New feature
fix:Bug fix
docs:Documentation only
refactor:Code change without behavior change
perf:Performance improvement
test:Test-only change
chore:Build / tooling

Commits are squashed at merge; the squashed message takes the PR title's shape. Aim for one logical change per PR.

Test coverage

New features ship with tests. The substrate's test suite has three layers:

LayerWhat it tests
UnitPure functions (computeFingerprint, reducers, canonicalize)
IntegrationRuntime construction + executeMessage with mock providers
DeterminismRecorded fixtures replayed for byte equality

A feature touching the fingerprint, the audit ledger, or the channel reducers belongs in all three layers. A feature touching only a peripheral surface (a new React hook, a new query helper) belongs in unit + integration.

Docs updates

Public-API changes land with docs updates in the same PR. The docs site here (pleachhq/getpleach) is a separate repository; small API additions land as a docs PR after the package merges, or as a single PR that updates the package's own README + inline JSDoc.

For substantial new surfaces (a new exported subpath, a new plugin hook), the docs site gets a new page. The CLAUDE.md in this repo documents the voice and structure conventions.

Local development

git clone https://github.com/pleachhq/core
cd core
npm install
npm test

The substrate uses the standard npm workflow — no special build tooling, no monorepo wrangler. The examples/minimal-agent and examples/host-adapter directories run against the local source.

cd examples/minimal-agent
npm install
HARNESS_MOCK_MODE=true node index.mjs

For changes that touch the schema bundle:

npm run schema:validate    # checks SQL bundle integrity
npm run schema:apply-test  # applies against a test DB

The schema bundle's additive rule (no edits to existing files, new files only) is enforced by the validator.

What the substrate intentionally doesn't accept

A short list of patterns that consistently get rejected. Not because the work is bad — because the substrate's contracts foreclose them.

PatternWhy rejected
Async stream observersBreaks replay determinism by design
New channel kinds without commutative+associative reducersSame
Out-of-lattice graph edgesThe lattice is what makes cost / observability structural
mode: "replace" on safety policiesSafety stacks append-only by contract
Storage adapters that aren't append-only for auditWire-format break
Identity-like fields in the fingerprint cache keyDefeats interactive caching + replay
eval("...") or runtime code generationDeterminism + safety review impossible

If your feature looks like one of these, the design discussion needs to surface what you're really trying to accomplish — the substrate likely has a different primitive for the actual goal.

Security disclosures

Report privately, not in public issues

Email getpleach@protonmail.com for vulnerabilities. Public GitHub issues are the wrong channel — they tip off attackers before a fix ships.

Include:

  • A description of the vulnerability.
  • A reproduction (or proof-of-concept).
  • Affected versions if known.
  • Your preferred attribution (or anonymity).

The upstream SECURITY.md documents response timelines.

No paid bug-bounty program

Reports get a real response, not a payout. The substrate is small enough that triage and credit happen in the open.

Code of conduct

Standard Contributor Covenant. The full text lives at CODE_OF_CONDUCT.md in each repository. The short version: be kind, don't harass, don't gatekeep, take disagreement to substance rather than personalities.

License acknowledgment

By contributing to @pleach/core, you agree that your contribution is licensed under the same FSL-1.1-Apache-2.0 the package ships under.

No CLA. The license text in the repo is the agreement.

Where to go next

On this page