Skip to main content

Shipping

The architecture, with the modules, the flow between them, and two sibling roots with opposite invariants.

This page maps the codebase for someone about to change it: the modules, what each one is responsible for, and the path a single invocation takes through them. It also covers the two sibling content roots and why their invariants are opposites, because most of the surprising rules in this repository descend from that split.

The module map

Everything lives under src/overpower/, flat. There is no package within a package, because the project is single-context.

ls src/overpower/*.py | wc -l
ModuleResponsibility
cli.pythe command line, parsing, the isatty() gate, the exit codes
discovery.pythe tree is the catalog, and list discovers artifacts by walking it
packaged.pywhere the two sibling roots live inside the package
scope.pywhether cwd is inside a git repository
wizard.pythe interactive wizard, and one Request out
remote.py--from, with any GitHub repository as a search root
planning.pyRequest → Plan, the one place a destination is decided
writing.pythe one write boundary, which executes the plan and reads nothing else
written.pythe only file overpower writes about its own content
inspection.pywhat is on the disk of the target, and what is wrong with it
screens.pywhat the product draws to the terminal
recipes.pyTOML in, a Recipe out
rendering.py(Recipe, document) → the grafts to make, a pure function over values
grafting.pysurgical insertion into a document that is not overpower's
runtimes.pythe runtime path table
jsonio.pythe sanctioned way to reach the standard library's JSON reader
yamlio.pythe sanctioned way to reach the YAML reader, and the catalog's door
errors.pythe product's exception root, with the two subclasses that separate 2 from 3

The flow of one invocation

cli.py parses the line and, in a terminal with a line that does not add up to a full request, hands the gaps to wizard.py, in the order artifacts, scope, runtimes, confirmation, because a later step can depend on an earlier one's answer. Either way, what comes out is the same Request.

For the embedded catalog, discovery.py and packaged.py answer what exists by walking content/. For --from, remote.py answers the same question by obtaining a copy of a foreign repository. planning.py turns the Request into a Plan, and every write passes through the single boundary in writing.py.

uvx overpower@latest install --skill panlabs-python-standards --runtime claude-code --dry-run

Two sibling roots, opposite invariants

Inside the package sit two content roots, siblings, and their invariants are opposites.

src/overpower/content/ carries the vendored trees, the pool of individually curated artifacts and the AI Frameworks. It must land 100%: every file tracked here has to reach the wheel byte-identical, because this is copied content, never generated, and a partial landing is a corrupted artifact nobody would notice at the point it happened.

src/overpower/catalog/ is the opposite: a single file, catalog.yaml, that carries only what the tree cannot know on its own, the bundle definitions, which have no directory of their own by construction, and one description line per AI Framework, which has no SKILL.md to read a description from.

Nothing that a directory walk could answer lives there. A field that duplicated a path the filesystem already knows would be a second source of truth for a fact that has only one.

Three gates in CI guard exactly the first. P1 confirms nothing under content/ is hidden from git, and refuses even the case where git tracks nothing there, so a gate with no subject never passes as green. P2 confirms the wheel carries the same set the git tree carries. P3 confirms the sdist carries exactly what it declared. The second root has no dedicated gate, because losing it fails loudly rather than quietly: a bundle vanishes from list, and install answers that it does not know the name. What fails loudly does not need a gate; what fails silently is what the three gates exist to catch.