Skip to content

Contributing

0xfauzi edited this page Aug 25, 2026 · 3 revisions

Contributing

kstrl is run as a formal project: the process rules below are not suggestions, they are the mechanism that keeps an AI-built codebase trustworthy. PRs that skip them will be asked to redo the work.

The process rules (H1-H4)

  • H1 - No self-review. AI-generated code is never gated by AI self-review. Every PR is reviewed by a human (or an independent review pipeline the human triggers). If you used an agent to write the change, say so.
  • H2 - Calibration is the truth signal for prompts. Any change to an adversarial prompt body (architect, engineer, reviewer, security, distiller) must re-run the calibration suite and record the detection delta against the saved baseline. A prompt edit without a calibration check is treated as untested.
  • H3 - Prompt versioning. Every adversarial prompt declares a *_PROMPT_VERSION semver next to its body, and tests/test_prompt_versions.py snapshots each prompt as a (hash, version) tuple. Body, version, and snapshot always move together in one diff; the test suite AST-walks the package and fails on any unenrolled *_PROMPT constant.
  • H4 - State what was tested vs assumed. Every PR description and every "done" claim lists what was actually exercised versus what is assumed. "Smoke passed" without saying what was checked is presence-testing, not behavior-testing.

The R8 cycle added a fifth rule and R10 states how to satisfy it: no assumed thresholds, advisory first. A numeric gate (coverage floor, mutation score, autonomy entry count, control-chart parameter) is never chosen to make a feature shippable. It ships in advisory mode, recording what it would have blocked, and graduates to blocking once the operator has read its output on real runs; or it is replayed against recorded run data and the replay result is written into the tracker doc. See Roadmap for the ID scheme.

Coding standards

  • from __future__ import annotations at the top of every file; type hints on all signatures; T | None over Optional[T].
  • @dataclass for data containers (frozen=True when immutable); Protocol for interfaces.
  • snake_case functions, PascalCase classes, UPPER_SNAKE constants; absolute imports grouped stdlib / third-party / local.
  • No bare except:; no mutable default arguments; no pickle on untrusted data.
  • Atomic writes use tempfile.mkstemp + os.replace; every subprocess has a bounded timeout; every config dataclass has from_env() and load(root_dir).
  • Match the surrounding code's comment density and idiom. Comments state constraints the code cannot show, nothing else.

Verification before any PR

uv run pytest tests/ -v
uv run mypy kstrl/ --strict
uv run ruff check kstrl/ tests/

CI runs these plus a spine job; the fast test tier must be green. If you touch an adversarial prompt, also run calibration (H2) - note that it uses real LLM calls and is opt-in via KSTRL_RUN_CALIBRATION=1.

Design doctrine to respect

  • Adversarial mindset: when editing role prompts or role code, ask whether the change makes the role more skeptical or more eager to please. Prefer skeptical.
  • Halt over heroics: fail loudly; never silently degrade.
  • Audit trail: no silent code paths - decisions write records (findings, events, journal entries).
  • Enforcement reads artifacts: gates run on diffs, lockfiles, and tool output in the mechanical verifier - never on agent self-report.
  • Phase numbers are sticky: new pipeline phases take fractional numbers; existing numbering never shifts.
  • Budget respect: never bypass max_adversarial_calls or token budgets without explicit opt-in.

Picking up work

  1. Read Vision and Philosophy and the current tracker, docs/dark-factory-roadmap.md.
  2. Three milestones are open. The R10 milestone (#235) is the current cycle and its issues are written to be picked up cold: each states the change, the tests to write by name, and the acceptance conditions. The R8 milestone (#156) holds the release stage and runtime feedback; the R9 milestone (#217) holds continuous learning.
  3. Check the item's "User decisions required" dependencies in the tracker - some items are blocked on owner decisions and will say so.
  4. Comment on the issue before starting so work is not duplicated.

PR expectations

  • One tracker item (or one coherent slice of an L-sized item) per PR.
  • The PR updates the tracker doc's status in the same diff (audit trail).
  • The description covers: what changed, what was tested vs assumed (H4), and any deviation from the tracker's design with rationale.
  • Docs-only changes are exempt from calibration but not from review.

Conduct

Be direct, cite evidence, and treat skepticism as a courtesy - the whole project is built on adversarial review. Critique designs, not people.

Clone this wiki locally