Repository navigation
ChartworkAI 0.1.0
First release of the Python package. The framework's Markdown contracts remain at 1.0.0
and are versioned separately (DEC-008).
While the package is 0.x the CLI surface, the
--jsonreport schema and the MCP tool
names may change in a minor release.
Added
- ChartworkAI Python package and CLI. The framework ships as an installable package
(pip install chartworkai) exposingchartworkai check [PATH]— the compliance linter, which exits
0 on pass and 1 on failures. Supports--jsonfor machine-readable output and--strict.
Zero runtime dependencies, so it never imposes a dependency tree on the repository it audits. chartworkai init— scaffolds a project's governance layer from a plain
pip install, with no clone of this repository. The templates, agent specs, prompts and
extensions ship inside the wheel. Output is byte-identical to the shell bootstrap, and CI
diffs the two on every change.chartworkai plan— regeneratesdocs/phase_plan.mdfrom repository state (tasks,
decisions, roster, status), carrying over the sections a human owns.- MCP server —
chartworkai mcpspeaks the Model Context Protocol over stdio, so any
assistant can callchartworkai_check,chartworkai_state,chartworkai_file_decision, and
chartworkai_file_handoffnatively. Implemented with the standard library alone to keep
the zero-dependency promise. chartworkai state— prints where a project stands (phase, tasks, blockers, recent
decisions and handoffs) as JSON.LICENSE— Apache License 2.0, with aNOTICEfile. Chosen over MIT for its
express patent grant and explicit trademark reservation, which suit the open-core
boundary (DEC-006).SECURITY.md— supported versions, private vulnerability reporting through GitHub Security
Advisories, and an honest security model covering the local-file/local-shell surface, the
no-network / no-telemetry / no-credentials core, and the optional extensions that talk to
third-party trackers.CONTRIBUTING.md— dev setup, the self-check every PR must keep passing, the decision-record
convention, and code style for POSIXshand Python.py.typed(PEP 561), so downstream type-checkers use the package's annotations.- Specs for the four remaining profiles —
database,competition-ml,investigation
anddeployed-serviceeach now document their required artifacts, verify contract,
default roles, layout and the real implementations they are drawn from. All six are
first-class; nothing is advertised as "planned" any more.framework.jsoncarries the
full definition for each and is cross-checked against the checker by test. - CI now gates the distributables: builds the sdist and wheel, runs
twine check, fails
if local artifacts leak into the sdist, installs from the sdist into a clean environment
and scaffolds outside the repository, and asserts thatinitrejects unknown profiles and
refuses to clobber.ruff format --checkwas added alongsideruff check.
Fixed
Findings from three pre-release audits (DEC-009). The theme is that a governance tool
must never state something false:
- The release process contradicted itself. The runbook created the production tag
before its "TestPyPI first" gate, while project state still described a manual token
upload after the implementation had moved to OIDC. DEC-010 now records the publishing
authority, TestPyPI must succeed againstmainbefore tagging, and the living
documents report the actual release state.
Filesystem-safety and privacy findings from a fourth audit, all reproduced before fixing:
-
The shell bootstrap was still destructive. The Python
inithad been hardened
and the shell script had not, while the two were advertised as equivalent. It now
refuses to overwrite an existing governance layer without--forceand rejects
unknown profiles, exactly as the Python entry point does. -
The overwrite guard was too narrow. It protected five documents; a curated
decision index, domain note, style guide or data contract could still be replaced
silently, and_framework_*directories were deleted outright. All of them are
protected now. -
Writes could escape the project through a symlink.
chartworkai planwould
follow a symlinkeddocs/phase_plan.mdand overwrite a file outside the
repository. Every write now refuses a symlinked target or a path resolving outside
the project root. -
A typo in the charter could weaken compliance. An unrecognised
Profile:value
was treated as non-data, sodata-sciecesilently dropped the data-contract
requirement. An unknown profile is now read the strictest way and reported as a
failure, in both implementations. -
MCP tools accepted any path on the filesystem. A tool argument is chosen by a
model acting on text it did not author. Paths are now confined to the server's
workspace, withCHARTWORKAI_ALLOW_ANY_PATH=1as a deliberate opt-out. -
initrefused nothing. Re-running it — or pointing it at the wrong directory —
silently rewrote the charter, status and tasks, discarding real work. It now refuses
when canonical documents already exist and requires--forceto overwrite. Adding
ChartworkAI to an existing repository still works; only the canonical documents are
protected. -
Unknown profiles were accepted.
--profile typowas taken at face value and
silently treated as non-data, handing the project the wrong governance contract. The
value is now validated against the six known profiles. -
chartworkai statereturned success for a directory that was not a project,
emitting a plausible-looking report. It now fails with a clear message — an agent
reading that over MCP would otherwise take it as truth. -
The MCP server echoed back any
protocolVersiona client sent, claiming
conformance to revisions it does not implement. It now negotiates down to a version it
actually supports. -
The
--jsonpathfield used backslashes on Windows, so a consumer matching on
docs/phase_plan.mdsilently missed on that platform. Paths are now always POSIX-style. -
initon a file path raised a bareNotADirectoryErrortraceback. All CLI entry
points now fail with a message and exit 1. -
The version was hard-coded in three places, one of which is published in
--json; it
is now derived from the installed distribution, leavingpyproject.tomlas the only
place a release number is written. -
The bootstrap named its seed decision
YYYYMMDD_charter_v1.md, which does not match the
YYYYMMDD_<NS>###_<title>.mdpattern the checker enforces — so every freshly scaffolded
project failed its own decision-naming check on a file the bootstrapper had just written.
It is nowYYYYMMDD_DEC001_charter_v1.mdin both implementations. -
Newly generated projects no longer refer to the tool by its former name.