chore: bootstrap repo (pyproject, uv lockfile, Python 3.14, MIT license)#29
Conversation
Establishes the minimum project metadata so subsequent harness tickets have a foundation to land against. - pyproject.toml: name harness-python-react, version 0.1.0, requires-python = ">=3.14", license = "MIT" (PEP 639), seed deps fastapi + pydantic v2. [tool.uv] package = false because src/ does not ship until #17 — this is an application, not a library. - uv.lock: resolved against CPython 3.14.3 (10 transitive deps). - LICENSE: MIT, copyright 2026 Constantinos Koutsakis. - README.md: 2-sentence stub linking to the issue tracker and project board; full README ships in #26. Refs #1
constk
left a comment
There was a problem hiding this comment.
Review — PR #29: bootstrap repo (v0.1.0)
Manual gates (CI doesn't exist yet, per #9 deferral). Verified the four files on the branch:
pyproject.toml— clean PEP 639 license format,[tool.uv] package = false, two seed deps with reasonable floors.LICENSE— MIT, copyright 2026, your name. Standard.README.md— 2-sentence stub linking issues + project board. Honest about status.uv.lock— 11 packages (10 transitive + the project itself), resolved against CPython 3.14.
.gitignore exists (~4.6 KB GitHub Python template) — checked it still has the unanchored lib/, build/, dist/, eggs/, sdist/, parts/, var/, wheels/ patterns that bit the previous project. You called this out as deferred to #5 with feedback_gitignore_anchor_lib cited. Good explicit deferral.
Discipline carrying over from the previous project — caught and named
You front-loaded everything I'd have flagged:
| Concern | Status | Owner |
|---|---|---|
No [build-system] block |
Defensible because [tool.uv] package = false; src/ doesn't exist yet |
#17 |
.gitignore unanchored patterns |
Documented, deliberately deferred | #5 |
| No CI gates | Acknowledged; manual smoke is what we have | #9 |
Refs #1 not Closes #1 |
QA-column workflow preserved (Backlog → In Progress → QA → Done) | manual |
| Version 0.1.0 baseline | Matches the previous project's bootstrap | versioning memory |
| Pydantic resolution path | uv lock --upgrade-package pydantic for future bumps |
discipline |
That's six explicit deferrals with named owners. Exactly the framing the previous project's harness rollout established — "declare the gap, file the ticket, don't pretend it's not there."
Substantive observations on what landed
1. requires-python = ">=3.14" is the most consequential choice. Python 3.14 shipped Oct 2025; actions/setup-python@v5 supports it, uv handles it natively, and you get the full PEP 695 generics + 3.13/3.14 typing refinements. The previous project was on 3.12. The trade-off is deployment surface: anywhere that doesn't have 3.14 available yet (older Debian repos, niche cloud runtimes) needs the system Python upgraded. For a greenfield template-style project starting in 2026, defensible — and reversible if a deployment target later forces 3.12 by lowering the floor in pyproject.toml. Worth being conscious you've made the call now rather than discovering it at #17 / #18 when scaffolding ships.
2. PEP 639 license format (license = "MIT" SPDX expression + license-files = ["LICENSE"]) — the new format from 2024. Older setuptools (< 77) would warn; uv + hatchling support it cleanly. Right call for a greenfield 2026 project — locks in forward-compatibility before any tool starts deprecating the legacy license = {text = "MIT"} form.
3. [tool.uv] package = false — declares this is an application, not a library. Suppresses uv's wheel-build path, which is what removes the need for [build-system] while still letting uv sync do its venv work. This is the right pattern for an "app, deployed as a process" use case (FastAPI server) versus "library, distributed via PyPI."
4. Seed dep floors:
fastapi>=0.115.0— same floor as the previous project.pydantic>=2.11.0— same floor as the previous project.
Both reasonable: 0.115 brought stable streaming improvements; 2.11 stabilised the strict-mode + discriminated-union behaviour you'll want for the contract layer (per feedback_otel_semconv / the StrictModel pattern from the previous project's #56). Consistent with what worked before.
5. uv.lock — 11 packages, no surprises. annotated-doc 0.0.4 is the only entry I didn't recognise — it's a recent split-off in pydantic's transitive tree. Real package, real resolution; not a typo or hijack. Trust uv.
Two minor cosmetic notes (judgment, not blocking)
Homepage and Repository URLs in [project.urls] are identical. PyPI displays them as separate links in the sidebar, so it's not wrong, but the convention is:
Homepage= the project landing page (could be a docs site).Repository= the git clone URL (e.g.https://github.com/constk/harness-python-react.git).
Right now both point at https://github.com/constk/harness-python-react. Minor — would matter if/when this hits PyPI, which package = false says it won't. Take it or leave it.
description reads more like a README tagline than a typical setuptools description. "Production-quality LLM-driven coding harness — Python (FastAPI) backend, Vite + React + TypeScript frontend." That's fine — there's no hard length limit, and PyPI's "doesn't apply" guard rails are off because of package = false. Worth knowing that if you ever flip package = true, the description shows up at the top of the PyPI page where punchier-than-formal descriptions read better than this one does.
Verdict
LGTM — good to merge. gh pr merge 29 --admin --squash per project_solo_owner_admin_merge. Move #1 from In Progress → QA on the project board, then Done after merge.
After merge:
develophas its first commit beyond the GitHub-initial state; baseline established.- The next PR (#2 per your note) builds on this. The discipline pattern from the previous project is already in place — explicit deferral with ticket owner — so I'd expect each subsequent bootstrap PR to be similarly tight.
- One thing worth flagging about the harness-as-baseline framing: this PR is what the whole harness gets built on top of. Anything that survives the bootstrap (Python version, license format, lockfile shape, app-not-library posture) is going to be load-bearing for #2-#28. The choices you've made are conservative and defensible; just naming that the foundation matters more than a follow-on PR's choices would.
A clean restart. The "explicit deferral with owner" pattern is the bit of muscle memory that survived from the previous project — that's worth more than anything in the four files.
Summary
pyproject.tomlwith project metadata,requires-python = ">=3.14", MIT license (PEP 639 SPDX expression), and seed depsfastapi+pydanticv2.[tool.uv] package = falsebecausesrc/does not ship until feat: backend scaffold (FastAPI app, /api/v1/health, /api/v1/echo, sessions) #17 — this is an application, not a library.uv.lockagainst CPython 3.14.3 (10 transitive deps resolved).LICENSE(MIT, copyright 2026 Constantinos Koutsakis).README.mdwith a 2-sentence stub linking to the issue tracker and project board; the full README ships in docs: README, CONTRIBUTING, CLAUDE.md, CHANGELOG seed, TASKS.md #26.Acceptance criteria (from #1)
pyproject.tomlpresent; project nameharness-python-react;requires-python = ">=3.14".uv.lockcommitted;uv syncsucceeds on Python 3.14.LICENSE(MIT) at repo root, copyright holder filled in.README.mddescribes the project in 2-3 sentences.developand merged. (this PR — pending merge)Test plan
uv lockresolves cleanly on Python 3.14.3.uv syncsucceeds and creates.venv.uv run python -c "import fastapi, pydantic"succeeds (fastapi==0.136.1,pydantic==2.13.3).Notes for reviewer
[build-system]/[tool.hatch]block intentionally: withpackage = false, uv skips the build step. Hatchling can be added in feat: backend scaffold (FastAPI app, /api/v1/health, /api/v1/echo, sessions) #17 whensrc/exists if we want wheel builds..gitignoreis the GitHub Python template (unanchoredlib/,build/,dist/) — known issue perfeedback_gitignore_anchor_lib. Deliberately not fixed here; ticket chore: .gitignore, .editorconfig, .dockerignore #5 owns that change..editorconfiglands in chore: .gitignore, .editorconfig, .dockerignore #5.Refs #1notCloses #1so the issue stays open until the QA → Done flow on the project board moves it.Refs #1