Write automation in Python
- Pin uv in the project’s
mise.toml. - Install the pinned version with
mise install. - Write shell tooling in Python.
- Declare the Python range and dependencies in each portable script’s PEP 723 header.
- Use
dependencies = []when a script uses only the standard library. - Give public commands executable names without file extensions.
- Install each command in a directory on
PATH. - Commit the adjacent script lock.
- Run portable scripts with
mise exec -- uv run --locked --script PATH. - Keep existing project language toolchains under their owners.
Establish the contract
- Before a substantial change, name the consumer, observable result, invariant, scope, and non-goals.
- Treat an invariant as a rule that every legal value or operation preserves.
- Start with the implementation that owns the requested behavior. Read contracts, tests, or project guidance when the task needs them.
- Distinguish current behavior, intended behavior, assumptions, and unknowns.
- Treat summaries and plans as leads until source evidence supports them.
- Choose reuse, extension, a new owner, or investigation from the evidence.
- Reuse an owner that meets the contract.
- Define the smallest faithful acceptance test and its nearest counterexample.
- Name the evidence that ends the task.
Preserve established facts
- Parse external input once at each entry point into constrained values or explicit failures.
- Keep unchecked construction under the invariant owner.
- Make successful parsing, normalization, lookup, and authorization return facts that later consumers need.
- Make consumer contracts accept those stronger values.
- Preserve the facts through transformations. Do not reconstruct raw primitives to bypass them.
- Prefer representations that exclude invalid shapes by construction.
- When static enforcement is absent, use schemas, controlled APIs, closed tagged values, and focused runtime tests.
- Keep values with different meanings distinct even when their primitive representations match.
- Do not treat a name, alias, unchecked wrapper, comment, or prior guard as proof.
- Keep a small private fact local when no later consumer needs it.
- Add a representation to prevent a named misuse.
Model legal alternatives and transitions
- Represent finite alternatives with closed variants and case-specific data.
- Avoid tags with unrelated optional fields, Boolean modes, and nulls with several meanings.
- Handle closed alternatives exhaustively.
- Make a new supported case expose incomplete consumers.
- Reject unsupported external input explicitly.
- When compatibility permits unknown values, model them explicitly.
- Make each transition accept its legal source state and return its destination state or a defined failure.
- Expose restricted operations through the state or capability that supports them.
- Do not depend on remembered call order.
- Scope evidence to the identity, version, action, and lifetime it establishes.
- If external mutation or elapsed time invalidates a fact, establish it again.
- Do not claim that ordinary types prove fresh authorization, immutable external state, atomicity, or single consumption.
Give each rule one owner
- Give each invariant, transition, default, and protocol rule one authoritative owner.
- Derive other representations from that owner.
- Put behavior with the smallest type or module that owns its meaning.
- Do not infer ownership from syntax or convenience.
- Keep small public interfaces that preserve facts consumers need.
- Hide implementation choices and keep necessary effects explicit.
- Keep transport records and primitive encodings in explicit adapters.
- Preserve stronger contracts in application code on each side.
- Put encoding and format selection in output adapters.
- When real consumers need a common serialization contract, reuse one.
- If a shared contract changes, change its schemas, parsers, generated models, examples, and callers together.
- Preserve compatibility unless the task authorizes its change.
- State semantic model changes even when source syntax remains compatible.
Keep decisions pure and effects explicit
- Prefer immutable values and deterministic domain functions.
- Pass effect results into decisions as values.
- Isolate filesystem, network, process, clock, randomness, environment, and mutable-service access in explicit adapters or capabilities.
- Give related sequencing, retries, cancellation, resource ownership, and completion one coordinator.
- Keep core callbacks pure.
- Do not hide effects or mutable ambient state in closures.
- When callback behavior affects correctness, define its order, invocation count, lifetime, and escape behavior.
- Preserve failure identity through composition.
- Make changes to a failure’s meaning explicit.
- Define traversal order and failure behavior.
- Preserve predicate order, early returns, cleanup, cancellation, and transaction behavior during refactors.
Make failure behavior part of the contract
- Represent expected failures as finite cases with the facts callers need.
- Distinguish causes that need different responses.
- Do not use ambiguous nulls, Boolean flags, sentinels, parsed messages, or undocumented exceptions for expected failures.
- Translate documented external failures once in their adapter.
- Preserve platform exception and cancellation contracts.
- Do not catch defects and report success.
- Stop unsupported or unknown outcomes. Do not invent stronger values.
- Reject unmet preconditions before protected effects.
- Do not report completion or rollback without evidence.
- If causes remain ambiguous, add bounded stage and outcome diagnostics.
- Keep secrets and unnecessary payloads outside diagnostics.
Maintain source-backed knowledge
- Reuse the repository’s existing knowledge owner and stable concept paths.
- For an established OKF bundle, preserve its format and producer lifecycle.
- Keep material system claims linked to source evidence and related concepts.
- Explain responsibility, flow, legal state, failures, and recovery that the reader needs.
- Distinguish current source facts, accepted decisions, proposals, and unresolved gaps.
- After source changes, examine affected concepts and stale citations against the current implementation.
- Update the explanation when behavior changes.
- If the explanation remains accurate, record the source review without an unnecessary rewrite.
- Use the project’s format, link, coverage, and freshness gates.
- Do not equate a recent timestamp, resolving link, or digest match with factual correctness.
- Keep generated indexes, provenance, and evidence metadata under their producer.
- Do not start unrelated knowledge generation or a new store during ordinary code work.
- Preserve historical results as evidence of their original runs.
Prove the claim at the necessary mechanism
- Use evidence from the mechanism behind the claim.
- Use compiler rejection for type restrictions and schema rejection for payload constraints.
- Use runtime evidence for effects, concurrency, persistence, and host behavior.
- Derive expected results from requirements or an independent fixture.
- Do not use the production algorithm as its own oracle.
- Prove an accepted path and its nearest named misuse.
- When a precondition fails, assert that the protected effect does not run.
- For a behavior change, make the focused assertion fail for the missing behavior before implementation.
- Keep the command, fixtures, assertion, directory, and meaningful environment stable through the failing and passing comparison.
- Start reuse and behavior-preserving refactors from passing characterization.
- Do not manufacture a failure when the requested behavior exists.
- Treat unavailable tools, invalid fixtures, timeouts, and zero selected tests as missing evidence.
- If integration remains uncertain, prove one real path from caller to result before expansion.
- Run the project’s necessary gates.
- Repeat or broaden tests for changed inputs, failures, affected consumers, or a named unresolved risk.
- Report what each result proves and what remains unknown.
- Do not infer factual correctness or reader comprehension from a documentation score.
Complete the authorized outcome
- Complete authorized implementation and its necessary tests without routine permission requests.
- Resolve ordinary design choices from source evidence.
- If a missing fact changes acceptance, authority, or irreversible-action safety, ask for clarification.
- Complete independent authorized work first.
- Respect analysis-only requests and preserve unrelated work.
- Keep publication, deployment, and destructive actions within their explicit authorization.
- Prefer the smallest complete change that prevents the named misuse.
- Do not add speculative frameworks or competing owners.
- Report the result, changed contracts, exact test outcomes, and material limits.
- Use passed, failed, skipped, or not run for outcomes.
- Write direct prose with stable terms.
- Preserve identifiers, literal errors, and the user’s supplied facts.
- Do not claim a fix for an unreproduced failure.
- Do not infer model behavior from instruction text.
- State unresolved conditions and the next decisive evidence.