Scaffolded projects are runtime apps, not Python packages¶
Decision date: 2026-06-04 (after v7.18.2 scaffolder audit)
Closes: .claude/docs/2026-06-03-v7.17-scaffolder-distributable-package-design.md (8 open questions)
Architect verdict: memory entry from agent abac9907719d964f5, 2026-06-04
Decision¶
symfonic init generates a runtime application, not an installable Python package. The scaffolder ships:
Dockerfiledocker-compose.ymlMakefilealembic.ini+alembic/env.pyapp/main.py(FastAPI entry point)webapp/(templates, static assets, CSS)requirements.txt(pinned viasymfonic-core[…]>=X,<Y)
None of these belong inside a pip install-able wheel. The scaffolder will NOT ship pyproject.toml.j2, NOT auto-generate a setup.py, and NOT add a [project] table to any of the generated files.
Why¶
When the design question was raised (2026-06-03, after a v7.16.1 hotfix where the CI's pip install -e . against a generated project failed), the surface seemed open. The v7.18.2 audit closed it on three observations:
- The scaffold artifact is a runtime app at every layer. Dockerfile, compose file, Alembic config, webapp assets, and a FastAPI entry point are not "Python package" concerns. Wrapping them in a wheel would be a category error.
- The friction that prompted the question was a CI bug, not an adopter need. The v7.16.1 hotfix replaced
pip install -e .withpip install -r requirements.txtinscaffold-smoke.yml. Adopters never had an installation problem — the smoke workflow had a wrong assumption. - No adopter has requested
pip install <generated-app>distributability. A production adopter team (at scale) and the SRE-starter pilot both treat generated projects as Docker / Compose-managed services, not as packages.
Shipping pyproject.toml.j2 would invite design churn — eight open questions covering package name, version scheme, dependency source, build backend, optional-deps groups, console scripts, Python pin, and distribution intent — for a path nobody travels.
What this means for adopters¶
- You install dependencies via
pip install -r requirements.txt(ordocker compose up --build). That is the documented path. It is unchanged. - You ship by building a container from the provided
Dockerfile, not by uploading a wheel. - Editable installs do not apply. If you want to develop the agent code itself, edit files in place — Uvicorn
--reloadand the Celery beat scheduler pick up changes withoutpip install -e .. - CI testing patterns: the project root contains the application code; tests can
cdinto the project and runpytestdirectly. There is no install step before testing the generated app.
What this means for symfonic-core itself¶
symfonic-core (this package) IS installable — it ships pyproject.toml, a wheel, and publishes to a PyPI registry. The decision above applies ONLY to projects scaffolded BY symfonic init.
The boundary is sharp:
| Layer | Installable? | Build artifact |
|---|---|---|
symfonic-core library |
Yes (pip install symfonic-core) |
Wheel + sdist on PyPI |
symfonic init <project> output |
No | Docker image from Dockerfile |
Closed questions from the v7.17 design doc¶
All eight open questions at .claude/docs/2026-06-03-v7.17-scaffolder-distributable-package-design.md are retired:
- Package name — N/A
- Version scheme — N/A
- Dependencies source —
requirements.txt, nopyproject.toml - Build backend — N/A (no wheel build)
- Optional-deps groups — N/A (use
requirements.txtcomments to gate components) - Console scripts — N/A (use
uvicorn/celery/maketargets) - Python pin — declared in
Dockerfile(FROM python:X.Y-slim) - Distribution intent — Docker image only, never a wheel
Related decisions¶
requirements.txt.j2pin tightening (v7.19+ backlog) — even though we close the package question, the pin range on the generatedrequirements.txtline still needs to lift from>=7.1,<8.0to the current scaffolder's own version floor. See.agent/team/plans/2026-06-04-v7.19-scaffolder-evolution-backlog.md.pre_conditionsDSL surfacing in scaffolded code (v7.19+ backlog) — the v7.18.0 state-predicate DSL is invisible in scaffoldedapp/setup/agent.py. Same backlog file.
These are scaffolder evolution work, NOT a return to the distributable-package question.