Repository Scripts¶
Python 3.11+ command-line utilities that validate repository structure and
create new ventures/products from templates. All scripts use only the Python
standard library — no external dependencies are required to run them,
except the gimp_*.py brand-asset tools below, which are the one
deliberate exception (see Brand-asset tools).
Validation scripts¶
Run all of them at once with:
python scripts/check.py
| Script | Purpose |
|---|---|
check.py |
Runs every validator below in a predictable order; nonzero exit on any failure. |
validate_repository.py |
Checks required root files, directories, entry points, templates, ADRs, and scans for filler text or duplicate IDs. |
validate_links.py |
Checks relative Markdown links resolve to real files/directories. |
validate_metadata.py |
Checks YAML front matter on authoritative Markdown documents against the metadata standard. |
validate_registries.py |
Checks JSON syntax and required fields in portfolio/*.json and venture/product/component JSON records. |
Creation scripts¶
| Script | Purpose |
|---|---|
create_venture.py |
Scaffolds a new venture from ventures/_template/. |
create_product.py |
Retired 2026-07-27 (see ADR-0017) — its template source, ventures/<slug>/products/_template/, no longer exists in any venture. Kept for its test coverage/history, not for use; a product is now created entirely in its venture's implementation repository. |
create_implementation_repository.py |
Scaffolds a new venture implementation repository from templates/implementation-repository/, per ADR-0014. Writes outside this repository; does not run git init or create a remote. |
All three refuse to overwrite existing paths, reject unsafe slugs, and only
update a registry file when explicitly asked with a flag. Run any of them
with --help for full usage.
Brand-asset tools¶
| Script | Purpose |
|---|---|
_gimp_common.py |
Shared helper: locates a gimp-console executable and runs a Python-Fu script in headless GIMP 3, returning its stdout. Not a CLI itself. |
gimp_trace_mark.py |
Crops a region of a raster image, selects a color, and traces it to a vector-path SVG (plug-in-sel2path). |
gimp_render_svg.py |
Rasterizes an SVG to a transparent PNG at a given width/height, via GIMP's librsvg-backed SVG loader. |
gimp_compose_badge.py |
Composites a mark SVG onto a solid-color rectangle (e.g. a favicon-style navy square with a centered white mark). |
Run any of them with --help for full usage. All three formalize the ad hoc
GIMP batch scripting used to produce Devonshire Digital LLC's candidate "D"
mark (see docs/company/brand-assets.md and the corresponding entry under
work/), so the same steps can be re-run for future brand assets (e.g.
Devonside Labs') without re-deriving the GIMP 3 Python API from scratch.
Dependency note (per
../docs/standards/dependency-and-tooling-standard.md):
these three scripts require GIMP 3 to be installed locally (they shell
out to gimp-console; no Python package is added). This is a minor,
easily-reversible tooling dependency — scoped to brand-asset production,
not to validation or scaffolding — so it's justified here rather than via a
separate ADR. _gimp_common.find_gimp_console() checks the GIMP_CONSOLE
environment variable, then PATH, then common Windows install locations;
set GIMP_CONSOLE explicitly if GIMP is installed somewhere nonstandard.
GIMP 3's gimp-console does not reliably self-terminate after a batch
script finishes (observed on Windows even without the -i interactive flag
and with stdin closed). _gimp_common.run_gimp_python() works around this
by streaming output for a completion sentinel and then killing the process
itself, rather than waiting for it to exit on its own — do not replace this
with a plain subprocess.run(...) call, which would block for the full
timeout on every invocation.
gimp_compose_badge.py's default centering only works for a square (1:1)
mark SVG. Its no-args default requests a square --mark-size (60% of
canvas height, both dimensions equal) and centers assuming that full square
gets filled. For a non-square mark (e.g. b3-mark-white.svg's 885:758
viewBox), GIMP's keep-ratio loader letterboxes the actual content inside
that square — the rendered ink ends up smaller than requested and
off-center (observed: top-anchored, leaving a big gap at the bottom) —
which is exactly the "too small and shifted north" defect found and fixed
in the B3 badge (see ventures/digital-products/docs/brand-assets.md's
2026-07-17 entry). For any non-square mark, don't rely on the defaults:
render the mark once at a size where width/height are left to
auto-match its true aspect (e.g. via gimp_render_svg.py --height N),
measure that PNG's transparent-pixel bounding box to get the content's
real margin fractions within its own render box, then solve for an
explicit --mark-size/--offset pair that lands the rendered ink (not
the nominal box) centered on the target canvas.
Finding GIMP/Inkscape on this machine: neither installer adds itself to
PATH, so where gimp, where inkscape, or shutil.which(...) will
report nothing even when both are installed — that is not evidence they're
missing. Confirm the real state by running python scripts/_gimp_common.py
directly (it prints the resolved gimp-console path and GIMP's version) or
by checking the paths below, before concluding a render step needs to be
skipped:
- GIMP 3.2:
C:\Program Files\GIMP 3\bin\gimp-console-3.2.exe(this is exactly_gimp_common._CANDIDATE_WINDOWS_GLOBS[0], sofind_gimp_console()resolves it with no extra configuration). - Inkscape:
C:\Program Files\Inkscape\bin\inkscape.exe. No script here drives Inkscape (it's the Founder's interactive editor of choice for master/export SVGs); its path is noted here only so a future automation need doesn't start from "is it even installed?".
Conventions¶
- Exit code
0means success; any nonzero exit code means at least one check failed.check.pyprints a summary of which validator failed. - Scripts avoid network access and avoid mutating files outside the paths the user explicitly requested.
- See
../tests/README.mdfor how these scripts are tested.