Skip to content
Public works board · Roadmap

Roadmap

What exists now, what is being built, and what is only proposed — each with the evidence behind it and the criterion that makes it done.

Last checked 2026-10-19 against Cuprum 0.2.0-beta2 and open pull requests. No delivery dates are promised.

Plate 06 Copper marks the end of an unfinished route. Dashed lines on the map are atmosphere; the board below is the status.

Before you read the board

How to read a status

  • Shipped

    Merged, tested, and released: in 0.1.0, or in a 0.2.0 beta.

  • In progress

    An open pull request exists. Plans count; merged does not.

  • Proposed

    Written down, with an exit criterion, and not started.

A phase number is not a status: the source roadmap has finished and unfinished steps side by side in several phases. Shipped cards say which PyPI release first carried the work.

The board

Shipped

27 items
  1. Roadmap 1.1–1.3 Command policy

    Catalogue, typed commands, and scoped policy

    Program values, sh.make builders, CuprumContext scopes, and before and after hooks.

    Done when Unknown programs are refused at construction; forbidden ones before spawn.

    Shipped Released in 0.1.0 Last checked 2026-10-19
    Evidence: Catalogue, typed commands, and scoped policy
  2. Roadmap 2.1–2.2 Pipelines and observability

    Pipelines, fail-fast, and telemetry adapters

    Composition with |, per-stage results, structured events, and logging, metrics, and tracing adapters.

    Done when The first failing non-final stage terminates the rest and is reported as failure_index.

    Shipped Released in 0.1.0 Last checked 2026-10-19
    Evidence: Pipelines, fail-fast, and telemetry adapters
  3. Roadmap 2.2.3 · ADR-013 · #375 Pipelines and observability

    GitHub Actions presentation sink

    An opt-in sink that folds a run into a log group and turns a failure into one annotation, or the same framing from RunOutputOptions(group=True, annotate_failure=True).

    Done when Capture, exit status, and the result are byte-for-byte unchanged by the sink.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: GitHub Actions presentation sink
  4. Roadmap 2.3 Pipelines and observability

    Concurrent command execution

    run_concurrent with bounded concurrency, collect-all or fail-fast, and results in submission order.

    Done when Hooks fire per command and failures map back to submission positions.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Concurrent command execution
  5. Roadmap 9.1.1–9.1.5 · #359 Pipelines and observability

    Line-level output and the idle heartbeat

    SafeCmd.lines(), on_line callbacks, and an opt-in keepalive for children that fall silent.

    Done when The heartbeat never terminates a process, extends a timeout, or enters captured output.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Line-level output and the idle heartbeat
  6. Roadmap 3.4 Command policy

    Execution timeouts

    Per-call, per-context, and scoped timeouts, raising TimeoutExpired with partial output.

    Done when Explicit beats ExecutionContext beats scope; the child is always reaped.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Execution timeouts
  7. Roadmap 3.1.1, 3.2.3–3.2.4 Builders and ergonomics

    Core builders and one-line catalogues

    Validated git, rsync, and tar builders, plus ProgramCatalogue.from_programs() and from_project().

    Done when A standalone script declares its programs in one call.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Core builders and one-line catalogues
  8. Roadmap 4.1–4.5 · ADR-016 Performance and parity

    Optional Rust stream pump

    A native inter-stage pump with Python fallback, backend selection, parity tests, and a benchmark ratchet, in one stable-ABI wheel per platform for CPython 3.12 and later. Technical preview.

    Done when Identical bytes on both backends; no native wheel is required to use Cuprum.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Optional Rust stream pump
  9. Roadmap 8.1, 8.4 Reliability

    Audited native boundaries

    The pump descriptor race closed, lifecycle modelled with Loom, and unsafe Rust confined to audited crates.

    Done when Verus, Kani, and Miri evidence archived for the applicable boundaries.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Evidence: Audited native boundaries
  10. PR #463 Command policy

    Catalogue-backed scoped contexts

    scoped(catalogue=…) establishes a scope directly from a catalogue rather than restating its allowlist.

    Done when Merged with tests and users’ guide coverage.

    Shipped Released in 0.2.0b1 Last checked 2026-10-19
    Pull request #463
  11. ADR-018 · #434 Command policy

    Explicit environment replacement and unset

    EnvMode selects an inherited, overlaid, or replacement child environment, and UNSET removes an inherited variable, without touching os.environ.

    Done when The effective mode reaches every ExecEvent and labels the execution and failure counters.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Explicit environment replacement and unset
  12. #440 · design §5.1.2 Command policy

    Scoped executable bindings

    bind_executable() runs a catalogued program from a pinned path or a resolver while the allowlist, metadata, and telemetry keep the logical name.

    Done when Resolution happens strictly after allowlist enforcement, and the result reports resolved_path.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Scoped executable bindings
  13. #514 Command policy

    sh.make resolves the scoped catalogue

    Inside scoped(catalogue=…), sh.make() resolves the program from that catalogue; an explicit catalogue= still wins, and the default applies only outside any catalogue scope.

    Done when A program the active catalogue does not list is refused when the builder is made, not at run time.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: sh.make resolves the scoped catalogue
  14. ADR-020 · #483 · #513 Builders and ergonomics

    A typed argument contract for builders

    Builders accept exactly ArgValue — str, int, float, bool, and paths — and reject bytes, lists, and other objects. A keyword that names an execution option, such as cwd= or timeout=, raises TypeError pointing at run_sync.

    Done when A static checker and the run-time check reject the same call; no value reaches the child as its repr.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: A typed argument contract for builders
  15. ADR-019 · #437 Builders and ergonomics

    An owned handle for a running command

    SafeCmd.start() returns a RunningCommand with wait(), signal(), terminate(), and kill(), settled once however the child ends; async with tears a live child down.

    Done when terminate() and kill() are safe to repeat after the child has gone, signal() on an exited child raises SignalAfterExitError, a stopped child still reports its output, and no child is left unreaped.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: An owned handle for a running command
  16. #444 Builders and ergonomics

    Byte-exact result mode

    run_bytes() and run_bytes_sync() on commands and pipelines return the child’s own bytes through BytesCommandResult and BytesPipelineResult, with every measurement intact.

    Done when run() never returns bytes, run_bytes() never returns text, and a timeout still carries partial output.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Byte-exact result mode
  17. PEP 561 · #501 Builders and ergonomics

    A typed package

    cuprum/py.typed ships in every wheel and source distribution, so type checkers read Cuprum’s annotations instead of Any.

    Done when A downstream type check resolves every exported name.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: A typed package
  18. #441 Pipelines and observability

    One terminal outcome per execution

    A settled event closes every observed execution exactly once with a bounded terminal_outcome; the metrics adapter counts failures and durations from it.

    Done when Spawn failures and cancellations settle without an invented exit code.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: One terminal outcome per execution
  19. ADR-019 · #437 Pipelines and observability

    Control observation

    observe_control() reports what signal(), terminate(), and kill() did to a child, with refusals as first-class outcomes and a bounded metrics hook.

    Done when Emission is fail-open, and a PID never becomes a metric label.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Control observation
  20. #435 Pipelines and observability

    Opt-in recovery from a closed echo destination

    BrokenPipePolicy.BEST_EFFORT disables echo for the affected stream alone when a sink raises BrokenPipeError; capture, line observation, and reaping continue.

    Done when STRICT stays the default, and the fallback is reported once through relay_fallbacks and the echo channel.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Opt-in recovery from a closed echo destination
  21. Roadmap 12 · ADR-021 · #438 Reliability

    Opt-in process-group ownership

    ProcessGroupPolicy.OWN_GROUP on the ExecutionContext makes the child a session and group leader on POSIX, so teardown reclaims descendants that hold a pipe open.

    Done when INHERIT stays the default; only the group the spawn created is signalled; Windows refuses rather than pretending.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Evidence: Opt-in process-group ownership
  22. ADR-023 · PR #625 · #442 Pipelines and observability

    Opt-in redaction for telemetry

    A RedactionPolicy of literals and patterns masks configured values in log records, spans, and Actions titles, without changing what runs or what is captured.

    Done when Inert by default, fails closed with RedactionError, and leaves bounded metric labels unchanged.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #625
  23. PR #511 · #445 Builders and ergonomics

    Streaming stdin and standard-stream redirection

    StdinStream feeds a child’s stdin from an async producer one chunk at a time, and StdioTarget sends stdout or stderr to a file, a descriptor, or the parent rather than a pipe.

    Done when More input than fits in memory can be fed, and a redirected stream never passes through the parent.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #511
  24. Roadmap 5.2.1 · PR #433 Performance and parity

    Cheaper per-line event emission

    A stream’s invariant event fields are computed once per observed stream rather than per line, with payloads unchanged.

    Done when Dataclass construction fell to 29.9% of the consume subtree against a 30% criterion, with the thin margin recorded.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #433
  25. Roadmap 6.1.1 · PR #432 Performance and parity

    A typed error boundary for the Rust streams

    A RustStreamError enum at the PyO3 boundary, so both backends fail the same way.

    Done when Error-mapping coverage at the boundary; proptest parity is the next step (6.1.2).

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #432
  26. PR #458 · #428 Reliability

    Safe native I/O on Windows

    The native path is constrained to handles that synchronous I/O can use; a raw overlapped handle is rejected as windows_raw_handle_rejected rather than used.

    Done when Merged with Windows coverage; pipeline hops there keep using the Python pump and stay correct.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #458
  27. PR #468 · #427 Reliability

    Wider Miri coverage

    Miri runs across more of the Rust stream boundary.

    Done when Merged, with the new evidence archived.

    Shipped Released in 0.2.0b2 Last checked 2026-10-19
    Pull request #468

