Thanks for considering a contribution. Before sending a PR, please read this whole document. The framework is held to a small set of non-negotiable invariants; PRs that violate them will not be merged regardless of feature appeal.
These are the rules the framework is built on. Every contribution must preserve them.
- Given the same inputs and the same
now, every framework function must produce byte-identical outputs. - No
Math.random, noDate.now()inside cognition paths —nowis always an argument. - IDs are derived deterministically (
makeId(...parts)+fnv1a), never randomly.
- Every signal, memory entry, report, decision, audit entry, and visibility change must carry a complete provenance trail: who produced it (agent, reviewer, ingestion adapter), when, and what it was derived from.
- "Anonymous" or "system-wide" provenance is not allowed.
- Confidence is a first-class field,
confidence ∈ [0, 1]. Not optional. Not implicit. - Do not collapse multiple signals into a scalar score without preserving the underlying signals.
4. No hidden inference
- If your code makes a probabilistic judgment, the judgment must be a
Signalwith provenance, not a hard-coded branch. - Heuristics are allowed; undocumented heuristics in critical paths are not.
- Pipeline stages, candidate states, kanban columns, applicant statuses — these are product concerns, not framework concerns.
- The framework reasons about people and organizations. Products built on top can model stages.
- Every score must be reproducible from inputs alone, and every input must be a signal with provenance.
- Authorization is by capability, not reviewer role. Adding a "if reviewerType === X" gate to bypass a capability check is a bug.
- New actions must declare their required capability in
CAPABILITY_FOR_ACTION.
- New cognition behavior must come with a benchmark scenario (in
lib/framework/src/benchmarks/). - New security behavior must come with a security benchmark scenario.
- Append-only artifacts (audit entries, signed actions, visibility history) must remain append-only.
- Returned references must be unmutable (frozen) or copies.
- Anyone with the inputs must be able to replay the framework to the same state. If your change breaks replay, it must add a deterministic migration path.
- Open an issue first for non-trivial changes. Use the appropriate issue template.
- Fork, branch, and implement.
- Run the full local check:
pnpm run typecheck pnpm benchmark:cognition pnpm test:cognitive-smoke
- If your change affects the HTTP contract, regenerate:
pnpm --filter @workspace/api-spec run codegen
- Open a PR using the PR template. Be explicit about which invariants your change touches and how you preserved them.
- Imperative, specific, and module-scoped:
security: derive required capability from action in AccessDecisionEngine. - No emoji prefixes. No
chore:for substantive changes.
- The cognition snapshot (
tests/cognitive-smoke/snapshot.json) is intentional. If you regenerate it, your PR description must explain why the output changed. - Snapshot updates without a corresponding cognition or schema change will be rejected.
- Place it under
lib/framework/src/agents/<area>/with its own module folder. - Declare a manifest:
{ id, role, capabilities, defaultProvider }. - Register it in the agent registry.
- Add a benchmark scenario that exercises its decision path.
- Update the relevant console page if the agent surfaces a new artifact kind.
- Skills live under
lib/framework/src/skills/<category>/. - Declare inputs → outputs as typed interfaces. No
any. - Skills must be pure with respect to their inputs +
now. - Wire it into the skill registry.
- Adapters live under
lib/framework/src/ingestion/adapters/. - Adapters must:
- declare a source kind,
- produce normalized signals with provenance,
- declare a reliability profile (or compute one),
- never silently drop ambiguous inputs — write a conflict entry instead.
- Add a benchmark scenario that ingests a synthetic payload through your adapter.
- Place it under
lib/framework/src/cognition/. - Cognition modules consume signals and produce signals — never side-effects.
- Disagreement must be preserved through your module, not collapsed.
- Update the snapshot manifest; provide a justification in the PR.
- Add the capability to
Capabilityinsecurity/types.ts. - Add the action to
AccessActionand map it inCAPABILITY_FOR_ACTION. - Update default capability bundles in
DEFAULT_CAPABILITIES_BY_TYPEonly if the new capability is broadly applicable; otherwise leave it explicit. - Add a benchmark scenario that asserts denial for a reviewer without the capability.
- Cognition benchmarks:
lib/framework/src/benchmarks/corpus.ts(scenarios) +lib/framework/src/benchmarks/(harness). The committed snapshot lives attests/cognitive-smoke/snapshot.json. - Security benchmarks:
lib/framework/src/security/benchmarks.ts. - Each scenario must be:
- synthetic (no real data),
- deterministic (same inputs → same outputs),
- documented (what it asserts and why).
- Place it under
lib/framework/src/collaboration/. - Disagreement and consensus must remain inspectable; do not merge dissent silently.
- TypeScript strict mode,
noImplicitAny,noUncheckedIndexedAccess. - NodeNext module resolution. Imports include the
.jsextension. - No
console.login server code. Usereq.login route handlers and the singletonloggerelsewhere. - Prefer named exports. Prefer interfaces over type aliases for public shapes.
- Keep files small. Split out subengines into their own modules.
Reject if:
- Any invariant above is weakened or worked around.
- Snapshots changed without justification.
- Authorization added through reviewer-type rather than capability.
- New mutable references returned from append-only structures.
- New code lacks provenance on its artifacts.
- New cognition path lacks a benchmark scenario.
By contributing you agree to the Code of Conduct.