Deterministic Critical Chain Project Management (CCPM) scheduler: validate a project network, build a resource-leveled buffered schedule, verify it, and plot a buffer-aware Gantt chart. Library + CLI, designed for both humans and AI agents.
Project description
ccpm-scheduler
Deterministic Critical Chain Project Management (CCPM) scheduling as a Python library and CLI — for humans, for AI agents, and for embedding in other tools.
Give it a project network (tasks, dependencies, duration estimates, resource assignments) plus resource availability, and it produces a proper Critical Chain schedule: resource-leveled, scheduled as late as possible, protected by a project buffer and feeding buffers, with a buffer-aware Gantt chart.
Same input always yields byte-identical output — the scheduler is fully deterministic, so it is scriptable, diffable, and testable.
Status
Phases 1–2 complete: extracted behavior-preserving from the
ccpm-scheduler Claude skill
(guarded by byte-identical golden tests), with a typed model, library API,
and the ccpm-scheduler CLI. Coming next (see PLAN.md): the
Claude skill drives this CLI (Phase 3), and the
our-planner GUI imports the library
(Phase 4).
CLI
Built for humans and AI agents: exit codes are a contract (0 = ok,
1 = problems found with the report still emitted, 2 = usage error), --json
prints a machine-readable document, there are no interactive prompts, and the
same input always produces byte-identical output.
ccpm-scheduler validate tasks.csv resources.csv calendar.csv
ccpm-scheduler build tasks.csv resources.csv --calendar calendar.csv \
--out-dir plan --title "Website relaunch"
ccpm-scheduler check plan/schedule.csv tasks.csv resources.csv calendar.csv
ccpm-scheduler plot plan/schedule.csv plan/gantt.png --resources resources.csv
ccpm-scheduler schema network # JSON Schema of the input format
The network input is either CSV files or a single JSON document (a path, or
- for stdin) in the exchange format:
echo '{"tasks": [...], "resources": [...]}' | ccpm-scheduler build - --json
build validates first: on a broken network you get the same coded issue
report as validate (exit 1) and no files. --json reports carry stable
machine-readable issue codes (E_CYCLE, E_NO_RESOURCE,
E_FRACTIONAL_ALLOCATION, …) plus the offending task/resource ids;
ccpm-scheduler schema report describes the shape.
Library API
from ccpm_scheduler import (load_network, validate_network,
build_schedule, check_schedule, plot_schedule)
network = load_network("tasks.csv", "resources.csv", "calendar.csv")
report = validate_network(network) # ValidationReport with coded Issues
if report.ok:
result = build_schedule(network, title="My project")
assert check_schedule(result.schedule, network).ok
plot_schedule(result.schedule, "gantt.png",
resources=network.resources, calendar=network.calendar)
print(result.stats.status_line("My project"))
Validation issues carry machine-readable codes (E_CYCLE, E_NO_RESOURCE,
E_FRACTIONAL_ALLOCATION, …) plus the offending task/resource ids, so an
embedding tool can annotate its own UI. Networks also load from a JSON
exchange format (network_from_json / network_to_json) that accepts
structured predecessor links ({"id": 2, "type": "SS", "lag": 2}), numeric
ids, and per-resource allocation maps — the shape GUI tools naturally emit.
Fractional allocations and capacities are rejected with precise errors in v1
(whole resources only).
(python -m ccpm_scheduler is equivalent to the ccpm-scheduler command;
the individual stages also remain runnable as python -m ccpm_scheduler.validate etc. with their original argument conventions.)
Input contract
tasks.csv — id, name, realistic_duration, optimal_duration (optional), predecessor_ids, resource_ids, url (optional)
realistic_duration: estimate with safety included;optimal_duration: padding-free estimate. Ifoptimal_durationis missing, the classic 50% cut is applied. (Legacy namesduration_safe/duration_aggressiveare accepted.)predecessor_ids: semicolon-separated links — bare id = Finish-to-Start, typed links with lag supported:A:SS+2,A:FF,A:SF. Buffer rows in the output use the CCPM-specific:PB/:FBlink types.resource_ids: semicolon-separated; every task needs at least one resource.
resources.csv — id, name, capacity, url (optional); capacity defaults to 1.
calendar.csv (optional) — resource_id, from, to, capacity: overrides a
resource's capacity on the half-open day range [from, to); capacity = 0
means unavailable. Tasks execute contiguously — they never pause across an
outage.
Durations are working days; the schedule uses integer day offsets from day 0.
Output
schedule.csv— tasks and buffers with start/finish, chain membership (critical,feeding-n), and link notation (buffers attached via:PB/:FB)summary.md— critical chain, project duration, buffer sizes, promised completion date (= end of the project buffer)gantt.png— critical chain, feeding chains, buffers, dependency arrows, and a resource-utilization panel on the same time axis
Development
uv sync
uv run pytest
The golden tests in tests/ assert byte-identical schedule.csv/summary.md
for five reference projects. Regenerate goldens only for deliberate, reviewed
behavior changes.
License
Dual-licensed under either of MIT or Apache License 2.0, at your option.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ccpm_scheduler-0.4.0.tar.gz.
File metadata
- Download URL: ccpm_scheduler-0.4.0.tar.gz
- Upload date:
- Size: 122.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e779b4fb1c6ebd2e1ca5fa6584f235739548302b4d1f7ed3df63c1264393472
|
|
| MD5 |
a32455f673854e90f8089633c038483b
|
|
| BLAKE2b-256 |
79d35605f6e51c4cb8dd321a53db06e4734986986d234d04b7425a8b69fdc8b3
|
File details
Details for the file ccpm_scheduler-0.4.0-py3-none-any.whl.
File metadata
- Download URL: ccpm_scheduler-0.4.0-py3-none-any.whl
- Upload date:
- Size: 42.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebc13283b4913a7f59c8a2d5ef768ceaefec4ae1fa1abcd04daeb0c1de7f6043
|
|
| MD5 |
b70cabfa0494c5a9b5f0c66dda5e4f64
|
|
| BLAKE2b-256 |
535bd7fcacf11d7b1728dc7adf739d42aad94857f89c7916ecc5843ac1a578bd
|