In progress

3 items
  1. PR #622 · #436 Reliability

    Bounded output delivery off the execution loop

    An opt-in worker and byte-bounded queue so a slow sink cannot stall the run’s event loop; saturation drops presentation output and says so, while capture stays complete.

    Done when Synchronous delivery is unchanged by default; drops and worker failures are categorized and countable.

    In progress Last checked 2026-10-19
    Pull request #622
  2. PR #619 · Roadmap 6.1.2 Performance and parity

    Proptest parity at the stream boundary

    A plan to drive the compiled consume boundary with generated UTF-8 and malformed bytes against the Python consumer, with committed replay evidence.

    Done when Identical results on both sides for every generated payload, with shrinking and replay recorded.

    In progress Last checked 2026-10-19
    Pull request #619
  3. PR #574 · Roadmap 5.2.2 Performance and parity

    Cheaper per-hook dispatch

    A plan to remove the per-hook awaitable check from per-line event dispatch while keeping payloads, hook order, and failure semantics.

    Done when Judged on its own profile criterion, since it shifts the 5.2.1 share by succeeding.

    In progress Last checked 2026-10-19
    Pull request #574

Proposed

10 items
  1. Roadmap 11 · RFC 0001 Builders and ergonomics

    Test doubles without a process

    An execution backend seam above the spawn, so a caller’s policy module can be tested for what it asked to run, with a recording double, and without a PATH stub.

    Done when A substituted run emits the same events and hooks, creates no process, and never weakens the catalogue or allowlist checks.

    Proposed Last checked 2026-10-19
    Evidence: Test doubles without a process
  2. Roadmap 3.1.2 Builders and ergonomics

    A scaffold for project builders

    A template module and checklist for writing project-specific builders.

    Done when The template and checklist are in the users’ guide.

    Proposed Last checked 2026-10-19
    Evidence: A scaffold for project builders
  3. Roadmap 3.2.1–3.2.2 Builders and ergonomics

    Opt-in attribute-style commands

    sh.register("ls", LS)-style sugar with allowlist enforcement and static-analysis support.

    Done when Registered attributes stay type-checked; nothing is discovered from PATH.

    Proposed Last checked 2026-10-19
    Evidence: Opt-in attribute-style commands
  4. Roadmap 3.3 Command policy

    Policy toggles and recommended defaults

    Switches for narrowing, unsafe-namespace warnings, and default echo, with safe defaults. Executable bindings are deliberately not part of this item.

    Done when Documented defaults and a migration note in the release notes.

    Proposed Last checked 2026-10-19
    Evidence: Policy toggles and recommended defaults
  5. Roadmap 6.2–6.4 Performance and parity

    Rust capture for capture-only streams

    Route fd-backed, UTF-8, capture-only streams through the Rust consume helper.

    Done when At least 20% lower wall time than the tuned Python baseline, or a recorded negative result.

    Proposed Last checked 2026-10-19
    Evidence: Rust capture for capture-only streams
  6. Roadmap 7 Performance and parity

    Raw-sink echo and tee acceleration

    A native helper for qualifying sinks, profiled before it is built.

    Done when A bounded, measured opportunity before any implementation.

    Proposed Last checked 2026-10-19
    Evidence: Raw-sink echo and tee acceleration
  7. Roadmap 8.5.1 Performance and parity

    A native wheel for Windows on Arm

    A cp312-abi3 win_arm64 wheel, planned for a later 0.2.0 beta.

    Done when The release builds the wheel, and CI installs it and sees is_rust_available() return True.

    Proposed Last checked 2026-10-19
    Evidence: A native wheel for Windows on Arm
  8. Roadmap 10 · after 0.2.0 Performance and parity

    Free-threaded stable-ABI wheels

    An abi3t wheel (PEP 803) so free-threaded CPython 3.15 gains the Rust pump, after auditing both layers for GIL-free safety.

    Done when Free-threaded CI passes without re-enabling the GIL, and installers pick the right wheel on every interpreter.

    Proposed Last checked 2026-10-19
    Evidence: Free-threaded stable-ABI wheels
  9. Roadmap 8.3 Performance and parity

    Decide on native orchestration

    Prototype a synchronous native subprocess path and decide whether pipeline orchestration goes native.

    Done when A recorded decision with measurements.

    Proposed Last checked 2026-10-19
    Evidence: Decide on native orchestration
  10. Setwork Builders and ergonomics

    Setwork: generated typed adapters

    A companion compiler that turns command descriptions into typed functions returning SafeCmd.

    Done when A publishable first corpus; see the Setwork preview.

    Proposed Last checked 2026-10-19
    Read the preview
In a rainy alley under a drone’s searchlight, the guardian plumber kneels at an opened utility cabinet, fitting a new copper tee into a tangle of grey conduit beside a pasted pipe-route diagram, while Copper sits on the tool bag and watches.
Plate 07 Later, in another Philadelphia, the guardian plumber fits a legible tee into an opaque one. Copper supervises.

Public works

Follow the work, or join it.

Every card links to its evidence. The source roadmap has the detail behind each step, and issues are the place to argue for a route that is not on the map yet.