From d2c4f5b0a862935f04311dc8b686bc85151fec91 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:37:19 -0500 Subject: [PATCH 01/55] chore(beads): create epic for omnix template substitution and CI workflow gaps --- .beads/issues.jsonl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 2a6f405..99499c9 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -2,6 +2,12 @@ {"id":"pnt-3bd","title":"Add crane.inputs.nixpkgs.follows and align cache declarations with vanixiets","description":"Two related flake hygiene items:\n\n1. crane input has no follows directive, causing a redundant independent nixpkgs evaluation. Since crane is a build library with no upstream cache, adding inputs.nixpkgs.follows = nixpkgs eliminates the extra eval with no cache downside.\n\n2. Cache declarations are minimal (3 substituters) compared to vanixiets (9). Add cache.nixos.org explicitly, numtide.cachix.org, and cameronraysmith.cachix.org to nixConfig.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:33.582737-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:49.646325-05:00","closed_at":"2026-02-03T18:04:49.646325-05:00","close_reason":"Implemented in e3a9997, added crane/numtide/cache.nixos.org caches","dependencies":[{"issue_id":"pnt-3bd","depends_on_id":"pnt-h2q","type":"related","created_at":"2026-02-03T15:48:44.907425-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3jf","title":"Validate sciexp/data platform instantiation","description":"Final validation gate before v0.2.0 release. Instantiate template to create the sciexp data platform repository.\n\nTarget: ~/projects/sciexp/data\n\nValidation steps:\n- Instantiate template with configuration for omicsio, scilake, scimesh package structure\n- Verify independent locks work for each package\n- Verify Nix builds succeed for all packages\n- Verify CI patterns work correctly\n- Document any issues found and fix if minor, or create follow-up issues if significant\n\nThis issue is blocked by the other four polish issues. Successful completion means we are ready to manually create the v0.2.0 release tag.\n\nReference: ~/projects/sciexp/planning/contexts/sciexp-data-platform.md for sciexp/data requirements\n\nScope: ~3 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:48:01.905707-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:14:16.459237-05:00","closed_at":"2026-02-05T15:14:16.459237-05:00","close_reason":"Validated: template evaluation, test infrastructure (11/11 tests pass across 3 packages), and instantiation workflow confirmed working. Welcome text and README are consistent. 619014b","dependencies":[{"issue_id":"pnt-3jf","depends_on_id":"pnt-6yk","type":"blocks","created_at":"2026-02-05T13:48:10.890329-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-5wx","type":"blocks","created_at":"2026-02-05T13:48:11.058701-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-m7j","type":"blocks","created_at":"2026-02-05T13:48:11.23594-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-bxq","type":"blocks","created_at":"2026-02-05T13:48:11.38108-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:36:48.63246-05:00"} +{"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:02.791847-05:00","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:03.823132-05:00","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:04.89314-05:00","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:07.237944-05:00","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:08.32939-05:00","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} {"id":"pnt-4jg.1","title":"Remove uv workspace, adopt path dependencies","description":"Remove [tool.uv.workspace] from root pyproject.toml. Each package gets own pyproject.toml with [tool.uv.sources] for sibling references using path sources with editable=true. Follow langchain pattern.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:07.344057-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T14:40:02.175394-05:00","closed_at":"2026-02-02T14:40:02.175394-05:00","close_reason":"Implemented in a8a823f. Removed root uv workspace, generated per-package locks, rewrote nix modules to Pattern 3 per-package loading.","dependencies":[{"issue_id":"pnt-4jg.1","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:07.344659-05:00","created_by":"Cameron Smith"}],"comments":[{"id":1,"issue_id":"pnt-4jg.1","author":"Cameron Smith","text":"Post-close fixup commits (774ec26):\n- fix(ci): update lock file references for per-package federation (d0cab2a)\n- fixup! merge federated workspace deps: replace // with zipAttrsWith for extras-safe dep merging (7b3e7ae)\n- fixup! load packages independently: document version-conflict invariant in python.nix and architecture doc (36eb8a7, 774ec26)\n\nReview findings addressed: stale CI cache-dependency-glob paths, fragile shallow-merge dep specs, undocumented overlay composition invariant. Full CI redesign (nix develop + justfile symmetry) deferred to pnt-dre.4.","created_at":"2026-02-02T20:17:00Z"}]} {"id":"pnt-4jg.2","title":"Configure pixi feature-based composition","description":"Implement pixi feature/environment pattern: [feature.X.dependencies] + [environments] composition. Single pixi.lock covering all environments. Per-feature task definitions. Target-specific dependencies for platform support.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:08.085592-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:36:49.459815-05:00","closed_at":"2026-02-02T15:36:49.459815-05:00","close_reason":"Verified pixi feature composition via nix develop -c just \u003crecipe\u003e. Fixed: added missing feature tasks to python-nix-template, delegated justfile conda recipes to pixi task names for correct working directory, moved deprecated build channels to backend.channels.","dependencies":[{"issue_id":"pnt-4jg.2","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:08.086155-05:00","created_by":"Cameron Smith"}]} From 7b6d9533e34bd6c963e589c791fc97b9d59f561e Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:50:36 -0500 Subject: [PATCH 02/55] chore(beads): mark pnt-3zn epic in_progress --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 99499c9..38bf18c 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -2,7 +2,7 @@ {"id":"pnt-3bd","title":"Add crane.inputs.nixpkgs.follows and align cache declarations with vanixiets","description":"Two related flake hygiene items:\n\n1. crane input has no follows directive, causing a redundant independent nixpkgs evaluation. Since crane is a build library with no upstream cache, adding inputs.nixpkgs.follows = nixpkgs eliminates the extra eval with no cache downside.\n\n2. Cache declarations are minimal (3 substituters) compared to vanixiets (9). Add cache.nixos.org explicitly, numtide.cachix.org, and cameronraysmith.cachix.org to nixConfig.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:33.582737-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:49.646325-05:00","closed_at":"2026-02-03T18:04:49.646325-05:00","close_reason":"Implemented in e3a9997, added crane/numtide/cache.nixos.org caches","dependencies":[{"issue_id":"pnt-3bd","depends_on_id":"pnt-h2q","type":"related","created_at":"2026-02-03T15:48:44.907425-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3jf","title":"Validate sciexp/data platform instantiation","description":"Final validation gate before v0.2.0 release. Instantiate template to create the sciexp data platform repository.\n\nTarget: ~/projects/sciexp/data\n\nValidation steps:\n- Instantiate template with configuration for omicsio, scilake, scimesh package structure\n- Verify independent locks work for each package\n- Verify Nix builds succeed for all packages\n- Verify CI patterns work correctly\n- Document any issues found and fix if minor, or create follow-up issues if significant\n\nThis issue is blocked by the other four polish issues. Successful completion means we are ready to manually create the v0.2.0 release tag.\n\nReference: ~/projects/sciexp/planning/contexts/sciexp-data-platform.md for sciexp/data requirements\n\nScope: ~3 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:48:01.905707-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:14:16.459237-05:00","closed_at":"2026-02-05T15:14:16.459237-05:00","close_reason":"Validated: template evaluation, test infrastructure (11/11 tests pass across 3 packages), and instantiation workflow confirmed working. Welcome text and README are consistent. 619014b","dependencies":[{"issue_id":"pnt-3jf","depends_on_id":"pnt-6yk","type":"blocks","created_at":"2026-02-05T13:48:10.890329-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-5wx","type":"blocks","created_at":"2026-02-05T13:48:11.058701-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-m7j","type":"blocks","created_at":"2026-02-05T13:48:11.23594-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-bxq","type":"blocks","created_at":"2026-02-05T13:48:11.38108-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:36:48.63246-05:00"} +{"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:50:30.680871-05:00"} {"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:02.791847-05:00","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:03.823132-05:00","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:04.89314-05:00","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} From f5bf4a403aefeb17d0261f7ff981b06809c890b9 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:51:32 -0500 Subject: [PATCH 03/55] feat(template): add camelCase omnix parameter for Nix variable names --- modules/template.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/template.nix b/modules/template.nix index 012ee43..06df889 100644 --- a/modules/template.nix +++ b/modules/template.nix @@ -92,6 +92,11 @@ description = "Name of the Python package (snake_case)"; placeholder = "python_nix_template"; } + { + name = "package-name-camel-case"; + description = "Name of the Python package (camelCase)"; + placeholder = "pythonNixTemplate"; + } { name = "monorepo-package"; description = "Include the functional programming monorepo package in the project"; From 64d6b4c205bb58da6767096d64ae145e7e52d073 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:53:24 -0500 Subject: [PATCH 04/55] fix(docs): replace Jinja placeholders with omnix literals in index.qmd --- docs/index.qmd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/index.qmd b/docs/index.qmd index fa3b0dd..6b9d127 100644 --- a/docs/index.qmd +++ b/docs/index.qmd @@ -1,14 +1,14 @@ --- -title: "{{package-name-kebab-case}}" -description: "{{project-description}}" +title: "python-nix-template" +description: "A Python project template for Nix using uv2nix and flake-parts" format: html: toc: false --- -# {{package-name-kebab-case}} +# python-nix-template -{{project-description}} +A Python project template for Nix using uv2nix and flake-parts ## Quick Start @@ -23,6 +23,6 @@ format: ## Links -- [GitHub Repository](https://github.com/{{git-org}}/{{package-name-kebab-case}}) +- [GitHub Repository](https://github.com/sciexp/python-nix-template) - [Installation Guide](guides/installation.qmd) - [API Reference](reference/index.qmd) \ No newline at end of file From ff102740d2162a4fd1947d0b735992e11ec45de0 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:53:40 -0500 Subject: [PATCH 05/55] fix(docs): replace Jinja placeholders with omnix literals in _quarto.yml --- docs/_quarto.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/_quarto.yml b/docs/_quarto.yml index 145d0ac..94d2b4a 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -39,9 +39,9 @@ interlinks: url: https://numpy.org/doc/stable/ website: - title: "{{package-name-kebab-case}}" - description: "{{project-description}}" - site-url: "https://{{git-org}}.github.io/{{package-name-kebab-case}}" + title: "python-nix-template" + description: "A Python project template for Nix using uv2nix and flake-parts" + site-url: "https://sciexp.github.io/python-nix-template" back-to-top-navigation: false page-navigation: true @@ -50,7 +50,7 @@ website: left: "" right: - icon: github - href: https://github.com/{{git-org}}/{{package-name-kebab-case}} + href: https://github.com/sciexp/python-nix-template search: type: overlay @@ -59,7 +59,7 @@ website: background: primary tools: - icon: github - href: https://github.com/{{git-org}}/{{package-name-kebab-case}} + href: https://github.com/sciexp/python-nix-template left: - sidebar:tutorials - sidebar:guides @@ -124,7 +124,7 @@ quartodoc: sections: - title: API Reference desc: | - API reference for {{package-name-kebab-case}}. + API reference for python-nix-template. contents: - name: main children: embedded From 7bb033612e729dbf826f6224e0ff41615a98bc45 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:53:48 -0500 Subject: [PATCH 06/55] fix(docs): replace Jinja placeholder with omnix literal in about/index.qmd --- docs/about/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/about/index.qmd b/docs/about/index.qmd index 47b6037..47499cd 100644 --- a/docs/about/index.qmd +++ b/docs/about/index.qmd @@ -15,4 +15,4 @@ csl: ../bibstyle.csl # Introduction {#sec-introduction} -This section provides background information for the {{package-name-kebab-case}} project. +This section provides background information for the python-nix-template project. From 33050fb5820ccb3bbbf87a50a722894cc5585daa Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:53:56 -0500 Subject: [PATCH 07/55] fix(docs): replace Jinja placeholder with omnix literal in concepts/index.qmd --- docs/concepts/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/index.qmd b/docs/concepts/index.qmd index 152f4fe..2827796 100644 --- a/docs/concepts/index.qmd +++ b/docs/concepts/index.qmd @@ -15,4 +15,4 @@ csl: ../bibstyle.csl # Introduction {#sec-introduction} -This section provides an overview of the concepts and terminology used in the {{package-name-kebab-case}} project. +This section provides an overview of the concepts and terminology used in the python-nix-template project. From 8196c28adf3e2caa5dcce064d73889b0352bed19 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:03 -0500 Subject: [PATCH 08/55] fix(docs): replace Jinja placeholders with omnix literals in getting-started.qmd --- docs/tutorials/getting-started.qmd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/getting-started.qmd b/docs/tutorials/getting-started.qmd index 94fb73e..e468dc2 100644 --- a/docs/tutorials/getting-started.qmd +++ b/docs/tutorials/getting-started.qmd @@ -1,11 +1,11 @@ --- title: "Getting Started" -description: "Quick tutorial to get up and running with {{package-name-kebab-case}}" +description: "Quick tutorial to get up and running with python-nix-template" --- -# Getting Started with {{package-name-kebab-case}} +# Getting Started with python-nix-template -This tutorial will walk you through the basic usage of {{package-name-kebab-case}}. +This tutorial will walk you through the basic usage of python-nix-template. ## Prerequisites @@ -23,7 +23,7 @@ See the [Installation Guide](../guides/installation.qmd) for detailed installati ```python # Example usage will be added here -print("Hello from {{package-name-kebab-case}}!") +print("Hello from python-nix-template!") ``` ## Next Steps From 6b8d90966ae79b1c02e193a2dcdf90829c53266d Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:14 -0500 Subject: [PATCH 09/55] fix(docs): replace Jinja placeholders with omnix literals in installation.qmd --- docs/guides/installation.qmd | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/guides/installation.qmd b/docs/guides/installation.qmd index 15d262f..9be4f6a 100644 --- a/docs/guides/installation.qmd +++ b/docs/guides/installation.qmd @@ -1,18 +1,18 @@ --- title: "Installation" -description: "How to install {{package-name-kebab-case}}" +description: "How to install python-nix-template" --- # Installation -This guide covers different ways to install {{package-name-kebab-case}}. +This guide covers different ways to install python-nix-template. ## Using UV (Recommended) The fastest way to get started is with UV: ```bash -uv pip install {{package-name-kebab-case}} +uv pip install python-nix-template ``` ## Using Pip @@ -20,7 +20,7 @@ uv pip install {{package-name-kebab-case}} You can also install with standard pip: ```bash -pip install {{package-name-kebab-case}} +pip install python-nix-template ``` ## Development Installation @@ -28,8 +28,8 @@ pip install {{package-name-kebab-case}} For development, clone the repository and set up the environment: ```bash -git clone https://github.com/{{git-org}}/{{package-name-kebab-case}}.git -cd {{package-name-kebab-case}} +git clone https://github.com/sciexp/python-nix-template.git +cd python-nix-template # With Nix (recommended) nix develop @@ -43,6 +43,6 @@ uv sync Verify your installation by running: ```python -import {{package-name-kebab-case}} -print({{package-name-kebab-case}}.__version__) +import python-nix-template +print(python-nix-template.__version__) ``` \ No newline at end of file From e28669bd8250d8cc939fa68aa15daff31eea4c32 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:21 -0500 Subject: [PATCH 10/55] fix(docs): replace Jinja placeholders with omnix literals in development.qmd --- docs/guides/development.qmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/development.qmd b/docs/guides/development.qmd index 3501289..2ab9fa6 100644 --- a/docs/guides/development.qmd +++ b/docs/guides/development.qmd @@ -1,11 +1,11 @@ --- title: "Development" -description: "Development guide for {{package-name-kebab-case}}" +description: "Development guide for python-nix-template" --- # Development Guide -This guide covers development workflows for {{package-name-kebab-case}}. +This guide covers development workflows for python-nix-template. ## Development Environment From ddcd59ab2375dac8d04a86966282443691b2229b Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:29 -0500 Subject: [PATCH 11/55] fix(docs): replace Jinja placeholder with omnix literal in development/index.qmd --- docs/development/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/index.qmd b/docs/development/index.qmd index c4e566e..a42981e 100644 --- a/docs/development/index.qmd +++ b/docs/development/index.qmd @@ -14,7 +14,7 @@ csl: ../bibstyle.csl # Introduction {#sec-introduction} -This section provides comprehensive technical documentation for developers working on {{package-name-kebab-case}}. It follows the AMDiRE (Artefact-based Model for Domain-independent Requirements Engineering) framework to ensure a structured, traceable approach to development documentation [@Mendez-Fernandez2015-xj;@Chuprina2021-xx]. +This section provides comprehensive technical documentation for developers working on python-nix-template. It follows the AMDiRE (Artefact-based Model for Domain-independent Requirements Engineering) framework to ensure a structured, traceable approach to development documentation [@Mendez-Fernandez2015-xj;@Chuprina2021-xx]. ## Artifact-based requirements framework {#sec-amdire} From 14960dc1aef1df76807847eb69ef8041683d439a Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:36 -0500 Subject: [PATCH 12/55] fix(docs): replace Jinja placeholder with omnix literal in context/index.qmd --- docs/development/context/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/context/index.qmd b/docs/development/context/index.qmd index 344d861..c6ad354 100644 --- a/docs/development/context/index.qmd +++ b/docs/development/context/index.qmd @@ -17,7 +17,7 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document outlines the context for the {{package-name-kebab-case}} project. +This document outlines the context for the python-nix-template project. | Topic | Reference | |-------|-----------| From e04604c20bac1d56571456e590deba6677914610 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:44 -0500 Subject: [PATCH 13/55] fix(docs): replace Jinja placeholder with omnix literal in context/context.qmd --- docs/development/context/context.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/context/context.qmd b/docs/development/context/context.qmd index 7e049ab..5b6a239 100644 --- a/docs/development/context/context.qmd +++ b/docs/development/context/context.qmd @@ -17,4 +17,4 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document specifies the context to establish the motivation and conceptual foundation for the {{package-name-kebab-case}} project. +This document specifies the context to establish the motivation and conceptual foundation for the python-nix-template project. From 1a9b101f8fa52e239622f96f321ff25462f3484f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:54:54 -0500 Subject: [PATCH 14/55] fix(docs): replace Jinja placeholder with omnix literal in architecture/index.qmd --- docs/development/architecture/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/architecture/index.qmd b/docs/development/architecture/index.qmd index d03bc32..fb17dbe 100644 --- a/docs/development/architecture/index.qmd +++ b/docs/development/architecture/index.qmd @@ -17,7 +17,7 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This system specification outlines the system architecture and design for the {{package-name-kebab-case}} project. +This system specification outlines the system architecture and design for the python-nix-template project. | Topic | Reference | |-------|-----------| From 206b4bd6f2ea1af571bf5d29203df8bf7e24f4e0 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:02 -0500 Subject: [PATCH 15/55] fix(docs): replace Jinja placeholder with omnix literal in architecture/architecture.qmd --- docs/development/architecture/architecture.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/architecture/architecture.qmd b/docs/development/architecture/architecture.qmd index 33561b5..b8609b4 100644 --- a/docs/development/architecture/architecture.qmd +++ b/docs/development/architecture/architecture.qmd @@ -17,4 +17,4 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This system specification provides a glass-box view of the architecture of the {{package-name-kebab-case}} package, detailing its internal structure, computational methods, and implementation approach. +This system specification provides a glass-box view of the architecture of the python-nix-template package, detailing its internal structure, computational methods, and implementation approach. From 3dd9d95855e465ff845f842dbfc47aa8fd00995f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:11 -0500 Subject: [PATCH 16/55] fix(docs): replace Jinja placeholder with omnix literal in requirements/requirements.qmd --- docs/development/requirements/requirements.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/requirements/requirements.qmd b/docs/development/requirements/requirements.qmd index 3dec495..7906836 100644 --- a/docs/development/requirements/requirements.qmd +++ b/docs/development/requirements/requirements.qmd @@ -17,4 +17,4 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This requirements specification document defines what {{package-name-kebab-case}} should do from an external (black-box) perspective without specifying how it will be implemented internally. +This requirements specification document defines what python-nix-template should do from an external (black-box) perspective without specifying how it will be implemented internally. From ae803dd3db957247eb0107062a3035c88061b020 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:25 -0500 Subject: [PATCH 17/55] fix(docs): replace Jinja placeholder with omnix literal in requirements/index.qmd --- docs/development/requirements/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/requirements/index.qmd b/docs/development/requirements/index.qmd index d2df5c2..5efc3d1 100644 --- a/docs/development/requirements/index.qmd +++ b/docs/development/requirements/index.qmd @@ -17,7 +17,7 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document will outline the requirements for the {{package-name-kebab-case}} project. +This document will outline the requirements for the python-nix-template project. | Topic | Reference | |-------|-----------| From 78a2e20466fc8fd5d55ca2c90951c4cb3f8ad222 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:33 -0500 Subject: [PATCH 18/55] fix(docs): replace Jinja placeholder with omnix literal in traceability/index.qmd --- docs/development/traceability/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/traceability/index.qmd b/docs/development/traceability/index.qmd index 138fb62..8532be4 100644 --- a/docs/development/traceability/index.qmd +++ b/docs/development/traceability/index.qmd @@ -13,7 +13,7 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document outlines the traceability and validation approach for the {{package-name-kebab-case}} project. +This document outlines the traceability and validation approach for the python-nix-template project. | Topic | Reference | |-------|-----------| From 7fa820e9213a81cbe430c4728aa91557a0fb3001 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:40 -0500 Subject: [PATCH 19/55] fix(docs): replace Jinja placeholder with omnix literal in traceability/testing.qmd --- docs/development/traceability/testing.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/traceability/testing.qmd b/docs/development/traceability/testing.qmd index 22715cc..1ba51f8 100644 --- a/docs/development/traceability/testing.qmd +++ b/docs/development/traceability/testing.qmd @@ -13,4 +13,4 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document describes the testing approach and infrastructure for the {{package-name-kebab-case}} library. +This document describes the testing approach and infrastructure for the python-nix-template library. From 7d3990f482e6906e3b46d23a5f78d6b0679a6e45 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:55:49 -0500 Subject: [PATCH 20/55] fix(docs): replace Jinja placeholder with omnix literal in work-items/index.qmd --- docs/development/work-items/index.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/development/work-items/index.qmd b/docs/development/work-items/index.qmd index d73687f..c7a53cd 100644 --- a/docs/development/work-items/index.qmd +++ b/docs/development/work-items/index.qmd @@ -16,6 +16,6 @@ csl: ../../bibstyle.csl ## Purpose of this Document {#sec-purpose} -This document provides an overview of the work items for the {{package-name-kebab-case}} project. +This document provides an overview of the work items for the python-nix-template project. In the Agile methodology, these might correspond to stories from epics, but they will generally be associated with GitHub issues and pull requests. \ No newline at end of file From c47395cc712ded9aec922c961f95854a6857da1f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:57:47 -0500 Subject: [PATCH 21/55] fix(template): align root package.json name and description with omnix placeholders --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a6d4f0f..5ccceb7 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "python-nix-template-template", + "name": "python-nix-template", "version": "0.0.0-development", "private": true, - "description": "Python Nix Template with uv2nix integration", + "description": "A Python project template for Nix using uv2nix and flake-parts", "repository": { "type": "git", "url": "https://github.com/sciexp/python-nix-template.git" From aaeecef057d5e4336e2ff087d433e6841b19fde4 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:57:54 -0500 Subject: [PATCH 22/55] fix(template): align pnt-cli package.json description with omnix placeholder --- packages/pnt-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pnt-cli/package.json b/packages/pnt-cli/package.json index c44aa6a..d7782b3 100644 --- a/packages/pnt-cli/package.json +++ b/packages/pnt-cli/package.json @@ -1,5 +1,5 @@ { - "description": "pnt-cli with pyo3 native bindings", + "description": "A Python project template for Nix using uv2nix and flake-parts", "devDependencies": { "@semantic-release/changelog": "^6.0.3", "@semantic-release/github": "^12.0.0", From 2f59dd1e9ba9289e2e4af104ab7171f3eab20841 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:58:01 -0500 Subject: [PATCH 23/55] fix(template): align pnt-functional package.json description with omnix placeholder --- packages/pnt-functional/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pnt-functional/package.json b/packages/pnt-functional/package.json index 6c66af8..aacd5d2 100644 --- a/packages/pnt-functional/package.json +++ b/packages/pnt-functional/package.json @@ -1,5 +1,5 @@ { - "description": "Python Nix Template with uv2nix integration", + "description": "A Python project template for Nix using uv2nix and flake-parts", "devDependencies": { "@semantic-release/changelog": "^6.0.3", "@semantic-release/github": "^12.0.0", From 03f56acb368be050f6841194b0bef73879f915fe Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 22:58:10 -0500 Subject: [PATCH 24/55] fix(template): align python-nix-template package.json description with omnix placeholder --- packages/python-nix-template/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/python-nix-template/package.json b/packages/python-nix-template/package.json index b1133fe..c143f69 100644 --- a/packages/python-nix-template/package.json +++ b/packages/python-nix-template/package.json @@ -1,5 +1,5 @@ { - "description": "Python Nix Template with uv2nix integration", + "description": "A Python project template for Nix using uv2nix and flake-parts", "devDependencies": { "@semantic-release/changelog": "^6.0.3", "@semantic-release/github": "^12.0.0", From 3ca68e02ba4175c5487a17fd75a3d1a079d45521 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:04:00 -0500 Subject: [PATCH 25/55] feat(template): gate wheel workflow files on pyo3-package parameter Add wheel-build.yaml and wheel-release.yaml to the pyo3-package paths list so they are excluded when instantiating without pyo3. --- modules/template.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/template.nix b/modules/template.nix index 06df889..088df7a 100644 --- a/modules/template.nix +++ b/modules/template.nix @@ -110,6 +110,8 @@ "packages/pnt-cli" "nix/packages/pnt-cli" "rust-toolchain.toml" + ".github/workflows/wheel-build.yaml" + ".github/workflows/wheel-release.yaml" ]; value = false; } From ca37c27c3e91801760e549327293d0af9d196786 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:04:27 -0500 Subject: [PATCH 26/55] feat(ci): add standalone wheel-release workflow for pyo3 packages Trigger wheel builds on release events instead of chaining from package-release.yaml, avoiding reusable workflow references that break when wheel-build.yaml is excluded by omnix template. --- .github/workflows/wheel-release.yaml | 68 ++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/wheel-release.yaml diff --git a/.github/workflows/wheel-release.yaml b/.github/workflows/wheel-release.yaml new file mode 100644 index 0000000..d9f1adc --- /dev/null +++ b/.github/workflows/wheel-release.yaml @@ -0,0 +1,68 @@ +name: Wheel Release + +on: + release: + types: [published] + +defaults: + run: + shell: bash + +jobs: + check-wheels: + name: Check if wheel build is needed + runs-on: ubuntu-latest + outputs: + build-wheels: ${{ steps.check.outputs.build-wheels }} + checkout-ref: ${{ steps.check.outputs.checkout-ref }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + ref: ${{ github.event.release.tag_name }} + sparse-checkout: packages + sparse-checkout-cone-mode: true + + - name: Determine if release needs wheel build + id: check + run: | + # Extract package name from tag (format: package-name-vX.Y.Z) + TAG="${{ github.event.release.tag_name }}" + # Remove version suffix to get package name + PACKAGE_NAME=$(echo "$TAG" | sed 's/-v[0-9].*//') + + echo "Tag: $TAG" + echo "Package: $PACKAGE_NAME" + echo "checkout-ref=$TAG" >> "$GITHUB_OUTPUT" + + # Check if this package uses maturin/pyo3 (has Cargo.toml) + if [ -f "packages/$PACKAGE_NAME/Cargo.toml" ]; then + echo "Package $PACKAGE_NAME has Cargo.toml, wheels needed" + echo "build-wheels=true" >> "$GITHUB_OUTPUT" + else + echo "Package $PACKAGE_NAME has no Cargo.toml, skipping wheels" + echo "build-wheels=false" >> "$GITHUB_OUTPUT" + fi + + build-wheels: + needs: [check-wheels] + if: ${{ needs.check-wheels.outputs.build-wheels == 'true' }} + uses: ./.github/workflows/wheel-build.yaml + with: + checkout-ref: ${{ needs.check-wheels.outputs.checkout-ref }} + + publish-wheels: + name: Publish wheels to PyPI + needs: [check-wheels, build-wheels] + if: ${{ needs.check-wheels.outputs.build-wheels == 'true' }} + runs-on: ubuntu-latest + steps: + - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7 + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + with: + pattern: wheels-* + merge-multiple: true + path: dist + - name: Publish to PyPI + run: uv publish dist/* + env: + UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }} From c8258e67d27ec2d6d20191afdd8113a2ae40868c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:05:29 -0500 Subject: [PATCH 27/55] refactor(ci): decouple wheel build from package-release workflow Remove build-wheels and publish-wheels jobs and the build-wheels input parameter. Detect maturin packages via Cargo.toml presence to skip uv build for pyo3 packages. Wheel building is now handled by the standalone wheel-release workflow triggered on release events. --- .github/workflows/package-release.yaml | 49 +++++++------------------- 1 file changed, 13 insertions(+), 36 deletions(-) diff --git a/.github/workflows/package-release.yaml b/.github/workflows/package-release.yaml index 6f68df6..b1d9c8b 100644 --- a/.github/workflows/package-release.yaml +++ b/.github/workflows/package-release.yaml @@ -44,11 +44,6 @@ on: required: false type: string default: "[]" - build-wheels: - description: "Whether to build cross-platform wheels via maturin" - required: false - type: boolean - default: false force-run: description: "Force execution even if already successful" required: false @@ -98,11 +93,6 @@ on: required: false type: string default: "[]" - build-wheels: - description: "Whether to build cross-platform wheels via maturin" - required: false - type: string - default: "false" force-run: description: "Force execution even if already successful" required: false @@ -216,8 +206,18 @@ jobs: echo "No release needed for ${{ inputs.package-name }}" fi + - name: Detect maturin package + id: detect-maturin + if: steps.cache.outputs.should-run == 'true' + run: | + if [ -f "${{ inputs.package-path }}/Cargo.toml" ]; then + echo "is-maturin=true" >> "$GITHUB_OUTPUT" + else + echo "is-maturin=false" >> "$GITHUB_OUTPUT" + fi + - name: Build package - if: steps.cache.outputs.should-run == 'true' && inputs.build-wheels != 'true' && (steps.release-info.outputs.released == 'true' || inputs.release-dry-run == 'true') + if: steps.cache.outputs.should-run == 'true' && steps.detect-maturin.outputs.is-maturin != 'true' && (steps.release-info.outputs.released == 'true' || inputs.release-dry-run == 'true') working-directory: ${{ inputs.package-path }} run: | nix develop --accept-flake-config -c uv build @@ -227,14 +227,14 @@ jobs: if: ${{ inputs.debug-enabled }} - name: Upload artifacts - if: steps.cache.outputs.should-run == 'true' && inputs.build-wheels != 'true' && (steps.release-info.outputs.released == 'true' || inputs.release-dry-run == 'true') + if: steps.cache.outputs.should-run == 'true' && steps.detect-maturin.outputs.is-maturin != 'true' && (steps.release-info.outputs.released == 'true' || inputs.release-dry-run == 'true') uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 with: name: ${{ steps.set-outputs.outputs.artifact-name }} path: ${{ inputs.package-path }}/dist - name: Publish to PyPI - if: steps.cache.outputs.should-run == 'true' && inputs.build-wheels != 'true' && steps.release-info.outputs.released == 'true' && inputs.release-dry-run != 'true' + if: steps.cache.outputs.should-run == 'true' && steps.detect-maturin.outputs.is-maturin != 'true' && steps.release-info.outputs.released == 'true' && inputs.release-dry-run != 'true' working-directory: ${{ inputs.package-path }} run: nix develop --accept-flake-config -c uv publish env: @@ -264,26 +264,3 @@ jobs: tags: "" secrets: inherit - build-wheels: - needs: [release] - if: ${{ inputs.build-wheels == 'true' && needs.release.outputs.released == 'true' && inputs.release-dry-run != 'true' }} - uses: ./.github/workflows/wheel-build.yaml - with: - checkout-ref: ${{ needs.release.outputs.tag }} - - publish-wheels: - name: Publish wheels to PyPI - needs: [release, build-wheels] - if: ${{ needs.release.outputs.released == 'true' }} - runs-on: ubuntu-latest - steps: - - uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7 - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - pattern: wheels-* - merge-multiple: true - path: dist - - name: Publish to PyPI - run: uv publish dist/* - env: - UV_PUBLISH_TOKEN: ${{ secrets.UV_PUBLISH_TOKEN }} From 4554e940c3217e33450188985e6850d73bdbd31f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:06:10 -0500 Subject: [PATCH 28/55] refactor(ci): remove build-wheels from package discovery and release inputs Wheel building is now handled by the standalone wheel-release workflow triggered on release events, so ci.yaml no longer needs to detect or pass build-wheels to package-release. --- .github/workflows/ci.yaml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f816fe6..cf694bb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -178,13 +178,6 @@ jobs: d=$(dirname "$f") n=$(basename "$d") - # Infer build-wheels from Cargo.toml presence (maturin/pyo3 package) - if [ -f "$d/Cargo.toml" ]; then - build_wheels="true" - else - build_wheels="false" - fi - # Read per-package CI metadata from .ci.json if present ci_json="$d/.ci.json" if [ -f "$ci_json" ]; then @@ -198,10 +191,9 @@ jobs: jq -nc \ --arg name "$n" \ --arg path "$d" \ - --arg build_wheels "$build_wheels" \ --arg build_images "$build_images" \ --argjson images "$images" \ - '{name: $name, path: $path, "build-wheels": $build_wheels, "build-images": $build_images, images: ($images | tojson)}' + '{name: $name, path: $path, "build-images": $build_images, images: ($images | tojson)}' done | jq -sc '.') echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" echo "Discovered packages: $PACKAGES" @@ -629,7 +621,6 @@ jobs: checkout-ref: ${{ needs.set-variables.outputs.checkout_ref }} build-images: ${{ matrix.package.build-images }} images-to-build: ${{ matrix.package.images }} - build-wheels: ${{ matrix.package.build-wheels || 'false' }} secrets: inherit # --------------------------------------------------------------------------- From fba3893fcaa26cd83f6a3c3537febc61d8eea921 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:08:44 -0500 Subject: [PATCH 29/55] fix(ci): resolve SC2012 use find instead of ls in package discovery --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cf694bb..e717750 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -174,7 +174,7 @@ jobs: - name: Discover packages id: discover-packages run: | - PACKAGES=$(ls -d packages/*/pyproject.toml | while read -r f; do + PACKAGES=$(find packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do d=$(dirname "$f") n=$(basename "$d") From c79bc6ad7d7614788be4c20f529b86b84a9ed4cc Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:09:11 -0500 Subject: [PATCH 30/55] fix(ci): resolve SC2086 and SC2129 in package-release.yaml Quote $GITHUB_OUTPUT to prevent globbing and word splitting. Use grouped redirects instead of individual redirects. Quote ${{ inputs.* }} arguments to release-package command. --- .github/workflows/package-release.yaml | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/package-release.yaml b/.github/workflows/package-release.yaml index b1d9c8b..4f3a359 100644 --- a/.github/workflows/package-release.yaml +++ b/.github/workflows/package-release.yaml @@ -160,7 +160,7 @@ jobs: id: tags-before if: steps.cache.outputs.should-run == 'true' run: | - echo "latest=$(git tag -l '${{ inputs.package-name }}-v*' | sort -V | tail -1)" >> $GITHUB_OUTPUT + echo "latest=$(git tag -l '${{ inputs.package-name }}-v*' | sort -V | tail -1)" >> "$GITHUB_OUTPUT" - name: Run semantic-release id: semantic-release @@ -169,7 +169,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - nix develop --accept-flake-config -c just release-package ${{ inputs.package-name }} ${{ inputs.release-dry-run }} + nix develop --accept-flake-config -c just release-package "${{ inputs.package-name }}" "${{ inputs.release-dry-run }}" - name: Extract release info if: always() @@ -180,16 +180,22 @@ jobs: PREV_TAG="${{ steps.tags-before.outputs.latest }}" if [ -n "$LATEST_TAG" ] && [ "$LATEST_TAG" != "$PREV_TAG" ]; then VERSION=$(echo "$LATEST_TAG" | grep -oP '\d+\.\d+\.\d+' || echo "unknown") - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "released=true" >> $GITHUB_OUTPUT - echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT + { + echo "version=$VERSION" + echo "released=true" + echo "tag=$LATEST_TAG" + } >> "$GITHUB_OUTPUT" else - echo "released=false" >> $GITHUB_OUTPUT - echo "tag=" >> $GITHUB_OUTPUT + { + echo "released=false" + echo "tag=" + } >> "$GITHUB_OUTPUT" fi else - echo "released=false" >> $GITHUB_OUTPUT - echo "tag=" >> $GITHUB_OUTPUT + { + echo "released=false" + echo "tag=" + } >> "$GITHUB_OUTPUT" fi - name: Set outputs From 4041977c1e83b2b35b3b2118248f4092a4c5e957 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:09:36 -0500 Subject: [PATCH 31/55] fix(ci): resolve SC2001 use parameter expansion in wheel-release.yaml Replace sed with bash parameter expansion ${TAG%%-v[0-9]*} to strip the version suffix from release tags. --- .github/workflows/wheel-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheel-release.yaml b/.github/workflows/wheel-release.yaml index d9f1adc..dee1398 100644 --- a/.github/workflows/wheel-release.yaml +++ b/.github/workflows/wheel-release.yaml @@ -28,7 +28,7 @@ jobs: # Extract package name from tag (format: package-name-vX.Y.Z) TAG="${{ github.event.release.tag_name }}" # Remove version suffix to get package name - PACKAGE_NAME=$(echo "$TAG" | sed 's/-v[0-9].*//') + PACKAGE_NAME="${TAG%%-v[0-9]*}" echo "Tag: $TAG" echo "Package: $PACKAGE_NAME" From 1feaf2111e96fb9ff09b4972d6f5c17e8a1a2461 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:10:08 -0500 Subject: [PATCH 32/55] fix(ci): resolve SC2086 quote matrix.package.path in ci.yaml --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e717750..5ad55d6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -480,7 +480,7 @@ jobs: if: steps.cache.outputs.should-run == 'true' run: | echo "::group::Preview semantic-release version" - OUTPUT=$(nix develop --accept-flake-config -c just preview-version main ${{ matrix.package.path }} 2>&1 | tee /dev/stderr) + OUTPUT=$(nix develop --accept-flake-config -c just preview-version main "${{ matrix.package.path }}" 2>&1 | tee /dev/stderr) echo "::endgroup::" # Strip ANSI escape codes before parsing (script outputs colored text) From cc5b2716a678fb19ff257b1c5e3fc5376a98f438 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 16 Feb 2026 23:11:01 -0500 Subject: [PATCH 33/55] chore(beads): close pnt-3zn issues 1-5 --- .beads/issues.jsonl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 38bf18c..29188df 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -3,11 +3,11 @@ {"id":"pnt-3jf","title":"Validate sciexp/data platform instantiation","description":"Final validation gate before v0.2.0 release. Instantiate template to create the sciexp data platform repository.\n\nTarget: ~/projects/sciexp/data\n\nValidation steps:\n- Instantiate template with configuration for omicsio, scilake, scimesh package structure\n- Verify independent locks work for each package\n- Verify Nix builds succeed for all packages\n- Verify CI patterns work correctly\n- Document any issues found and fix if minor, or create follow-up issues if significant\n\nThis issue is blocked by the other four polish issues. Successful completion means we are ready to manually create the v0.2.0 release tag.\n\nReference: ~/projects/sciexp/planning/contexts/sciexp-data-platform.md for sciexp/data requirements\n\nScope: ~3 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:48:01.905707-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:14:16.459237-05:00","closed_at":"2026-02-05T15:14:16.459237-05:00","close_reason":"Validated: template evaluation, test infrastructure (11/11 tests pass across 3 packages), and instantiation workflow confirmed working. Welcome text and README are consistent. 619014b","dependencies":[{"issue_id":"pnt-3jf","depends_on_id":"pnt-6yk","type":"blocks","created_at":"2026-02-05T13:48:10.890329-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-5wx","type":"blocks","created_at":"2026-02-05T13:48:11.058701-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-m7j","type":"blocks","created_at":"2026-02-05T13:48:11.23594-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-bxq","type":"blocks","created_at":"2026-02-05T13:48:11.38108-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:50:30.680871-05:00"} -{"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:02.791847-05:00","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:03.823132-05:00","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:04.89314-05:00","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:07.237944-05:00","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:37:08.32939-05:00","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:51:59.673636-05:00","closed_at":"2026-02-16T22:51:59.673636-05:00","close_reason":"Implemented in f5bf4a4","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:56:41.185276-05:00","closed_at":"2026-02-16T22:56:41.185276-05:00","close_reason":"Implemented in f5bf4a4..7d3990f","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} {"id":"pnt-4jg.1","title":"Remove uv workspace, adopt path dependencies","description":"Remove [tool.uv.workspace] from root pyproject.toml. Each package gets own pyproject.toml with [tool.uv.sources] for sibling references using path sources with editable=true. Follow langchain pattern.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:07.344057-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T14:40:02.175394-05:00","closed_at":"2026-02-02T14:40:02.175394-05:00","close_reason":"Implemented in a8a823f. Removed root uv workspace, generated per-package locks, rewrote nix modules to Pattern 3 per-package loading.","dependencies":[{"issue_id":"pnt-4jg.1","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:07.344659-05:00","created_by":"Cameron Smith"}],"comments":[{"id":1,"issue_id":"pnt-4jg.1","author":"Cameron Smith","text":"Post-close fixup commits (774ec26):\n- fix(ci): update lock file references for per-package federation (d0cab2a)\n- fixup! merge federated workspace deps: replace // with zipAttrsWith for extras-safe dep merging (7b3e7ae)\n- fixup! load packages independently: document version-conflict invariant in python.nix and architecture doc (36eb8a7, 774ec26)\n\nReview findings addressed: stale CI cache-dependency-glob paths, fragile shallow-merge dep specs, undocumented overlay composition invariant. Full CI redesign (nix develop + justfile symmetry) deferred to pnt-dre.4.","created_at":"2026-02-02T20:17:00Z"}]} {"id":"pnt-4jg.2","title":"Configure pixi feature-based composition","description":"Implement pixi feature/environment pattern: [feature.X.dependencies] + [environments] composition. Single pixi.lock covering all environments. Per-feature task definitions. Target-specific dependencies for platform support.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:08.085592-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:36:49.459815-05:00","closed_at":"2026-02-02T15:36:49.459815-05:00","close_reason":"Verified pixi feature composition via nix develop -c just \u003crecipe\u003e. Fixed: added missing feature tasks to python-nix-template, delegated justfile conda recipes to pixi task names for correct working directory, moved deprecated build channels to backend.channels.","dependencies":[{"issue_id":"pnt-4jg.2","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:08.086155-05:00","created_by":"Cameron Smith"}]} From 0d10d3099d92af0ae3494082190fb7c5ab59adab Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 00:18:32 -0500 Subject: [PATCH 34/55] chore(pnt-functional): bump version to 0.2.2 --- packages/pnt-functional/pyproject.toml | 4 ++-- packages/pnt-functional/uv.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pnt-functional/pyproject.toml b/packages/pnt-functional/pyproject.toml index ba1ca45..aa71e16 100644 --- a/packages/pnt-functional/pyproject.toml +++ b/packages/pnt-functional/pyproject.toml @@ -19,7 +19,7 @@ license = { text = "Apache-2.0" } name = "pnt-functional" readme = "README.md" requires-python = ">=3.12,<3.14" -version = "0.2.1" +version = "0.2.2" [project.scripts] pnt-functional = "pnt_functional.main:greet" @@ -89,7 +89,7 @@ types = "pyright src/" [tool.pixi.package] name = "pnt-functional" -version = "0.2.1" +version = "0.2.2" [tool.pixi.package.run-dependencies] beartype = ">=0.19.0,<0.20.0" diff --git a/packages/pnt-functional/uv.lock b/packages/pnt-functional/uv.lock index d87c83d..50a295e 100644 --- a/packages/pnt-functional/uv.lock +++ b/packages/pnt-functional/uv.lock @@ -235,7 +235,7 @@ wheels = [ [[package]] name = "pnt-functional" -version = "0.2.1" +version = "0.2.2" source = { editable = "." } dependencies = [ { name = "beartype" }, From 10e5dec4bdb3e8c5e0bdbf361dadd4ea78a91ff6 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 00:18:51 -0500 Subject: [PATCH 35/55] chore(pnt-cli): bump version to 0.1.3 --- packages/pnt-cli/Cargo.lock | 40 ++++++++++++++++----------------- packages/pnt-cli/Cargo.toml | 2 +- packages/pnt-cli/pyproject.toml | 2 +- packages/pnt-cli/uv.lock | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/pnt-cli/Cargo.lock b/packages/pnt-cli/Cargo.lock index ba37256..562c095 100644 --- a/packages/pnt-cli/Cargo.lock +++ b/packages/pnt-cli/Cargo.lock @@ -10,9 +10,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "libc" -version = "0.2.180" +version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "once_cell" @@ -22,11 +22,11 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "pnt-cli-core" -version = "0.1.2" +version = "0.1.3" [[package]] name = "pnt-cli-py" -version = "0.1.2" +version = "0.1.3" dependencies = [ "pnt-cli-core", "pyo3", @@ -49,9 +49,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3ccafdf54c050be48a3a086d372f77ba6615f5057211607cd30e5ac5cec6d" +checksum = "14c738662e2181be11cb82487628404254902bb3225d8e9e99c31f3ef82a405c" dependencies = [ "libc", "once_cell", @@ -63,18 +63,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972720a441c91fd9c49f212a1d2d74c6e3803b231ebc8d66c51efbd7ccab11c8" +checksum = "f9ca0864a7dd3c133a7f3f020cbff2e12e88420da854c35540fd20ce2d60e435" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5994456d9dab8934d600d3867571b6410f24fbd6002570ad56356733eb54859b" +checksum = "9dfc1956b709823164763a34cc42bbfd26b8730afa77809a3df8b94a3ae3b059" dependencies = [ "libc", "pyo3-build-config", @@ -82,9 +82,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ce9cc8d81b3c4969748807604d92b4eef363c5bb82b1a1bdb34ec6f1093a18" +checksum = "29dc660ad948bae134d579661d08033fbb1918f4529c3bbe3257a68f2009ddf2" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -94,9 +94,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf4b60036a154d23282679b658e3cc7d88d3b8c9a40b43824785f232d2e1b98" +checksum = "e78cd6c6d718acfcedf26c3d21fe0f053624368b0d44298c55d7138fde9331f7" dependencies = [ "heck", "proc-macro2", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" dependencies = [ "proc-macro2", "quote", @@ -127,12 +127,12 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/packages/pnt-cli/Cargo.toml b/packages/pnt-cli/Cargo.toml index 65ef0a5..54b7ae5 100644 --- a/packages/pnt-cli/Cargo.toml +++ b/packages/pnt-cli/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/pnt-cli-core", "crates/pnt-cli-py"] [workspace.package] -version = "0.1.2" +version = "0.1.3" edition = "2024" license = "Apache-2.0" diff --git a/packages/pnt-cli/pyproject.toml b/packages/pnt-cli/pyproject.toml index 36bf60e..3a7c5a9 100644 --- a/packages/pnt-cli/pyproject.toml +++ b/packages/pnt-cli/pyproject.toml @@ -16,7 +16,7 @@ description = "CLI package with Rust extension module via pyo3/maturin" license = { text = "Apache-2.0" } name = "pnt-cli" requires-python = ">=3.12,<3.14" -version = "0.1.2" +version = "0.1.3" [project.scripts] pnt-cli = "pnt_cli:main" diff --git a/packages/pnt-cli/uv.lock b/packages/pnt-cli/uv.lock index a5f22fe..a733f47 100644 --- a/packages/pnt-cli/uv.lock +++ b/packages/pnt-cli/uv.lock @@ -49,7 +49,7 @@ wheels = [ [[package]] name = "pnt-cli" -version = "0.1.2" +version = "0.1.3" source = { editable = "." } [package.dev-dependencies] From c1f5cd971899fe74212e6633ecf3b2505107fc36 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 00:19:07 -0500 Subject: [PATCH 36/55] chore(python-nix-template): bump version to 0.2.1 --- packages/python-nix-template/pyproject.toml | 4 ++-- packages/python-nix-template/uv.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/python-nix-template/pyproject.toml b/packages/python-nix-template/pyproject.toml index e39e389..487a0b5 100644 --- a/packages/python-nix-template/pyproject.toml +++ b/packages/python-nix-template/pyproject.toml @@ -7,7 +7,7 @@ description = "Add your description here" name = "python-nix-template" readme = "README.md" requires-python = ">=3.12,<3.14" -version = "0.2.0" +version = "0.2.1" [project.scripts] python-nix-template = "python_nix_template:main" @@ -83,7 +83,7 @@ types = "pyright src/" [tool.pixi.package] name = "python-nix-template" -version = "0.2.0" +version = "0.2.1" [tool.pixi.package.run-dependencies] diff --git a/packages/python-nix-template/uv.lock b/packages/python-nix-template/uv.lock index e173806..d5b9c5e 100644 --- a/packages/python-nix-template/uv.lock +++ b/packages/python-nix-template/uv.lock @@ -1399,7 +1399,7 @@ wheels = [ [[package]] name = "python-nix-template" -version = "0.2.0" +version = "0.2.1" source = { editable = "." } [package.dev-dependencies] From 763c04737d7fca377f0fd06a1b9d621404d01f98 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 00:19:28 -0500 Subject: [PATCH 37/55] fix(ci): add camelCase param to template workflow test invocations --- .github/workflows/template.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/template.yaml b/.github/workflows/template.yaml index c436c5e..3ccf7da 100644 --- a/.github/workflows/template.yaml +++ b/.github/workflows/template.yaml @@ -147,6 +147,7 @@ jobs: nix --accept-flake-config run github:juspay/omnix/v1.3.2 -- init "$REPO_REF" -o pnt-mono --non-interactive --params '{ "package-name-kebab-case": "pnt-mono", "package-name-snake-case": "pnt_mono", + "package-name-camel-case": "pntMono", "monorepo-package": true, "git-org": "pnt-mono", "author": "Pnt Mono", @@ -187,6 +188,7 @@ jobs: nix --accept-flake-config run github:juspay/omnix/v1.3.2 -- init "$REPO_REF" -o pnt-new --non-interactive --params '{ "package-name-kebab-case": "pnt-new", "package-name-snake-case": "pnt_new", + "package-name-camel-case": "pntNew", "monorepo-package": false, "git-org": "pnt-new", "author": "Pnt New", From 82c2e1ce98fb7fe247e7e87c55cc5c55ff74049c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 00:21:26 -0500 Subject: [PATCH 38/55] refactor(ci): remove redundant maximize-build-space step from deploy-docs The setup-nix composite action already calls nothing-but-nix at the cleave level, which removes all pre-installed software including the Android SDK and CodeQL toolcache that this step targeted. --- .github/workflows/deploy-docs.yaml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 2940cb1..0a52550 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -35,21 +35,6 @@ jobs: build-docs: runs-on: ubuntu-latest steps: - # https://github.com/easimon/maximize-build-space/blob/v10/action.yml#L121-L137 - - name: Maximize build space - run: | - echo "Available storage before removing unused software:" - sudo df -h - echo - sudo rm -rf /usr/local/lib/android - echo "Available storage after removing android:" - sudo df -h - echo - sudo rm -rf /opt/hostedtoolcache/CodeQL - echo "Available storage after removing codeql:" - sudo df -h - echo - - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: From 6fd27b9d1fe374a02627a54e411ac220c4d0d30f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:31:35 -0500 Subject: [PATCH 39/55] chore(beads): add deploy-docs alignment issues pnt-3zn.6-10 --- .beads/issues.jsonl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 29188df..c776184 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -4,10 +4,15 @@ {"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:50:30.680871-05:00"} {"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:51:59.673636-05:00","closed_at":"2026-02-16T22:51:59.673636-05:00","close_reason":"Implemented in f5bf4a4","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.10","title":"Add execution cache and link validation to deploy-docs workflow","description":"Integrate cached-ci-job composite action into the deploy-docs workflow to skip redundant builds when docs content has not changed. Add documentation link validation step (just docs-linkcheck) before deployment. Hash sources should include docs content, setup-nix action, deploy-docs workflow, justfile, and scripts. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:51.835528-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:19.219029-05:00","dependencies":[{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:51.836243-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.287119-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:56:41.185276-05:00","closed_at":"2026-02-16T22:56:41.185276-05:00","close_reason":"Implemented in f5bf4a4..7d3990f","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, main (worker entry point), compatibility_flags (nodejs_compat, global_fetch_strictly_public), observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Consider relocating from repo root to a docs package directory to match vanixiets (packages/docs/wrangler.jsonc) and typescript-nix-template patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:11.13797-05:00","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:14.748126-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:16.294775-05:00","dependencies":[{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:49.066821-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.6","type":"blocks","created_at":"2026-02-17T09:31:26.460586-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.7","type":"blocks","created_at":"2026-02-17T09:31:26.610437-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:18.112696-05:00","dependencies":[{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:50.157342-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.106011-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} {"id":"pnt-4jg.1","title":"Remove uv workspace, adopt path dependencies","description":"Remove [tool.uv.workspace] from root pyproject.toml. Each package gets own pyproject.toml with [tool.uv.sources] for sibling references using path sources with editable=true. Follow langchain pattern.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:07.344057-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T14:40:02.175394-05:00","closed_at":"2026-02-02T14:40:02.175394-05:00","close_reason":"Implemented in a8a823f. Removed root uv workspace, generated per-package locks, rewrote nix modules to Pattern 3 per-package loading.","dependencies":[{"issue_id":"pnt-4jg.1","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:07.344659-05:00","created_by":"Cameron Smith"}],"comments":[{"id":1,"issue_id":"pnt-4jg.1","author":"Cameron Smith","text":"Post-close fixup commits (774ec26):\n- fix(ci): update lock file references for per-package federation (d0cab2a)\n- fixup! merge federated workspace deps: replace // with zipAttrsWith for extras-safe dep merging (7b3e7ae)\n- fixup! load packages independently: document version-conflict invariant in python.nix and architecture doc (36eb8a7, 774ec26)\n\nReview findings addressed: stale CI cache-dependency-glob paths, fragile shallow-merge dep specs, undocumented overlay composition invariant. Full CI redesign (nix develop + justfile symmetry) deferred to pnt-dre.4.","created_at":"2026-02-02T20:17:00Z"}]} {"id":"pnt-4jg.2","title":"Configure pixi feature-based composition","description":"Implement pixi feature/environment pattern: [feature.X.dependencies] + [environments] composition. Single pixi.lock covering all environments. Per-feature task definitions. Target-specific dependencies for platform support.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:08.085592-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:36:49.459815-05:00","closed_at":"2026-02-02T15:36:49.459815-05:00","close_reason":"Verified pixi feature composition via nix develop -c just \u003crecipe\u003e. Fixed: added missing feature tasks to python-nix-template, delegated justfile conda recipes to pixi task names for correct working directory, moved deprecated build channels to backend.channels.","dependencies":[{"issue_id":"pnt-4jg.2","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:08.086155-05:00","created_by":"Cameron Smith"}]} From 6e711e888d059ef21c397fe64c97696e4f13b31f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:36:16 -0500 Subject: [PATCH 40/55] chore(beads): update pnt-3zn.6,7,10 descriptions for Quarto context --- .beads/issues.jsonl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index c776184..ba12c23 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -4,13 +4,13 @@ {"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:50:30.680871-05:00"} {"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:51:59.673636-05:00","closed_at":"2026-02-16T22:51:59.673636-05:00","close_reason":"Implemented in f5bf4a4","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.10","title":"Add execution cache and link validation to deploy-docs workflow","description":"Integrate cached-ci-job composite action into the deploy-docs workflow to skip redundant builds when docs content has not changed. Add documentation link validation step (just docs-linkcheck) before deployment. Hash sources should include docs content, setup-nix action, deploy-docs workflow, justfile, and scripts. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:51.835528-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:19.219029-05:00","dependencies":[{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:51.836243-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.287119-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.10","title":"Add execution cache and link validation to deploy-docs workflow","description":"Provisional — requires research before implementation. Integrate cached-ci-job composite action into the deploy-docs workflow to skip redundant builds when docs content has not changed. Hash sources should include docs content, setup-nix action, deploy-docs workflow, justfile, and scripts. Additionally, research whether Quarto has built-in link validation functionality (the reference implementations use Astro Starlight which supports link checking via just docs-linkcheck). If Quarto supports link validation natively or via a plugin, add a validation step before deployment. If no viable link validation exists for Quarto, drop that portion of this issue. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:51.835528-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:10.814615-05:00","dependencies":[{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:51.836243-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.287119-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:56:41.185276-05:00","closed_at":"2026-02-16T22:56:41.185276-05:00","close_reason":"Implemented in f5bf4a4..7d3990f","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, main (worker entry point), compatibility_flags (nodejs_compat, global_fetch_strictly_public), observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Consider relocating from repo root to a docs package directory to match vanixiets (packages/docs/wrangler.jsonc) and typescript-nix-template patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:11.13797-05:00","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:14.748126-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:08.418796-05:00","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:09.44833-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:16.294775-05:00","dependencies":[{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:49.066821-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.6","type":"blocks","created_at":"2026-02-17T09:31:26.460586-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.7","type":"blocks","created_at":"2026-02-17T09:31:26.610437-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:18.112696-05:00","dependencies":[{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:50.157342-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.106011-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} From 6519167c84de9579e442cd1c7595bd2c22c858bc Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:37:22 -0500 Subject: [PATCH 41/55] chore(beads): add local verification requirement to pnt-3zn.7 --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index ba12c23..4897148 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -10,7 +10,7 @@ {"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:08.418796-05:00","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:09.44833-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Verification requirement: before this issue can be closed, the updated recipes must be demonstrated to work locally (at minimum just docs-deploy-preview must successfully build and upload a preview to Cloudflare from a local devshell). This local verification is the proof that the same recipes will work when called from CI/CD in pnt-3zn.8. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:37:16.802891-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:16.294775-05:00","dependencies":[{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:49.066821-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.6","type":"blocks","created_at":"2026-02-17T09:31:26.460586-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.7","type":"blocks","created_at":"2026-02-17T09:31:26.610437-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:18.112696-05:00","dependencies":[{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:50.157342-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.106011-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} From 6020c6def33f19f4801c7817c1f2ddc6b20331f7 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:47:10 -0500 Subject: [PATCH 42/55] feat(deploy): align wrangler.jsonc with Workers static assets best practices --- wrangler.jsonc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wrangler.jsonc b/wrangler.jsonc index 370a3ad..914df22 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -1,9 +1,17 @@ { + "$schema": "node_modules/wrangler/config-schema.json", "name": "python-nix-template", "compatibility_date": "2025-09-09", "assets": { "directory": "docs/_site" }, + "observability": { + "enabled": true + }, + "dev": { + "port": 8787 + }, + "workers_dev": false, "preview_urls": true, "routes": [ { From 749599da093f4ec8663920e2ef81925d66fdaed5 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:49:51 -0500 Subject: [PATCH 43/55] feat(docs): replace deploy recipes with sops-based credential pattern Replace docs-deploy and docs-preview-deploy with docs-deploy-production and docs-deploy-preview that route Cloudflare credentials through sops exec-env. Production deploy checks for existing version by commit tag before falling back to direct deploy. Preview deploy sanitizes branch names and tags versions with commit metadata. Add docs-versions, docs-deployments, and docs-tail utility recipes for Cloudflare Workers observability. --- justfile | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/justfile b/justfile index a150151..1156c3b 100644 --- a/justfile +++ b/justfile @@ -833,15 +833,90 @@ docs-check: docs-dev: docs-build bunx wrangler dev -# Deploy docs +# Deploy documentation to Cloudflare Workers (production) [group('docs')] -docs-deploy: docs-build - bunx wrangler deploy +docs-deploy-production: docs-build + #!/usr/bin/env bash + set -euo pipefail + CURRENT_SHA=$(git rev-parse HEAD) + CURRENT_TAG=$(git rev-parse --short=12 HEAD) + CURRENT_SHORT=$(git rev-parse --short HEAD) + CURRENT_BRANCH=$(git branch --show-current) + if [ -n "${GITHUB_ACTIONS:-}" ]; then + DEPLOYER="${GITHUB_ACTOR:-github-actions}" + DEPLOY_CONTEXT="${GITHUB_WORKFLOW:-CI}" + DEPLOY_MSG="Deployed by ${DEPLOYER} from ${CURRENT_BRANCH} via ${DEPLOY_CONTEXT}" + else + DEPLOYER=$(whoami) + DEPLOY_HOST=$(hostname -s) + DEPLOY_MSG="Deployed by ${DEPLOYER} from ${CURRENT_BRANCH} on ${DEPLOY_HOST}" + fi + echo "Deploying to production from branch: ${CURRENT_BRANCH}" + echo "Current commit: ${CURRENT_SHORT} (${CURRENT_SHA})" + echo "Looking for existing version with tag: ${CURRENT_TAG}" + echo "" + EXISTING_VERSION=$(sops exec-env vars/shared.yaml \ + "bunx wrangler versions list --json" | \ + jq -r --arg tag "$CURRENT_TAG" \ + '.[] | select(.annotations["workers/tag"] == $tag) | .id' | head -1) + if [ -n "$EXISTING_VERSION" ]; then + echo "Found existing version: ${EXISTING_VERSION}" + echo "Promoting to 100% production traffic..." + export DEPLOYMENT_MESSAGE="${DEPLOY_MSG}" + sops exec-env vars/shared.yaml " + bunx wrangler versions deploy ${EXISTING_VERSION}@100% --yes --message \"\$DEPLOYMENT_MESSAGE\" + " + echo "Promoted version ${EXISTING_VERSION} to production" + else + echo "No existing version found, falling back to direct deploy..." + sops exec-env vars/shared.yaml ' + bunx wrangler deploy + ' + echo "Built and deployed to production" + fi + echo "Production URL: https://python-nix-template.scientistexperience.net" + +# Deploy documentation to Cloudflare Workers (preview) +[group('docs')] +docs-deploy-preview branch=`git branch --show-current`: docs-build + #!/usr/bin/env bash + set -euo pipefail + SAFE_BRANCH=$(echo "{{branch}}" | tr '/' '-' | tr -c 'a-zA-Z0-9-' '-' | sed 's/--*/-/g; s/^-//; s/-$//' | cut -c1-40) + COMMIT_TAG=$(git rev-parse --short=12 HEAD) + COMMIT_SHORT=$(git rev-parse --short HEAD) + COMMIT_MSG=$(git log -1 --pretty=format:'%s') + GIT_STATUS=$(git diff-index --quiet HEAD -- && echo "clean" || echo "dirty") + TAG="${COMMIT_TAG}" + MESSAGE="[{{branch}}] ${COMMIT_MSG} (${COMMIT_TAG}, ${GIT_STATUS})" + echo "Deploying preview for branch: {{branch}}" + echo "Sanitized alias: b-${SAFE_BRANCH}" + echo "Commit: ${COMMIT_SHORT} (${GIT_STATUS})" + echo "Tag: ${COMMIT_TAG}" + echo "" + export VERSION_TAG="${TAG}" VERSION_MESSAGE="${MESSAGE}" SAFE_BRANCH="${SAFE_BRANCH}" + sops exec-env vars/shared.yaml ' + bunx wrangler versions upload \ + --tag "$VERSION_TAG" \ + --message "$VERSION_MESSAGE" \ + --preview-alias "b-${SAFE_BRANCH}" + ' + echo "" + echo "Preview uploaded: https://b-${SAFE_BRANCH}-python-nix-template.sciexp.workers.dev" + +# List recent Cloudflare Workers versions +[group('docs')] +docs-versions limit="10": + sops exec-env vars/shared.yaml "bunx wrangler versions list --limit {{limit}}" + +# List recent Cloudflare Workers deployments +[group('docs')] +docs-deployments: + sops exec-env vars/shared.yaml "bunx wrangler deployments list" -# Preview docs on remote +# Tail live logs from Cloudflare Workers [group('docs')] -docs-preview-deploy: data-sync docs-build - bunx wrangler versions upload --preview-alias b-$(git branch --show-current) +docs-tail: + sops exec-env vars/shared.yaml "bunx wrangler tail" # Sync data from drive (using encrypted service account) [group('docs')] From 810efaea3327b1260f3256315ef34d4fcdc4933a Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:50:16 -0500 Subject: [PATCH 44/55] docs: update README recipe listing for renamed deploy recipes --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bffd7b5..d639a0e 100644 --- a/README.md +++ b/README.md @@ -282,13 +282,16 @@ Available recipes: data-sync # Sync data from drive (using encrypted service account) docs-build # Build docs docs-check # Check docs - docs-deploy # Deploy docs + docs-deploy-preview branch=`git branch --show-current` # Deploy documentation to Cloudflare Workers (preview) + docs-deploy-production # Deploy documentation to Cloudflare Workers (production) + docs-deployments # List recent Cloudflare Workers deployments docs-dev # Run local docs deployment docs-extensions # Add quartodoc extension docs-local # Preview docs locally - docs-preview-deploy # Preview docs on remote docs-reference # Build quartodoc API reference docs-sync # Sync docs freeze data to DVC remote + docs-tail # Tail live logs from Cloudflare Workers + docs-versions limit="10" # List recent Cloudflare Workers versions [nix] ci # Run CI checks locally with `om ci` From 3cdafefb68cb3bd220bec90d3a44819076ad6205 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:51:23 -0500 Subject: [PATCH 45/55] fix(docs): remove unsupported --limit flag from docs-versions recipe Wrangler versions list always returns the 10 most recent and does not accept a --limit parameter. --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 1156c3b..1a250e3 100644 --- a/justfile +++ b/justfile @@ -905,8 +905,8 @@ docs-deploy-preview branch=`git branch --show-current`: docs-build # List recent Cloudflare Workers versions [group('docs')] -docs-versions limit="10": - sops exec-env vars/shared.yaml "bunx wrangler versions list --limit {{limit}}" +docs-versions: + sops exec-env vars/shared.yaml "bunx wrangler versions list" # List recent Cloudflare Workers deployments [group('docs')] From 73a3fa43ca0280844eeff3ae3d1d2487a1161b9f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:51:34 -0500 Subject: [PATCH 46/55] fixup! docs: update README recipe listing for renamed deploy recipes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d639a0e..78c10b0 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ Available recipes: docs-reference # Build quartodoc API reference docs-sync # Sync docs freeze data to DVC remote docs-tail # Tail live logs from Cloudflare Workers - docs-versions limit="10" # List recent Cloudflare Workers versions + docs-versions # List recent Cloudflare Workers versions [nix] ci # Run CI checks locally with `om ci` From 0a291d9c9a2a38b19c3fa98ae9a19e2452c3f4c5 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 09:52:58 -0500 Subject: [PATCH 47/55] chore(beads): close pnt-3zn.6 and pnt-3zn.7 --- .beads/issues.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 4897148..664f524 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -9,8 +9,8 @@ {"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:08.418796-05:00","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Verification requirement: before this issue can be closed, the updated recipes must be demonstrated to work locally (at minimum just docs-deploy-preview must successfully build and upload a preview to Cloudflare from a local devshell). This local verification is the proof that the same recipes will work when called from CI/CD in pnt-3zn.8. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:37:16.802891-05:00","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:47:44.868798-05:00","closed_at":"2026-02-17T09:47:44.868798-05:00","close_reason":"Implemented in 6020c6d","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Verification requirement: before this issue can be closed, the updated recipes must be demonstrated to work locally (at minimum just docs-deploy-preview must successfully build and upload a preview to Cloudflare from a local devshell). This local verification is the proof that the same recipes will work when called from CI/CD in pnt-3zn.8. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:52:51.41033-05:00","closed_at":"2026-02-17T09:52:51.41033-05:00","close_reason":"Implemented in 6020c6d..73a3fa4. Sops credential path verified locally: docs-versions and docs-deployments both query Cloudflare API successfully.","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:16.294775-05:00","dependencies":[{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:49.066821-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.6","type":"blocks","created_at":"2026-02-17T09:31:26.460586-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.7","type":"blocks","created_at":"2026-02-17T09:31:26.610437-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:18.112696-05:00","dependencies":[{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:50.157342-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.106011-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} From 705484b02bfcf1068399c358152c74b7fa47ff9c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:06:52 -0500 Subject: [PATCH 48/55] fix(docs): align deploy recipe output and error handling with reference implementations --- justfile | 59 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/justfile b/justfile index 1a250e3..14813a4 100644 --- a/justfile +++ b/justfile @@ -852,8 +852,10 @@ docs-deploy-production: docs-build DEPLOY_MSG="Deployed by ${DEPLOYER} from ${CURRENT_BRANCH} on ${DEPLOY_HOST}" fi echo "Deploying to production from branch: ${CURRENT_BRANCH}" - echo "Current commit: ${CURRENT_SHORT} (${CURRENT_SHA})" + echo "Current commit: ${CURRENT_SHORT}" + echo "Full SHA: ${CURRENT_SHA}" echo "Looking for existing version with tag: ${CURRENT_TAG}" + echo "Deployment message: ${DEPLOY_MSG}" echo "" EXISTING_VERSION=$(sops exec-env vars/shared.yaml \ "bunx wrangler versions list --json" | \ @@ -861,20 +863,48 @@ docs-deploy-production: docs-build '.[] | select(.annotations["workers/tag"] == $tag) | .id' | head -1) if [ -n "$EXISTING_VERSION" ]; then echo "Found existing version: ${EXISTING_VERSION}" - echo "Promoting to 100% production traffic..." + echo " This version was already built and tested in preview" + echo " Promoting to 100% production traffic..." + echo "" export DEPLOYMENT_MESSAGE="${DEPLOY_MSG}" - sops exec-env vars/shared.yaml " + if sops exec-env vars/shared.yaml " bunx wrangler versions deploy ${EXISTING_VERSION}@100% --yes --message \"\$DEPLOYMENT_MESSAGE\" - " - echo "Promoted version ${EXISTING_VERSION} to production" + "; then + echo "" + echo "Successfully promoted version ${EXISTING_VERSION} to production" + echo " Tag: ${CURRENT_TAG}" + echo " Full SHA: ${CURRENT_SHA}" + echo " Deployed by: ${DEPLOY_MSG}" + echo " Production URL: https://python-nix-template.scientistexperience.net" + else + echo "" + echo "Failed to promote version ${EXISTING_VERSION}" + echo " Deployment was cancelled or failed" + exit 1 + fi else - echo "No existing version found, falling back to direct deploy..." - sops exec-env vars/shared.yaml ' + echo "No existing version found with tag: ${CURRENT_TAG}" + echo " This should only happen if:" + echo " - This is the first deployment" + echo " - Commit was made directly on main (not recommended)" + echo " - Version was cleaned up (retention policy)" + echo "" + echo " Falling back to direct build and deploy..." + echo "" + if sops exec-env vars/shared.yaml ' bunx wrangler deploy - ' - echo "Built and deployed to production" + '; then + echo "" + echo "Built and deployed to production" + echo " Full SHA: ${CURRENT_SHA}" + echo " Deployed by: ${DEPLOY_MSG}" + echo " Production URL: https://python-nix-template.scientistexperience.net" + else + echo "" + echo "Failed to build and deploy" + exit 1 + fi fi - echo "Production URL: https://python-nix-template.scientistexperience.net" # Deploy documentation to Cloudflare Workers (preview) [group('docs')] @@ -882,6 +912,7 @@ docs-deploy-preview branch=`git branch --show-current`: docs-build #!/usr/bin/env bash set -euo pipefail SAFE_BRANCH=$(echo "{{branch}}" | tr '/' '-' | tr -c 'a-zA-Z0-9-' '-' | sed 's/--*/-/g; s/^-//; s/-$//' | cut -c1-40) + COMMIT_SHA=$(git rev-parse HEAD) COMMIT_TAG=$(git rev-parse --short=12 HEAD) COMMIT_SHORT=$(git rev-parse --short HEAD) COMMIT_MSG=$(git log -1 --pretty=format:'%s') @@ -891,7 +922,9 @@ docs-deploy-preview branch=`git branch --show-current`: docs-build echo "Deploying preview for branch: {{branch}}" echo "Sanitized alias: b-${SAFE_BRANCH}" echo "Commit: ${COMMIT_SHORT} (${GIT_STATUS})" + echo "Full SHA: ${COMMIT_SHA}" echo "Tag: ${COMMIT_TAG}" + echo "Message: ${COMMIT_MSG}" echo "" export VERSION_TAG="${TAG}" VERSION_MESSAGE="${MESSAGE}" SAFE_BRANCH="${SAFE_BRANCH}" sops exec-env vars/shared.yaml ' @@ -901,7 +934,11 @@ docs-deploy-preview branch=`git branch --show-current`: docs-build --preview-alias "b-${SAFE_BRANCH}" ' echo "" - echo "Preview uploaded: https://b-${SAFE_BRANCH}-python-nix-template.sciexp.workers.dev" + echo "Version uploaded successfully" + echo " Tag: ${COMMIT_TAG}" + echo " Full SHA: ${COMMIT_SHA}" + echo " Message: ${MESSAGE}" + echo " Preview URL: https://b-${SAFE_BRANCH}-python-nix-template.sciexp.workers.dev" # List recent Cloudflare Workers versions [group('docs')] From 4089daadb17760417caff500bf7515a4bda3f11c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:13:03 -0500 Subject: [PATCH 49/55] refactor(ci): restructure deploy-docs to single-job direct deploy via justfile --- .github/workflows/deploy-docs.yaml | 96 ++++++++++++++---------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index 0a52550..ed6e1b6 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -5,23 +5,54 @@ on: inputs: debug_enabled: description: "Run with tmate.io debugging enabled" - required: true + required: false type: string default: "false" branch: description: "Git branch or ref to checkout" required: true type: string + sanitized_branch: + description: "URL-safe branch name for preview alias (auto-computed if empty)" + required: false + type: string + default: "" + environment: + description: "Deployment environment (preview or production)" + required: false + type: string + default: "preview" + force_run: + description: "Force execution even if already successful" + required: false + type: string + default: "false" workflow_call: inputs: debug_enabled: description: "Run with tmate.io debugging enabled" + required: false type: string default: "false" branch: description: "Git branch or ref to checkout" required: true type: string + sanitized_branch: + description: "URL-safe branch name for preview alias (auto-computed if empty)" + required: false + type: string + default: "" + environment: + description: "Deployment environment (preview or production)" + required: false + type: string + default: "production" + force_run: + description: "Force execution even if already successful" + required: false + type: string + default: "false" defaults: run: @@ -32,8 +63,14 @@ permissions: deployments: write jobs: - build-docs: + deploy-docs: runs-on: ubuntu-latest + environment: + name: ${{ inputs.environment }} + url: ${{ inputs.environment == 'preview' && format('https://b-{0}-python-nix-template.sciexp.workers.dev', inputs.sanitized_branch || inputs.branch) || 'https://python-nix-template.scientistexperience.net' }} + permissions: + contents: read + deployments: write steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -43,62 +80,19 @@ jobs: - name: Setup Nix uses: ./.github/actions/setup-nix with: + installer: quick system: x86_64-linux - enable-cachix: true - cachix-name: ${{ vars.CACHIX_CACHE_NAME }} - cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: Setup tmate debug session + if: inputs.debug_enabled == 'true' uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3 - if: ${{ inputs.debug_enabled == 'true' }} - - name: Build docs + - name: Deploy docs env: SOPS_AGE_KEY: ${{ secrets.CI_AGE_KEY }} run: | - df -h - nix develop --accept-flake-config -c just docs-build - df -h - - - name: Upload docs - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 - with: - name: docs-site - path: | - docs/_site - wrangler.jsonc - - deploy-docs: - needs: build-docs - runs-on: ubuntu-latest - steps: - - name: Download docs - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 - with: - name: docs-site - - - name: Site artifact tree - run: | - if command -v tree &> /dev/null; then - tree --du -alh + if [ "${{ inputs.environment }}" = "preview" ]; then + nix develop --accept-flake-config -c just docs-deploy-preview "${{ inputs.sanitized_branch || inputs.branch }}" else - echo "tree command not found, skipping file tree display" + nix develop --accept-flake-config -c just docs-deploy-production fi - - - name: Deploy preview - id: deployment - uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # ratchet:cloudflare/wrangler-action@v3 - with: - wranglerVersion: "4.37.1" - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: versions upload --preview-alias b-${{ inputs.branch }} - gitHubToken: ${{ secrets.GITHUB_TOKEN }} - - - name: Preview rollout command - env: - WRANGLER_OUTPUT: ${{ steps.deployment.outputs.command-output }} - run: | - WRANGLER_VERSION_ID=$(echo "$WRANGLER_OUTPUT" | grep -oP 'Version ID: \K[a-f0-9-]+') - echo "WRANGLER_VERSION_ID=$WRANGLER_VERSION_ID" - echo "bunx wrangler versions deploy ${WRANGLER_VERSION_ID}@100 --yes --dry-run" From 5880c8ea2a1431270027ceb35d178fe54b1ca423 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:15:26 -0500 Subject: [PATCH 50/55] feat(ci): add sanitized_branch computation to set-variables job Compute a URL-safe branch name for Cloudflare preview alias subdomains, matching the sanitization logic used by the justfile and reference templates. --- .github/workflows/ci.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5ad55d6..838f673 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -98,6 +98,7 @@ jobs: checkout_ref: ${{ steps.set-variables.outputs.checkout_ref }} checkout_rev: ${{ steps.set-variables.outputs.checkout_rev }} has_docs: ${{ steps.check-docs.outputs.has_docs }} + sanitized_branch: ${{ steps.set-variables.outputs.sanitized_branch }} packages: ${{ steps.discover-packages.outputs.packages }} force_ci: ${{ steps.set-variables.outputs.force_ci }} @@ -161,6 +162,12 @@ jobs: CHECKOUT_REV="${{ github.sha }}" fi + # Sanitize branch name for Cloudflare preview alias (must be valid subdomain component) + # - Replace / and other non-alphanumeric chars with - + # - Collapse consecutive hyphens, remove leading/trailing hyphens + # - Truncate to 40 chars (safe for subdomain label limit of 63) + SANITIZED_BRANCH=$(echo "$CHECKOUT_REF" | tr '/' '-' | tr -c 'a-zA-Z0-9-' '-' | sed 's/--*/-/g; s/^-//; s/-$//' | cut -c1-40) + { echo "debug=$DEBUG" echo "skip_ci=$SKIP_CI" @@ -168,6 +175,7 @@ jobs: echo "dry_run_release=$DRY_RUN_RELEASE" echo "checkout_ref=$CHECKOUT_REF" echo "checkout_rev=$CHECKOUT_REV" + echo "sanitized_branch=$SANITIZED_BRANCH" echo "force_ci=$FORCE_CI" } >> "$GITHUB_OUTPUT" From f0e96e2ff5352528f9e00f27cb9e96818f5cfbf9 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:15:47 -0500 Subject: [PATCH 51/55] feat(ci): pass deploy-docs inputs from preview-docs-deploy caller Rename preview-docs to preview-docs-deploy and pass sanitized_branch, environment, and force_run inputs to the deploy-docs reusable workflow. --- .github/workflows/ci.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 838f673..2795b49 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -557,10 +557,10 @@ jobs: key: ${{ steps.cache.outputs.cache-key }} # --------------------------------------------------------------------------- - # job 8: preview-docs + # job 8: preview-docs-deploy # deploy docs to preview environment (PR only) # --------------------------------------------------------------------------- - preview-docs: + preview-docs-deploy: needs: set-variables if: ${{ needs.set-variables.outputs.has_docs == 'true' && needs.set-variables.outputs.skip_ci != 'true' && ( contains(github.event.pull_request.labels.*.name, 'docs-preview') || (github.event_name == 'workflow_dispatch' && inputs.run_docs_preview) ) }} uses: ./.github/workflows/deploy-docs.yaml @@ -573,6 +573,9 @@ jobs: with: debug_enabled: ${{ needs.set-variables.outputs.debug }} branch: ${{ needs.set-variables.outputs.checkout_ref }} + sanitized_branch: ${{ needs.set-variables.outputs.sanitized_branch }} + environment: preview + force_run: ${{ needs.set-variables.outputs.force_ci }} secrets: inherit # --------------------------------------------------------------------------- From 5bc8c88525978e5d8760633c84281720cbc42ba2 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:16:11 -0500 Subject: [PATCH 52/55] feat(ci): pass deploy-docs inputs from production-docs-deploy caller Rename deploy-docs to production-docs-deploy and pass sanitized_branch, environment, and force_run inputs. Use set-variables outputs for debug and branch instead of hardcoded values for consistency. --- .github/workflows/ci.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2795b49..b908e6c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -635,10 +635,10 @@ jobs: secrets: inherit # --------------------------------------------------------------------------- - # job 11: deploy-docs + # job 11: production-docs-deploy # production docs deployment on push to main/beta # --------------------------------------------------------------------------- - deploy-docs: + production-docs-deploy: needs: [set-variables, test-python, nix] if: ${{ needs.set-variables.outputs.has_docs == 'true' && github.repository_owner == 'sciexp' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/beta') }} uses: ./.github/workflows/deploy-docs.yaml @@ -646,11 +646,14 @@ jobs: contents: read deployments: write concurrency: - group: deploy-docs-${{ github.workflow }}-${{ github.ref_name }} + group: production-docs-deploy-${{ github.workflow }}-${{ github.ref_name }} cancel-in-progress: true with: - debug_enabled: "false" - branch: ${{ github.ref_name }} + debug_enabled: ${{ needs.set-variables.outputs.debug }} + branch: ${{ needs.set-variables.outputs.checkout_ref }} + sanitized_branch: ${{ needs.set-variables.outputs.sanitized_branch }} + environment: production + force_run: ${{ needs.set-variables.outputs.force_ci }} secrets: inherit # --------------------------------------------------------------------------- From 921378cde614c97d39dc3f34821df66df5ef2f13 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 10:17:37 -0500 Subject: [PATCH 53/55] feat(ci): add execution cache to deploy-docs workflow Integrate cached-ci-job composite action to skip redundant deployments when docs content, setup-nix action, workflow file, and justfile are unchanged. Gate all steps on cache decision and persist job result markers via actions/cache for subsequent runs. --- .github/workflows/deploy-docs.yaml | 37 +++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-docs.yaml b/.github/workflows/deploy-docs.yaml index ed6e1b6..0df42d7 100644 --- a/.github/workflows/deploy-docs.yaml +++ b/.github/workflows/deploy-docs.yaml @@ -76,18 +76,29 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: ref: ${{ inputs.branch }} + fetch-depth: 0 # for git diff in composite action + + - name: Check execution cache + id: cache + uses: ./.github/actions/cached-ci-job + with: + check-name: preview-docs-deploy + hash-sources: 'docs/**/* .github/actions/setup-nix/action.yml .github/workflows/deploy-docs.yaml justfile' + force-run: ${{ inputs.force_run }} - name: Setup Nix + if: steps.cache.outputs.should-run == 'true' uses: ./.github/actions/setup-nix with: installer: quick system: x86_64-linux - name: Setup tmate debug session - if: inputs.debug_enabled == 'true' + if: inputs.debug_enabled == 'true' && steps.cache.outputs.should-run == 'true' uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3 - name: Deploy docs + if: steps.cache.outputs.should-run == 'true' env: SOPS_AGE_KEY: ${{ secrets.CI_AGE_KEY }} run: | @@ -96,3 +107,27 @@ jobs: else nix develop --accept-flake-config -c just docs-deploy-production fi + + - name: Create job result marker + if: success() && steps.cache.outputs.should-run == 'true' && steps.cache.outputs.cache-source == 'none' + shell: bash + run: | + mkdir -p "${{ steps.cache.outputs.cache-path }}" + cat > "${{ steps.cache.outputs.cache-path }}/marker" < Date: Tue, 17 Feb 2026 10:19:02 -0500 Subject: [PATCH 54/55] chore(beads): close pnt-3zn.8-10, epic 10/10 complete --- .beads/issues.jsonl | 144 ++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 664f524..298d206 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,72 +1,72 @@ -{"id":"pnt-1q5","title":"Switch nixpkgs URL to optimized channel tarball format","description":"Current nixpkgs input uses github:NixOS/nixpkgs/nixos-unstable (GitHub archive format). Vanixiets uses https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz (channel tarball), which is smaller, faster to fetch, and avoids GitHub rate limiting.\n\nAdopt the tarball URL pattern from vanixiets for the primary nixpkgs input.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:35.584808-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:05:10.871297-05:00","closed_at":"2026-02-03T18:05:10.871297-05:00","close_reason":"Implemented in 293d46d","dependencies":[{"issue_id":"pnt-1q5","depends_on_id":"pnt-h2q","type":"related","created_at":"2026-02-03T15:48:45.065971-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3bd","title":"Add crane.inputs.nixpkgs.follows and align cache declarations with vanixiets","description":"Two related flake hygiene items:\n\n1. crane input has no follows directive, causing a redundant independent nixpkgs evaluation. Since crane is a build library with no upstream cache, adding inputs.nixpkgs.follows = nixpkgs eliminates the extra eval with no cache downside.\n\n2. Cache declarations are minimal (3 substituters) compared to vanixiets (9). Add cache.nixos.org explicitly, numtide.cachix.org, and cameronraysmith.cachix.org to nixConfig.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:33.582737-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:49.646325-05:00","closed_at":"2026-02-03T18:04:49.646325-05:00","close_reason":"Implemented in e3a9997, added crane/numtide/cache.nixos.org caches","dependencies":[{"issue_id":"pnt-3bd","depends_on_id":"pnt-h2q","type":"related","created_at":"2026-02-03T15:48:44.907425-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3jf","title":"Validate sciexp/data platform instantiation","description":"Final validation gate before v0.2.0 release. Instantiate template to create the sciexp data platform repository.\n\nTarget: ~/projects/sciexp/data\n\nValidation steps:\n- Instantiate template with configuration for omicsio, scilake, scimesh package structure\n- Verify independent locks work for each package\n- Verify Nix builds succeed for all packages\n- Verify CI patterns work correctly\n- Document any issues found and fix if minor, or create follow-up issues if significant\n\nThis issue is blocked by the other four polish issues. Successful completion means we are ready to manually create the v0.2.0 release tag.\n\nReference: ~/projects/sciexp/planning/contexts/sciexp-data-platform.md for sciexp/data requirements\n\nScope: ~3 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:48:01.905707-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:14:16.459237-05:00","closed_at":"2026-02-05T15:14:16.459237-05:00","close_reason":"Validated: template evaluation, test infrastructure (11/11 tests pass across 3 packages), and instantiation workflow confirmed working. Welcome text and README are consistent. 619014b","dependencies":[{"issue_id":"pnt-3jf","depends_on_id":"pnt-6yk","type":"blocks","created_at":"2026-02-05T13:48:10.890329-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-5wx","type":"blocks","created_at":"2026-02-05T13:48:11.058701-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-m7j","type":"blocks","created_at":"2026-02-05T13:48:11.23594-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3jf","depends_on_id":"pnt-bxq","type":"blocks","created_at":"2026-02-05T13:48:11.38108-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","dependencies":[{"issue_id":"pnt-3qp","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:20:20.918483-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3qp","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:20:21.103095-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:50:30.680871-05:00"} -{"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:51:59.673636-05:00","closed_at":"2026-02-16T22:51:59.673636-05:00","close_reason":"Implemented in f5bf4a4","dependencies":[{"issue_id":"pnt-3zn.1","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:02.79261-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.10","title":"Add execution cache and link validation to deploy-docs workflow","description":"Provisional — requires research before implementation. Integrate cached-ci-job composite action into the deploy-docs workflow to skip redundant builds when docs content has not changed. Hash sources should include docs content, setup-nix action, deploy-docs workflow, justfile, and scripts. Additionally, research whether Quarto has built-in link validation functionality (the reference implementations use Astro Starlight which supports link checking via just docs-linkcheck). If Quarto supports link validation natively or via a plugin, add a validation step before deployment. If no viable link validation exists for Quarto, drop that portion of this issue. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:51.835528-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:36:10.814615-05:00","dependencies":[{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:51.836243-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.10","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.287119-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:56:41.185276-05:00","closed_at":"2026-02-16T22:56:41.185276-05:00","close_reason":"Implemented in f5bf4a4..7d3990f","dependencies":[{"issue_id":"pnt-3zn.2","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:03.823779-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","dependencies":[{"issue_id":"pnt-3zn.3","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:04.893864-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","dependencies":[{"issue_id":"pnt-3zn.4","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:07.238745-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","dependencies":[{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-16T22:37:08.330069-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.5","depends_on_id":"pnt-3zn.4","type":"blocks","created_at":"2026-02-16T22:37:14.424629-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:47:44.868798-05:00","closed_at":"2026-02-17T09:47:44.868798-05:00","close_reason":"Implemented in 6020c6d","dependencies":[{"issue_id":"pnt-3zn.6","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:46.77587-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Verification requirement: before this issue can be closed, the updated recipes must be demonstrated to work locally (at minimum just docs-deploy-preview must successfully build and upload a preview to Cloudflare from a local devshell). This local verification is the proof that the same recipes will work when called from CI/CD in pnt-3zn.8. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:52:51.41033-05:00","closed_at":"2026-02-17T09:52:51.41033-05:00","close_reason":"Implemented in 6020c6d..73a3fa4. Sops credential path verified locally: docs-versions and docs-deployments both query Cloudflare API successfully.","dependencies":[{"issue_id":"pnt-3zn.7","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:47.937024-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:16.294775-05:00","dependencies":[{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:49.066821-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.6","type":"blocks","created_at":"2026-02-17T09:31:26.460586-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.8","depends_on_id":"pnt-3zn.7","type":"blocks","created_at":"2026-02-17T09:31:26.610437-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:31:18.112696-05:00","dependencies":[{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn","type":"parent-child","created_at":"2026-02-17T09:30:50.157342-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-3zn.9","depends_on_id":"pnt-3zn.8","type":"blocks","created_at":"2026-02-17T09:31:28.106011-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete."} -{"id":"pnt-4jg.1","title":"Remove uv workspace, adopt path dependencies","description":"Remove [tool.uv.workspace] from root pyproject.toml. Each package gets own pyproject.toml with [tool.uv.sources] for sibling references using path sources with editable=true. Follow langchain pattern.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:07.344057-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T14:40:02.175394-05:00","closed_at":"2026-02-02T14:40:02.175394-05:00","close_reason":"Implemented in a8a823f. Removed root uv workspace, generated per-package locks, rewrote nix modules to Pattern 3 per-package loading.","dependencies":[{"issue_id":"pnt-4jg.1","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:07.344659-05:00","created_by":"Cameron Smith"}],"comments":[{"id":1,"issue_id":"pnt-4jg.1","author":"Cameron Smith","text":"Post-close fixup commits (774ec26):\n- fix(ci): update lock file references for per-package federation (d0cab2a)\n- fixup! merge federated workspace deps: replace // with zipAttrsWith for extras-safe dep merging (7b3e7ae)\n- fixup! load packages independently: document version-conflict invariant in python.nix and architecture doc (36eb8a7, 774ec26)\n\nReview findings addressed: stale CI cache-dependency-glob paths, fragile shallow-merge dep specs, undocumented overlay composition invariant. Full CI redesign (nix develop + justfile symmetry) deferred to pnt-dre.4.","created_at":"2026-02-02T20:17:00Z"}]} -{"id":"pnt-4jg.2","title":"Configure pixi feature-based composition","description":"Implement pixi feature/environment pattern: [feature.X.dependencies] + [environments] composition. Single pixi.lock covering all environments. Per-feature task definitions. Target-specific dependencies for platform support.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:08.085592-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:36:49.459815-05:00","closed_at":"2026-02-02T15:36:49.459815-05:00","close_reason":"Verified pixi feature composition via nix develop -c just \u003crecipe\u003e. Fixed: added missing feature tasks to python-nix-template, delegated justfile conda recipes to pixi task names for correct working directory, moved deprecated build channels to backend.channels.","dependencies":[{"issue_id":"pnt-4jg.2","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:08.086155-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4jg.3","title":"Document package distribution channels","description":"Document which packages support uv/pypi vs pixi/conda distribution. Note dependency graph differences between channels. Update README and package metadata.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:09.051203-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:38.374454-05:00","closed_at":"2026-02-02T15:37:38.374454-05:00","close_reason":"Documented in docs/notes/architecture/package-distribution-channels.md. Both packages support dual-channel (uv/PyPI + pixi/conda-forge) with independent locks. No blocking dependency graph differences between channels.","dependencies":[{"issue_id":"pnt-4jg.3","depends_on_id":"pnt-4jg","type":"parent-child","created_at":"2026-01-19T11:55:09.051857-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4jg.3","depends_on_id":"pnt-4jg.1","type":"blocks","created_at":"2026-01-19T12:20:13.557576-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4jg.3","depends_on_id":"pnt-4jg.2","type":"blocks","created_at":"2026-01-19T12:20:16.147971-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us","title":"Template v0.2.0 Release Polish","description":"Final polish and validation before v0.2.0 release. Prove template is production-ready for sciexp data platform instantiation and general use. Completing this epic enables the manual v0.2.0 tag creation.","status":"closed","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:40.344366-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:19:46.382817-05:00","closed_at":"2026-02-05T19:19:46.382817-05:00","close_reason":"All children closed. Template v0.2.0 release polish complete. af7b303","dependencies":[{"issue_id":"pnt-4us","depends_on_id":"pnt-6yk","type":"parent-of","created_at":"2026-02-05T13:48:06.692349-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us","depends_on_id":"pnt-5wx","type":"parent-of","created_at":"2026-02-05T13:48:06.867893-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us","depends_on_id":"pnt-m7j","type":"parent-of","created_at":"2026-02-05T13:48:07.04595-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us","depends_on_id":"pnt-bxq","type":"parent-of","created_at":"2026-02-05T13:48:07.225269-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us","depends_on_id":"pnt-3jf","type":"parent-of","created_at":"2026-02-05T13:48:07.399917-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.1","title":"Add pyo3-package template param to modules/template.nix","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.550401-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:07:22.809551-05:00","closed_at":"2026-02-05T19:07:22.809551-05:00","close_reason":"Implemented in 6fcdac4","dependencies":[{"issue_id":"pnt-4us.1","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:47.551113-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.2","title":"Add hasCli conditional guards to modules/python.nix","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.707539-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:08:24.466211-05:00","closed_at":"2026-02-05T19:08:24.466211-05:00","close_reason":"Implemented in be7c6d0","dependencies":[{"issue_id":"pnt-4us.2","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:47.708146-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.3","title":"Add hasCli conditional guard to modules/containers.nix","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.867613-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:09:29.970634-05:00","closed_at":"2026-02-05T19:09:29.970634-05:00","close_reason":"Implemented in b794759 (parallel session)","dependencies":[{"issue_id":"pnt-4us.3","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:47.868421-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.4","title":"Gate Rust tooling in modules/devshell.nix behind hasCli","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.01078-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:10:01.017053-05:00","closed_at":"2026-02-05T19:10:01.017053-05:00","close_reason":"Implemented in 40591c5","dependencies":[{"issue_id":"pnt-4us.4","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:48.011346-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.5","title":"Dynamize release-packages matrix in ci.yaml","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.170487-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:09:23.768755-05:00","closed_at":"2026-02-05T19:09:23.768755-05:00","close_reason":"Implemented in b794759","dependencies":[{"issue_id":"pnt-4us.5","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:48.171131-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-4us.6","title":"Verify template instantiation with pyo3-package false","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.309753-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:19:46.210854-05:00","closed_at":"2026-02-05T19:19:46.210854-05:00","close_reason":"Verified: both monorepo (pyo3:true) and single-package (pyo3:false) instantiations pass. af7b303","dependencies":[{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us","type":"parent-child","created_at":"2026-02-05T19:05:48.310354-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us.1","type":"blocks","created_at":"2026-02-05T19:05:54.190532-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us.2","type":"blocks","created_at":"2026-02-05T19:05:54.348835-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us.3","type":"blocks","created_at":"2026-02-05T19:05:54.497258-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us.4","type":"blocks","created_at":"2026-02-05T19:05:54.64941-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-4us.6","depends_on_id":"pnt-4us.5","type":"blocks","created_at":"2026-02-05T19:05:54.797078-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-5vr","title":"Add production containers via nix2container and replace flocken tooling","description":"Add lightweight production/execution container images using nix2container (vanixiets pattern) and replace flocken manifest tooling. This does NOT touch nixpod-based dev containers.\n\nProduction containers (new):\n- nix2container.buildImage for minimal per-package execution images\n- Each user-facing package gets a container with only its runtime closure\n- pkgsCross for cross-compilation (eliminates QEMU dependency)\n- Per-container layer strategy: base layer (bash, coreutils) + app layer\n\nFlocken replacement (affects all containers):\n- crane-based mkMultiArchManifest replacing flocken mkDockerManifest\n- skopeo-nix2container with nix: transport for pushing\n- containerMatrix flake output for CI matrix generation (pure nix evaluation)\n- build-nix-images.yaml updated for nix2container workflow\n\nDoes NOT include:\n- Dev container migration (see pnt-xxx blocked issue)\n- Changes to buildMultiUserNixImage or nixpod integration\n- Existing dev container content or architecture\n\nReference: ~/projects/nix-workspace/vanixiets/modules/containers/default.nix\nReference: ~/projects/nix-workspace/vanixiets/lib/mk-multi-arch-manifest.nix\n\nAcceptance criteria:\n- nix2container flake input added\n- At least one production container defined via nix2container.buildImage\n- pkgsCross used for cross-compilation targets\n- lib/mk-multi-arch-manifest.nix ported from vanixiets\n- containerMatrix flake output for CI matrix generation\n- flocken replaced by crane-based manifests for production containers\n- Existing dev containers still build and work (no regression)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T20:24:12.624117-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T00:32:32.102656-05:00","closed_at":"2026-02-03T00:32:32.102656-05:00","close_reason":"Implemented in c760bd1. PR #44.","comments":[{"id":3,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02\n\nDone:\n- Researched vanixiets nix2container patterns (containers/default.nix, mk-multi-arch-manifest.nix, containers.yaml workflow)\n- Researched current pnt container infrastructure (containers.nix, build-nix-image action, build-nix-images workflow)\n- Identified scope mismatch between vanixiets lightweight tool containers and pnt dev containers\n- Rescoped to production containers + flocken replacement only (dev containers deferred to pnt-mgq)\n\nRemaining:\n- Add nix2container flake input\n- Create lib/mk-multi-arch-manifest.nix (port from vanixiets)\n- Define at least one production container via nix2container.buildImage (pnt-cli is the natural candidate)\n- Add pkgsCross targets and containerMatrix flake output\n- Replace flocken manifest tooling for existing dev containers (crane-based manifests)\n- Update build-nix-images.yaml workflow\n- Update build-nix-image composite action (QEMU no longer needed for production containers)\n- Add justfile recipes for container build/push (local/CI symmetry)\n\nContext for next agent:\n- vanixiets reference files are fully analyzed, see subagent outputs in this session\n- setup-nix action is already deployed on this branch stack (pnt-m3t-setup-nix merged into branch)\n- build-nix-image action already had redundant Nix install removed\n- Branch is pnt-5vr-nix2container, branched off pnt-m3t-setup-nix tip\n- Dev containers MUST NOT be touched — only production containers and manifest tooling","created_at":"2026-02-03T02:52:29Z"},{"id":4,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02 (continued)\n\nCompleted:\n- Added nix2container flake input, removed flocken as direct input\n- Created nix/lib/mk-multi-arch-manifest.nix (ported from vanixiets, generalized with mkSourceUri for mixed transport)\n- Added minimal CLI entrypoint to pnt-cli (main() exercising pyo3 greet/add bindings)\n- Defined pnt-cli production container via nix2container.buildImage with 2-layer strategy\n- Replaced flocken manifests with crane-based manifests for all containers (production: nix: transport, dev: docker-archive: transport)\n- Added containerMatrix flake output for CI matrix generation\n- Refactored build-nix-images.yaml to 3-job pattern (discover/build/manifest)\n- Removed obsolete build-nix-image composite action\n- Updated ci.yaml and package-release.yaml callers\n- Added justfile container recipes (build/load/push for production and dev, matrix display)\n\nKnown limitations:\n- Production containers built natively per-system (not pkgsCross) due to Python + maturin + Cargo cross-compilation complexity\n- docker-archive: transport for dev container manifests not yet tested against crane index append (may need validation)\n- Dev containers in CI still limited to x86_64-linux only (NIX_IMAGE_SYSTEMS override)\n\nRemaining for verification:\n- Linux builder needed to test actual container image builds (nix build .#pnt-cliProductionImage)\n- CI workflow run to validate end-to-end (discover -\u003e build -\u003e manifest push)\n- Verify docker-archive: transport works with skopeo + crane manifest list creation","created_at":"2026-02-03T03:52:51Z"},{"id":5,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02 (CI refactoring)\n\nDone:\n- Fixed template test failure: added [project] and [tool.uv.workspace] to root pyproject.toml\n- Simplified template.yaml: replaced GitGuardian with setup-nix action, removed scan/set-variables jobs\n- Created scripts/ci/ci-build-category.sh for category-based matrix builds\n- Added justfile recipes: ci-build-category, scan-secrets, scan-staged, preview-version, release-package\n- Added gitleaks to devshell for local/CI parity\n- Refactored ci.yaml: replaced omnix/nixci with 3-entry category matrix (packages, checks, devshells), replaced GitGuardian with gitleaks via nix develop, added flake-validation and bootstrap-verification jobs, added preview-release-version job, reduced top-level permissions to contents:read\n- Refactored package-release.yaml: replaced setup-uv and setup-yarn actions with nix develop via setup-nix, added cached-ci-job support, fixed artifact upload path\n- Fixed permissions chain: build-nix-images.yaml needs packages:write from callers, added to build-pr-images and test-release-packages\n\nRemaining:\n- CI run verification: latest push (4bc84a3) should resolve startup_failure from permissions chain. Need to verify CI passes end-to-end.\n- Iterative fixes: if nix category builds or test-release-packages fail at runtime, diagnose from logs and fix\n- Close pnt-5vr once CI confirmed working\n- Container workflow 3-job pattern (discover -\u003e build -\u003e manifest) not yet tested in CI\n\nContext for next agent:\n- Branch is pnt-5vr-nix2container with PR #44\n- The CI architecture now matches vanixiets/typescript-nix-template patterns\n- Three parallel startup_failures were caused by permissions chain issues (build-nix-images.yaml declares packages:write at workflow level, GitHub validates entire call chain at parse time)\n- run 21617100530 was from an intermediate push before the full refactoring landed\n- The secrets-scan job uses nix develop -c just scan-secrets (gitleaks is in devshell)\n- The nix job uses a static 3-entry matrix calling just ci-build-category\n- package-release.yaml now uses nix develop for all tool access (yarn, uv)\n- To check CI: gh run list --workflow \"CI/CD\" --limit 3 --repo sciexp/python-nix-template\n- To download logs: gh api \"repos/sciexp/python-nix-template/actions/runs/\u003cid\u003e/logs\" \u003e logs.zip","created_at":"2026-02-03T04:45:03Z"}]} -{"id":"pnt-5wx","title":"Add rust-toolchain.toml for explicit Rust version","description":"Add explicit rust-toolchain.toml to provide Rust version specification outside of Nix context.\n\nReference: ~/projects/rust-workspace/ironstar/rust-toolchain.toml\n\nImplementation:\n- Create rust-toolchain.toml with channel matching flake.nix Rust version\n- Include components: rustfmt, clippy, rust-analyzer, rust-src\n- Verify version consistency with flake.nix Rust specification\n\nThis helps IDEs and standalone Rust tools work correctly without requiring Nix.\n\nScope: ~15 minutes","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:47.549292-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:06:29.635123-05:00","closed_at":"2026-02-05T15:06:29.635123-05:00","close_reason":"Implemented in a0dd498"} -{"id":"pnt-6yk","title":"Remove teller references and cleanup","description":"Remove outdated teller references since the project has migrated to sops-nix.\n\nChanges needed:\n- Update README.md: change 'teller shell' to 'sops environment' in the check-secrets recipe documentation\n- Verify if teller package in modules/devshell.nix is still needed; remove if unused since sops is the actual secrets manager\n- Search for any other teller config remnants and remove them\n\nScope: ~30 minutes","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:43.905379-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:06:11.313308-05:00","closed_at":"2026-02-05T15:06:11.313308-05:00","close_reason":"Implemented in 1dc676c"} -{"id":"pnt-8um","title":"Align setup-nix action with vanixiets canonical","description":"Bring .github/actions/setup-nix/action.yml and all workflow call sites into alignment with vanixiets. Keep extra-conf as pnt-specific extension. Remove extra-pull-names. Update action pins, restore type annotations and inline comments.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T01:24:30.820655-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T01:29:00.587728-05:00","closed_at":"2026-02-16T01:29:00.587728-05:00","close_reason":"Implemented in 9bdc018..a53ced8 on branch pnt-8um-align-setup-nix"} -{"id":"pnt-btz","title":"pyo3/Rust extension integration","description":"Add Rust extension module support via maturin + pyo3, demonstrating Nix build integration with crane cargoArtifacts sharing and uv2nix overlay composition.\n\nArchitecture documented in: docs/notes/architecture/crane-uv2nix-integration.md\n\nKey patterns:\n- Per-package Rust workspace (crates/ inside Python package)\n- crane buildDepsOnly for artifact caching\n- uv2nix overlay injection for maturin builds\n- CI matrix with rust-deps/rust-checks/python-wheel categories\n\nReference implementations:\n- ~/projects/rust-workspace/ironstar (crane patterns)\n- ~/projects/planning-workspace/langchain (federated Python)\n","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:41.426256-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:45:01.187149-05:00","closed_at":"2026-02-02T20:45:01.187149-05:00","close_reason":"All 3 children complete. Crane + uv2nix + maturin integration fully operational.","dependencies":[{"issue_id":"pnt-btz","depends_on_id":"pnt-dre","type":"blocks","created_at":"2026-01-19T11:55:32.690895-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-btz","depends_on_id":"pnt-4jg","type":"blocks","created_at":"2026-01-19T11:55:32.812602-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-btz.1","title":"Create pnt-cli package scaffold with Rust crates","description":"Create packages/pnt-cli/ with federated structure:\n\nDirectory structure:\n- packages/pnt-cli/pyproject.toml (maturin build-backend, manifest-path binding)\n- packages/pnt-cli/src/pnt_cli/__init__.py (Python wrapper)\n- packages/pnt-cli/crates/Cargo.toml ([workspace] with member crates)\n- packages/pnt-cli/crates/pnt-cli-core/Cargo.toml (pure Rust library)\n- packages/pnt-cli/crates/pnt-cli-py/Cargo.toml (pyo3 bindings, depends on core)\n\npyproject.toml configuration:\n- [build-system] requires maturin\u003e=1.5\n- [tool.maturin] manifest-path = \"crates/pnt-cli-py/Cargo.toml\"\n- [tool.maturin] module-name = \"pnt_cli._native\"\n\nMinimal proof-of-concept: expose a simple function from Rust to Python.\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:17.885691-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:30:16.311977-05:00","closed_at":"2026-02-02T20:30:16.311977-05:00","close_reason":"Implemented in a3e79c3. Scaffold verified: cargo check, cargo test (2/2 pass), cargo clippy clean.","dependencies":[{"issue_id":"pnt-btz.1","depends_on_id":"pnt-btz","type":"parent-child","created_at":"2026-01-19T11:55:17.886287-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-btz.1","depends_on_id":"pnt-4jg.1","type":"blocks","created_at":"2026-01-19T12:20:18.940008-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-btz.2","title":"Implement crane + uv2nix Nix modules","description":"Create Nix modules implementing the crane + uv2nix integration pattern.\n\nFiles to create:\n- nix/packages/pnt-cli/rust.nix (crane configuration)\n- nix/packages/pnt-cli/default.nix (Python + Rust composition)\n- nix/modules/rust/lib.nix (shared crane utilities, optional)\n\nrust.nix pattern:\n- crane-lib.buildDepsOnly for cargoArtifacts caching\n- commonArgs pattern for derivation hash consistency\n- crane-lib.vendorCargoDeps for maturin's cargo invocation\n- Export cargoArtifacts, cargoVendorDir, clippy, nextest\n\ndefault.nix pattern:\n- Import rust.nix\n- Create overlay injecting cargoVendorDir and CARGO_TARGET_DIR\n- Export overlay and checks for flake composition\n\nUpdate nix/modules/python.nix:\n- Load pnt-cli workspace independently (federated pattern)\n- Compose Rust overlay with uv2nix overlays\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:18.885252-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:41:16.274515-05:00","closed_at":"2026-02-02T20:41:16.274515-05:00","close_reason":"Implemented in 8d8a814. Crane checks (clippy, nextest) build. Full maturin wheel builds via nix build .#default. Python import verified: greet('nix') and add(2,3) work end-to-end.","dependencies":[{"issue_id":"pnt-btz.2","depends_on_id":"pnt-btz","type":"parent-child","created_at":"2026-01-19T11:55:18.885818-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-btz.2","depends_on_id":"pnt-btz.1","type":"blocks","created_at":"2026-01-19T12:20:08.210077-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-btz.3","title":"Validate integration and update CI","description":"Validate the full crane + uv2nix + maturin integration and update CI.\n\nValidation checklist:\n- [ ] nix build .#pnt-cli produces working wheel\n- [ ] Python import succeeds: from pnt_cli._native import ...\n- [ ] Rust changes trigger minimal rebuilds (cargoArtifacts cached)\n- [ ] Python-only changes don't rebuild Rust\n- [ ] cargoClippy and cargoNextest checks pass\n\nCI updates (.github/workflows/ci.yaml):\n- Add rust-deps matrix category for cargoArtifacts caching\n- Add rust-checks matrix category for clippy/nextest\n- Ensure proper cache key based on Cargo.lock hash\n- Follow ironstar CI matrix pattern\n\nDocumentation updates:\n- Add usage example to README\n- Document development workflow (uv sync + maturin develop vs nix build)\n- Note editable install limitations\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:19.746622-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:44:56.18025-05:00","closed_at":"2026-02-02T20:44:56.18025-05:00","close_reason":"Validated in 1b7b12e. All acceptance criteria pass: nix build produces working wheel, Python import succeeds, clippy/nextest checks pass, justfile recipes work via nix develop -c. CI updated with Rust path filters and hash-sources.","dependencies":[{"issue_id":"pnt-btz.3","depends_on_id":"pnt-btz","type":"parent-child","created_at":"2026-01-19T11:55:19.74722-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-btz.3","depends_on_id":"pnt-btz.2","type":"blocks","created_at":"2026-01-19T12:20:11.013516-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-bxq","title":"Fix template instantiation workflow and documentation","description":"Fix CI template.yaml workflow and improve instantiation documentation.\n\nCRITICAL: The current template.yaml workflow expects pytest to run from repo root, which FAILS in the federated monorepo pattern (no root pyproject.toml). Must update to use 'just test-all' instead.\n\nReference: ~/projects/sciexp/pnt-mono-8dbebca/python-nix-template-instantiation-experience-8dbebca.md documents the instantiation pain points and experience.\n\nCode changes:\n- Update .github/workflows/template.yaml to use 'nix develop -c just test-all' instead of expecting pytest from repo root\n\nDocumentation improvements:\n- Add explicit 'uv lock' post-instantiation step in README (each package needs individual locking)\n- Clarify this is independent-lock pattern, NOT uv workspaces\n- Add cachix cache creation guidance for instantiated projects\n- Document domain-organized package structure for multi-domain monorepos (like sciexp/data with io/, lake/, mesh/ subdirectories)\n- Consider omnix post-init hook for auto-locking packages if feasible\n\nScope: ~2 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:57.902854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:10:28.749501-05:00","closed_at":"2026-02-05T15:10:28.749501-05:00","close_reason":"Implemented in 38e7d56"} -{"id":"pnt-cu0","title":"Replace maturin-action with nix-native wheel builds","description":"The current wheel-build.yaml uses PyO3/maturin-action@v1 and actions/setup-python@v5, third-party GitHub Actions with no local testing parity. The preferred pattern across the ecosystem (vanixiets, typescript-nix-template) is nix develop -c just [recipe] so that builds are reproducible locally, on any machine, and in CI.\n\nResearch these reference implementations for Nix-native maturin/crane wheel building:\n- ~/projects/nix-workspace/pyperscan-uses-crane-maturin (crane + maturin integration)\n- ~/projects/nix-workspace/crane-maturin (dedicated crane-maturin library)\n- ~/projects/maturin (maturin source with Nix build examples)\n\nDesign an approach consistent with uv2nix, pyproject.nix, and crane that could produce cross-platform wheels via nix build or nix develop -c just build-wheels. The goal: replace everything in wheel-build.yaml except the actions/checkout and actions/upload-artifact steps with a single nix develop -c just build-wheels invocation.\n\nConsiderations:\n- Cross-compilation targets: linux-x86_64, linux-aarch64, macos-x86_64, macos-aarch64\n- Whether Nix cross-compilation can replace the current multi-runner matrix strategy\n- Integration with crane vendorCargoDeps for offline builds\n- How pyproject.nix and uv2nix handle maturin wheel metadata\n- Whether sdist generation should also be Nix-native","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-04T20:34:33.483691-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T21:09:15.823081-05:00","closed_at":"2026-02-04T21:09:15.823081-05:00","close_reason":"Research confirms Nix-native builds cannot produce manylinux-compatible wheels for PyPI. crane-maturin explicitly sets --manylinux off. The hybrid approach (crane-maturin for local/Nix, maturin-action for PyPI) implemented in pnt-wbq is the correct architecture. No further action needed.","dependencies":[{"issue_id":"pnt-cu0","depends_on_id":"pnt-wbq","type":"discovered-from","created_at":"2026-02-04T20:34:48.946731-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-dre","title":"Infrastructure alignment","description":"Align Makefile, justfile, scripts/, and CI with vanixiets and typescript-nix-template patterns. Makefile bootstrap-only, grouped justfile recipes, cached-ci-job CI pattern, omnix template integration.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:39.841346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:56:26.823947-05:00","closed_at":"2026-02-02T15:56:26.823947-05:00","close_reason":"All children closed: pnt-dre.1 (Makefile), pnt-dre.2 (justfile), pnt-dre.3 (scripts), pnt-dre.4 (cached-ci-job/CI), pnt-dre.5 (omnix template). Infrastructure alignment complete."} -{"id":"pnt-dre.1","title":"Refactor Makefile to bootstrap-only pattern","description":"Restrict Makefile to bootstrap targets only: install-nix, install-direnv, verify, setup-user, check-secrets, clean. Move all other targets to justfile.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:54.237851-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:39:45.088007-05:00","closed_at":"2026-02-02T15:39:45.088007-05:00","close_reason":"Added verify, setup-user, check-secrets targets aligned with vanixiets. Updated bootstrap output with numbered next-steps. Makefile was already bootstrap-only; no targets removed.","dependencies":[{"issue_id":"pnt-dre.1","depends_on_id":"pnt-dre","type":"parent-child","created_at":"2026-01-19T11:54:54.238477-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-dre.2","title":"Adopt grouped justfile recipe pattern","description":"Reorganize justfile with grouped recipes and section headers following vanixiets pattern: nix, python, conda, docs, secrets, ci/cd groups. Add help comments for each recipe.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:55.145094-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:42:24.899403-05:00","closed_at":"2026-02-02T15:42:24.899403-05:00","close_reason":"Aligned group naming (conda package→conda, python package→python), fixed Documentation→Docs header, demoted GCP sub-section, corrected type recipe comment, moved helper to EOF.","dependencies":[{"issue_id":"pnt-dre.2","depends_on_id":"pnt-dre","type":"parent-child","created_at":"2026-01-19T11:54:55.145764-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-dre.3","title":"Reorganize scripts/ directory structure","description":"Move scripts into subdirectories: scripts/ci/, scripts/docs/, scripts/sops/. IMPORTANT: scripts/bootstrap.sh must remain at stable path for curl one-liner URL. Update justfile and CI references.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:55.839371-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:45:23.076616-05:00","closed_at":"2026-02-02T15:45:23.076616-05:00","close_reason":"Created scripts/bootstrap.sh (stable URL for curl one-liner) and scripts/ci/maximize-build-space.sh (canonical version of duplicated CI logic). Workflow inline references deferred to pnt-dre.4 CI redesign due to pre-checkout step ordering. scripts/sops/ and scripts/docs/ skipped — no duplication issues warranting extraction.","dependencies":[{"issue_id":"pnt-dre.3","depends_on_id":"pnt-dre","type":"parent-child","created_at":"2026-01-19T11:54:55.839951-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-dre.4","title":"Implement cached-ci-job composite action pattern","description":"Add .github/actions/cached-ci-job composite action following typescript-nix-template pattern. Content-addressed caching with hash-sources and force-run support. Update CI to use category-based matrix builds.\n\nPost-federation CI adaptation: the migration from uv workspace to per-package independent locks (pnt-4jg.1) means CI must now discover and iterate packages under packages/. The matrix strategy needs a package axis in addition to the category axis, producing either a {package} x {category} matrix or per-package reusable workflow dispatches. Review how ci.yaml currently enumerates packages and ensure the composite action pattern supports per-package resolution of lock files, dependency caches, and build artifacts.\n\nAcceptance criteria:\n- .github/actions/cached-ci-job composite action implemented\n- Content-addressed caching with hash-sources and force-run support\n- CI matrix discovers packages/ dynamically (not hardcoded)\n- Matrix crosses package x category dimensions\n- Per-package uv.lock files used for cache keys (not root lock)\n- Category-based builds follow typescript-nix-template pattern","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:56.79376-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:55:30.748155-05:00","closed_at":"2026-02-02T15:55:30.748155-05:00","close_reason":"Implemented cached-ci-job composite action (ported from typescript-nix-template), per-package CI justfile recipes (ci-sync, ci-lint, ci-test, ci-typecheck, ci-check, list-packages-json), rewrote python-test.yaml to use nix develop -c just \u003crecipe\u003e, added dynamic package discovery and force_run to ci.yaml. All CI steps expressible as nix develop -c just \u003crecipe\u003e.","dependencies":[{"issue_id":"pnt-dre.4","depends_on_id":"pnt-dre","type":"parent-child","created_at":"2026-01-19T11:54:56.794334-05:00","created_by":"Cameron Smith"}],"comments":[{"id":2,"issue_id":"pnt-dre.4","author":"Cameron Smith","text":"Minimal CI path fixes applied in d0cab2a as part of pnt-4jg.1 fixups: cache-dependency-glob updated to packages/*/uv.lock, uv sync/lint/test moved into per-package working-directory, ci.yaml path filters updated.\n\nRemaining for pnt-dre.4: replace setup-python/setup-uv actions with nix develop -c just \u003crecipe\u003e pattern, add justfile recipes for per-package sync/test/lint/typecheck, implement cached-ci-job composite action, dynamic package discovery.","created_at":"2026-02-02T20:17:02Z"}]} -{"id":"pnt-dre.5","title":"Add omnix template integration","description":"Configure om.templates in flake with parameter definitions. Add template-verify justfile recipe. Create .github/workflows/template.yaml for CI validation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:57.668262-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:56:15.624906-05:00","closed_at":"2026-02-02T15:56:15.624906-05:00","close_reason":"om.templates, template-verify recipe, and template.yaml workflow already existed. Fixed stale path-ignore filters for per-package lock pattern.","dependencies":[{"issue_id":"pnt-dre.5","depends_on_id":"pnt-dre","type":"parent-child","created_at":"2026-01-19T11:54:57.66888-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-dtx","title":"Simplify .envrc and remove set-git-env indirection","description":"Replace 41-line .envrc with 15-line version matching reference repos. Move git metadata exports to devshell shellHook as direct exports. Delete modules/git-env.nix. Remove set-git-env from devshell packages and shellHook.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T22:46:42.329044-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T22:49:14.40069-05:00","closed_at":"2026-02-05T22:49:14.40069-05:00","close_reason":"Simplified .envrc from 41 to 14 lines, inlined git metadata exports, removed git-env.nix. 94f3298"} -{"id":"pnt-e06","title":"Fix crane version placeholder warning in pnt-cli nix derivation","description":"crane-maturin's buildMaturinPackage invokes crateNameFromCargoToml which cannot resolve version from the workspace-only Cargo.toml during the dummySrc phase. Pass version explicitly by reading it from the workspace Cargo.toml via builtins.fromTOML.","status":"closed","priority":2,"issue_type":"bug","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T21:04:25.204989-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T21:04:58.049709-05:00","closed_at":"2026-02-16T21:04:58.049709-05:00","close_reason":"Implemented in 8901dd5"} -{"id":"pnt-edl","title":"Modernize nix module architecture and template validation","description":"Migrate python-nix-template to dendritic flake-parts architecture (import-tree) matching vanixiets, ironstar, and typescript-nix-template conventions. Fix template.yaml workflow to properly validate instantiated templates including PyO3/maturin extensions.\n\nMotivation: Current nix/modules/ uses hand-rolled readDir discovery instead of import-tree. Template CI test (test-omnix-template) fails because it runs nix develop -c pytest which cannot load PyO3 _native extension (maturin packages are excluded from editableOverlay by design). Both issues block PR #44 from being fully validated.\n\nReference implementations:\n- vanixiets: modules/ with import-tree, 200+ auto-discovered modules\n- ironstar: modules/ with import-tree, crane for Rust builds\n- typescript-nix-template: modules/ with import-tree, two-variant template testing\n\nSequencing: Migration first (structural), then template workflow fix (validation). Template test depends on knowing the final module layout.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:09:57.390595-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T17:47:25.690809-05:00","closed_at":"2026-02-03T17:47:25.690809-05:00","close_reason":"All children complete: pnt-j6f (dendritic flake-parts migration), pnt-3qp (test strategy validation), pnt-m1w (template workflow fix). Nix module architecture modernized with import-tree and conditional package composition."} -{"id":"pnt-h2o","title":"Migrate from yarn to bun monorepo for semantic-release tooling","description":"The python-nix-template currently uses yarn@4.6.0 as its JavaScript package manager for semantic-release tooling, while vanixiets and typescript-nix-template both use bun@1.3.4. This divergence:\n- Complicates porting scripts between repositories (e.g., preview-version.sh needed bun-to-yarn adaptation)\n- Means the python-nix-template cannot use the exact same scripts/preview-version.sh as the other repos\n- Introduces yarn-specific configuration (.yarnrc.yml, yarn.lock) that differs from the ecosystem standard\n\nMigration scope:\n- Replace yarn.lock with bun.lockb\n- Update packageManager field in all package.json files from yarn to bun\n- Update all justfile recipes that reference yarn (preview-version, release-package, test-package-release, etc.)\n- Update scripts/preview-version.sh to use bun instead of yarn\n- Update CI workflows referencing yarn\n- Remove .yarnrc.yml and yarn-specific configuration\n- Verify semantic-release, semantic-release-monorepo, and all plugins work correctly under bun\n\nReference: vanixiets and typescript-nix-template for the target bun configuration.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-04T20:34:43.898129-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T21:09:06.495921-05:00","closed_at":"2026-02-04T21:09:06.495921-05:00","close_reason":"Implemented in 06324ed. Migrated from yarn@4.6.0 to bun@1.3.4 across devShell, package.json (root + 3 packages), justfile, preview-version.sh, CI workflows, gitignore, and gitattributes.","dependencies":[{"issue_id":"pnt-h2o","depends_on_id":"pnt-wbq","type":"discovered-from","created_at":"2026-02-04T20:34:49.100152-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-h2q","title":"Remove nixpkgs follows from pyproject-nix chain to restore cache hits","description":"The pyproject-nix, uv2nix, and pyproject-build-systems inputs all declare inputs.nixpkgs.follows = nixpkgs, which forces them to use our nixpkgs revision. Since pyproject-nix.cachix.org builds against their own pinned nixpkgs, the follows override causes derivation hash mismatches, forcing source rebuilds of maturin, python-libcst, and other build-system packages.\n\nRemove the nixpkgs follows from all three inputs while keeping the internal cross-references (pyproject-build-systems.inputs.pyproject-nix.follows and .uv2nix.follows) since those are co-released.\n\nBefore: source rebuilds of maturin/libcst on every devshell entry.\nAfter: cache hits from pyproject-nix.cachix.org for build-system packages.\nTradeoff: second nixpkgs evaluation during flake eval (acceptable for build tool cache hits).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:30.164416-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:48.434561-05:00","closed_at":"2026-02-03T18:04:48.434561-05:00","close_reason":"Implemented in e3a9997"} -{"id":"pnt-j6f","title":"Migrate to dendritic flake-parts with import-tree","description":"Restructure nix module architecture to match reference implementations (vanixiets, ironstar, typescript-nix-template).\n\nChanges required:\n- Add import-tree as flake input (github:vic/import-tree or equivalent)\n- Move nix/modules/*.nix to modules/*.nix (top-level)\n- Replace readDir-based discovery in flake.nix with: flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules)\n- Add systems.nix module (extract system list from flake.nix)\n- Add flake-parts.nix module (external module imports like nix-unit)\n- Keep nix/packages/pnt-cli/ and nix/lib/ as non-module utilities (imported explicitly by python.nix)\n- Update all relative paths in modules that reference nix/packages/ or nix/lib/ (now one level up)\n- containers.nix is 355 lines — evaluate splitting into containers/dev.nix and containers/production.nix\n- Update template.nix conditional paths to reflect new module locations\n- Verify nix flake check passes after restructure\n- Update .github/workflows/ path filters if they reference nix/modules/\n\nKey architectural decisions:\n- Modules communicate through _module.args (python.nix exports) and config namespace (pre-commit.devShell)\n- import-tree auto-discovers all .nix files in modules/ tree\n- No manual imports list in flake.nix — adding a file to modules/ auto-includes it\n- nix/packages/ stays as explicit utility imports (not auto-discovered modules)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:10:03.187287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:43.74843-05:00","closed_at":"2026-02-03T11:07:43.74843-05:00","close_reason":"Implemented in b27f3c8. Dendritic migration, root pyproject.toml removal, ruff.toml, per-package justfile recipes, editable root fix.","dependencies":[{"issue_id":"pnt-j6f","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:10:17.67297-05:00","created_by":"Cameron Smith"}],"comments":[{"id":6,"issue_id":"pnt-j6f","author":"Cameron Smith","text":"Removing root pyproject.toml: vestigial workspace declaration contradicts federation model in python.nix","created_at":"2026-02-03T16:01:31Z"}]} -{"id":"pnt-m1w","title":"Fix template.yaml workflow for proper PyO3 and multi-variant validation","description":"Align template.yaml with typescript-nix-template patterns and fix the test-omnix-template job.\n\nRoot cause resolved (pnt-3qp): The PyO3 _native import failure was caused by pytest collecting tests from the source namespace, shadowing the installed wheel. Fixed by relocating pnt-cli tests to tests/ (outside src/). The editable overlay root was also fixed to use per-package paths ($REPO_ROOT/packages/\u003cname\u003e).\n\nRemaining work:\n- Replace nix develop -c pytest with nix flake check --accept-flake-config in template test\n- nix flake check exercises all Nix builds including maturin wheel, validating PyO3 integration\n- Add set-variables job (debug flags, skip-ci, checkout details)\n- Test TWO variants matching monorepo-package boolean parameter:\n 1. Full monorepo (monorepo-package=true): includes pnt-functional + pnt-cli\n 2. Single package (monorepo-package=false): main package only\n- Fix cachix reference: instantiated template tries pnt-mono.cachix.org which 401s (expected for fresh project, but should be parameterized or removed)\n- Consider adding lightweight smoke test after flake check: nix develop -c python -c 'import pnt_mono'\n- Root pyproject.toml has been removed; template assertion now checks ruff.toml\n- Per-package justfile recipes are now the standard pattern (test, lint, type take package parameter)\n\nReference: typescript-nix-template .github/workflows/template.yaml tests full and minimal variants with git init, bun install, nix flake check sequence.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:10:08.916223-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T17:47:13.700141-05:00","closed_at":"2026-02-03T17:47:13.700141-05:00","close_reason":"Implemented in 3a0873e. Template workflow single-package variant fixed via builtins.pathExists guard on pnt-functional references in modules/python.nix. Both Template and CI/CD workflows passing.","dependencies":[{"issue_id":"pnt-m1w","depends_on_id":"pnt-edl","type":"child-of","created_at":"2026-02-03T10:10:17.838035-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-m1w","depends_on_id":"pnt-j6f","type":"blocked-by","created_at":"2026-02-03T10:10:18.005313-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-m1w","depends_on_id":"pnt-3qp","type":"blocked-by","created_at":"2026-02-03T10:20:21.254918-05:00","created_by":"Cameron Smith"}],"comments":[{"id":7,"issue_id":"pnt-m1w","author":"Cameron Smith","text":"Checkpoint: 2026-02-03 session\n\nDone:\n- Rewrote template.yaml aligned with typescript-nix-template pattern\n- Added set-variables job, cached-ci-job integration, workflow-level concurrency, force_run input\n- Replaced nix develop -c pytest with nix flake check + import smoke tests\n- Fixed per-package uv lock (federation model has no root pyproject.toml)\n- Disabled dev containers (catppuccin-starship build failure via nixpod) to unblock nix flake check\n- Archived dev container code to nix/disabled/containers-dev.nix.txt\n- Removed nixpod flake input and dev container justfile recipes\n\nRemaining:\n- CI run 21646259884 is in progress, needs to pass\n- If CI passes: close pnt-m1w and pnt-edl\n- If CI fails: debug and iterate\n\nCommits this session: 5eaab99..ee0295d (7 commits)","created_at":"2026-02-03T20:19:44Z"}]} -{"id":"pnt-m3t","title":"Adopt setup-nix composite action with nothing-but-nix pattern","description":"Port the vanixiets setup-nix composite action to python-nix-template, replacing inline Nix installation across all workflows.\n\nCurrent state:\n- ci.yaml, python-test.yaml, build-nix-images.yaml each inline DeterminateSystems/nix-installer-action\n- build-nix-images.yaml uses ad-hoc maximize-build-space shell script\n- scripts/ci/maximize-build-space.sh exists but is not wired into workflows\n\nTarget state (matching vanixiets):\n- .github/actions/setup-nix/action.yml composite action\n- Uses wimpysworld/nothing-but-nix for space reclamation (replaces maximize-build-space.sh)\n- Uses cachix/install-nix-action with pinned Nix version\n- Configures build-dir = /nix/build (nothing-but-nix workaround)\n- Integrates magic-nix-cache and cachix setup\n- Hatchet protocol support for configurable space levels\n- All workflows delegate Nix setup to this single action\n\nAcceptance criteria:\n- .github/actions/setup-nix/action.yml implemented (port from vanixiets)\n- ci.yaml nixci job uses setup-nix action\n- python-test.yaml uses setup-nix action\n- build-nix-images.yaml uses setup-nix action (replaces inline maximize-build-space)\n- .github/actions/build-nix-image/ updated (its Nix install steps replaced by setup-nix)\n- scripts/ci/maximize-build-space.sh removed (superseded by nothing-but-nix)\n- setup-python-uv action evaluated for removal (if all Python CI runs via nix develop)\n\nReference: ~/projects/nix-workspace/vanixiets/.github/actions/setup-nix/action.yml","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T20:24:06.14337-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T21:16:20.627824-05:00","closed_at":"2026-02-02T21:16:20.627824-05:00","close_reason":"Implemented in 0b1e4fa, setup-nix action ported from vanixiets"} -{"id":"pnt-m7j","title":"Sync mergify.yml with vanixiets/typescript-nix-template patterns","description":"Upgrade mergify.yml from basic 26-line config to full-featured ~120-line config matching vanixiets and typescript-nix-template patterns.\n\nReference files:\n- ~/projects/nix-workspace/vanixiets/.github/mergify.yml\n- ~/projects/nix-workspace/typescript-nix-template/.github/mergify.yml\n\nChanges needed:\n- Add YAML anchors for base_conditions, required_checks, human_author_conditions, bot_author_conditions\n- Expand required_checks to cover all CI jobs (secrets-scan, set-variables, check-fast-forward, flake-validation, bootstrap-verification, etc.)\n- Split pull_request_rules into separate rules for human vs bot authors\n- Create separate queue rules: default for humans (batch_size: 1), bot-updates for bots (batch_size: 10)\n- Update checks_timeout format to match vanixiets pattern\n\nScope: ~2 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:53.370062-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:07:28.214895-05:00","closed_at":"2026-02-05T15:07:28.214895-05:00","close_reason":"Implemented in f369393"} -{"id":"pnt-mgq","title":"Migrate dev containers to nix2container via upgraded nixpod","description":"Update the dev container builds (containerImage, devcontainerImage) to use nix2container once nixpod itself has completed its nix2container migration.\n\nCurrent state:\n- nix/modules/containers.nix imports buildMultiUserNixImage from nixpod\n- nixpod uses dockerTools.buildLayeredImageWithNixDb internally\n- flocken handles multi-arch manifest creation for dev containers\n- Dev containers include multi-user Nix daemon, home-manager activation, s6-overlay\n\nBlocked on: nixpod completing its nix2container migration (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template's dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (from pnt-5vr production container work)\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- Dev containers build using nixpod's nix2container-based API\n- flocken fully removed from flake.nix (production containers handled by pnt-5vr)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n\nReference: ~/projects/nix-workspace/nixpod-home/docs/notes/development/container-build-refactoring.md\nReference: ~/projects/nix-workspace/nixpod-home/containers/nix.nix","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T21:47:38.830624-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T21:47:38.830624-05:00"} -{"id":"pnt-nu7","title":"Add update-flake-inputs workflow and fix Mergify check names","description":"Add the update-flake-inputs GitHub Actions workflow matching the canonical pattern from vanixiets/tnt/ironstar. Fix Mergify check name mismatch for test-python matrix jobs using regex matching. Rename mergify.yml and labeler.yml to .yaml extension. Add flake updater secrets to upload scripts.","status":"in_progress","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-12T15:22:03.939445-05:00","created_by":"Cameron Smith","updated_at":"2026-02-12T15:24:45.602214-05:00"} -{"id":"pnt-pzl","title":"Evaluate pkgs-by-name-for-flake-parts adoption for package auto-discovery","description":"Vanixiets uses pkgs-by-name-for-flake-parts for automatic package discovery from pkgs/by-name/. Python-nix-template currently hard-codes package paths in modules/python.nix, requiring manual updates for each new package.\n\nDirect adoption is feasible but python-nix-template packages need Python-specific overlay composition (crane integration, maturin compatibility, editable overlay exclusion). Requires designing a Python-aware discovery layer or adapting the pkgs-by-name pattern to emit overlays rather than standalone derivations.\n\nThis is architectural preparation for multi-package growth. Lower priority than cache and follows fixes.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:39.744987-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:07:32.63938-05:00","closed_at":"2026-02-03T18:07:32.63938-05:00","close_reason":"Won't-fix: pkgs-by-name auto-discovery is incompatible with uv2nix overlay composition model. Packages are overlays composed into a shared set, not standalone derivations. Two-file Rust pattern (rust.nix + default.nix) also incompatible with single-file-per-package structure."} -{"id":"pnt-rvh","title":"Align renovate config with ecosystem conventions","description":"Migrate .github/renovate.json from minimal config:base to full ecosystem pattern matching typescript-nix-template and ironstar. Subsumes Renovate auto-migration PR #69.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-12T15:49:19.073091-05:00","created_by":"Cameron Smith","updated_at":"2026-02-12T15:53:21.231244-05:00","closed_at":"2026-02-12T15:53:21.231244-05:00","close_reason":"Implemented in cbf07c5"} -{"id":"pnt-wbq","title":"Cross-compile and release pnt-cli wheels for all major platforms via crane pkgsCross","description":"Build and release platform-specific Python wheels for pnt-cli (PyO3/maturin package with Rust extension modules) across all four major targets: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin.\n\nCurrent state: pnt-cli builds and tests on a single platform via hand-rolled crane + maturin + uv2nix overlay composition (nix/packages/pnt-cli/rust.nix and default.nix). It has never been released. semantic-release is configured in packages/pnt-cli/package.json but predicts no pending release.\n\nResearch findings: Nix pkgsCross is not viable for PyPI wheel distribution. No project in the ecosystem uses Nix cross-compilation to produce manylinux-compatible wheels. The industry standard is GitHub Actions + maturin-action with manylinux containers for Linux and native runners for macOS. crane-maturin (vlaci/crane-maturin) provides a thin wrapper over crane that eliminates hand-rolled boilerplate for maturin builds.\n\nScope (three phases):\n\nPhase A — crane-maturin refactor (no new capabilities):\n- Add vlaci/crane-maturin as flake input (pinned)\n- Replace nix/packages/pnt-cli/rust.nix + default.nix with single buildMaturinPackage call via mkLib\n- Update modules/python.nix overlay composition to use crane-maturin's output pattern\n- Verify nix flake check and nix develop -c pytest pass for all 3 packages\n- Benefit: automatic two-phase cargo caching, PYO3_PYTHON handling, passthru.tests (pytest, clippy, doc, fmt, test, audit)\n\nPhase B — CI wheel build workflow (new capability):\n- New workflow: .github/workflows/wheel-build.yaml\n- Matrix: linux-x86_64, linux-aarch64, macos-x86_64, macos-aarch64\n- Linux: maturin-action with manylinux: auto (pure Rust, no custom containers needed)\n- macOS: native runners (macos-15 for arm64)\n- Python 3.12 only (template users extend as needed)\n- Artifact upload per platform\n- Concrete for pnt-cli but with clear parameterization points (package name, maturin args as workflow variables)\n\nPhase C — release pipeline:\n- Coordinate with existing package-release.yaml\n- Trigger: semantic-release creates tag → dispatches wheel builds → collects artifacts\n- Publish to PyPI via uv publish with trusted publishing (OIDC)\n- Include sdist alongside wheels\n- Existing packages/pnt-cli/package.json semantic-release config drives versioning\n\nReference implementations:\n- ~/projects/nix-workspace/crane-maturin — vlaci/crane-maturin source (mkLib API, buildMaturinPythonPackage.nix)\n- ~/projects/nix-workspace/pyperscan-uses-crane-maturin — flake.nix overlay pattern, CI workflow structure\n- pydantic-core, polars, cryptography — industry standard maturin-action CI patterns\n\nOut of scope:\n- Nix cross-build outputs (nix build .#packages.aarch64-linux.pnt-cli from x86_64-linux) — separate concern\n- Multiple Python version matrix — start with 3.12, extend later\n- omnix template parameterization — edit-in-place customization","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T23:00:13.965286-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T15:21:02.210086-05:00","closed_at":"2026-02-04T15:21:02.210086-05:00","close_reason":"Implemented across phases A (60894ef), B (b4e9a4c), C (a2b936d, b7441d5).\n\nPhase A: crane-maturin + nixpkgsPrebuilt eliminates dual Rust compilation.\nPhase B: wheel-build.yaml with maturin-action matrix (4 platforms + sdist).\nPhase C: package-release.yaml gains build-wheels pipeline with OIDC trusted publishing.\n\nActivation prerequisites (operational, not code):\n1. Configure PyPI trusted publishing for package-release.yaml workflow in pypi environment\n2. Consider adding @semantic-release/git to pnt-cli package.json to update pyproject.toml version before wheel builds","dependencies":[{"issue_id":"pnt-wbq","depends_on_id":"pnt-5vr","type":"discovered-from","created_at":"2026-02-02T23:00:28.588784-05:00","created_by":"Cameron Smith"}],"comments":[{"id":8,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Checkpoint: Phase A complete, Phase B in progress\n\nDone (Phase A — crane-maturin refactor):\n- Moved Cargo workspace root from packages/pnt-cli/crates/ to packages/pnt-cli/ so pyproject.toml and Cargo.toml share the same src root (required by crane-maturin)\n- Added vlaci/crane-maturin as pinned flake input\n- Replaced rust.nix + default.nix with single crane-maturin integration in default.nix\n- Overlay uses hybrid approach: augments uv2nix base via overrideAttrs (preserving pyproject-nix resolver metadata for devShell) while pulling cargoVendorDir and passthru.tests from crane-maturin's standalone buildMaturinPackage\n- nix flake check passes with expanded test suite: pnt-cli-{clippy,doc,fmt,pytest,test(nextest)}\n- nix develop -c python confirms native module loads correctly\n- 3 clean atomic commits: Cargo restructure, flake input, crane-maturin refactor\n\nKey learning:\n- crane-maturin's buildMaturinPackage cannot directly replace the uv2nix overlay entry because pyproject-nix's resolveVirtualEnv needs passthru.dependencies metadata that buildPythonPackage does not produce\n- The hybrid approach works: crane-maturin for standalone build + test suite, uv2nix overrideAttrs for the overlay entry with crane's cargoVendorDir injected via preBuild\n- crane-maturin's `pname` parameter silences crane workspace name warnings\n\nRemaining (Phase B + C):\n- Phase B: wheel-build.yaml with maturin-action matrix (linux + macOS, Python 3.12)\n- Phase C: release pipeline coordination with package-release.yaml\n\nBranch: pnt-wbq-cross-compile-wheels (3 commits ahead of pnt-5vr-nix2container)","created_at":"2026-02-04T18:43:17Z"},{"id":9,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Checkpoint: nixpkgsPrebuilt refactor complete, Phase B pending\n\nDone (Phase A continued):\n- Replaced overrideAttrs overlay with pyproject-nix hacks.nixpkgsPrebuilt\n- Eliminates dual Rust compilation: crane-maturin builds once, nixpkgsPrebuilt adapts for uv2nix resolver\n- Added workspace.metadata.crane.name to silence placeholder warnings\n- Validated: nix flake check (6/6), nix develop -c pytest (2/2), nix build .#default all pass\n- Confirmed nixpkgsPrebuilt preserves passthru.dependencies for mkVirtualEnv\n\nKey learning:\n- pyproject-nix's hacks.nixpkgsPrebuilt is the correct adapter between nixpkgs buildPythonPackage outputs and pyproject-nix package sets\n- The previous overrideAttrs approach compiled Rust twice (once in cmPackage, once in the overlay via pyprojectHook + maturin)\n- nixpkgsPrebuilt strips nixpkgs propagation/wrapping and copies site-packages, taking passthru from prev\n- Cargo workspace-only root pattern (no [package] in root Cargo.toml) works with crane-maturin via manifest-path in pyproject.toml\n\nRemaining (Phase B + C):\n- Phase B: wheel-build.yaml with maturin-action matrix (linux + macOS, Python 3.12)\n- Phase C: release pipeline coordination with package-release.yaml\n\nBranch: pnt-wbq-cross-compile-wheels (4 commits ahead of pnt-yty-cloudflare-docs-alignment)","created_at":"2026-02-04T20:06:38Z"},{"id":10,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Phase B + C complete\n\nDone (Phase B — wheel-build workflow):\n- Created .github/workflows/wheel-build.yaml with maturin-action\n- Matrix: linux-x86_64 (ubuntu-latest), linux-aarch64 (ubuntu-24.04-arm), macos-x86_64 (macos-15-intel), macos-aarch64 (macos-15)\n- Callable via workflow_dispatch + workflow_call for release pipeline integration\n- Builds sdist + 4 platform wheels, uploads as artifacts (wheels-* pattern)\n- PACKAGE_PATH env var as template customization point\n\nDone (Phase C — release pipeline integration):\n- Added build-wheels input to package-release.yaml (follows build-images pattern)\n- When build-wheels=true: skips single-platform uv build/publish, calls wheel-build.yaml with release tag, then publishes all artifacts via uv publish --trusted-publishing always (OIDC)\n- Added pnt-cli to ci.yaml release-packages matrix with build-wheels: true\n- Existing pure Python packages unaffected (python-nix-template, pnt-functional use existing uv build path)\n\nNote: PyPI trusted publishing requires configuring the OIDC trust relationship on PyPI for the publish-wheels job (environment: pypi). pnt-cli's package.json lacks @semantic-release/git so pyproject.toml version is not updated by semantic-release — this is a pre-existing concern for all packages.\n\nBranch: pnt-wbq-cross-compile-wheels (4 new commits)","created_at":"2026-02-04T20:20:07Z"},{"id":11,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Post-closure session: release pipeline hardening\n\nInvestigated CI run 21687459543 where all preview-release-version jobs\nfailed silently. Root cause: the preview-version justfile recipe ran\nsemantic-release directly on the PR branch without merge simulation,\nso semantic-release rejected the non-release branch.\n\nImplemented four components to fix the release pipeline:\n\n1. Ported scripts/preview-version.sh from vanixiets (merge simulation\n via git merge-tree, worktree, temporary ref updates, yarn instead\n of bun, GITHUB_OUTPUT integration)\n\n2. Removed @semantic-release/git from all package.json files and\n package-release.yaml. Adopted pre-merge version bump pattern:\n developer runs just update-version \u003cpkg\u003e \u003cver\u003e as part of the PR.\n\n3. Added version consistency check step to preview-release-version CI\n job. Compares previewed next version against pyproject.toml (and\n Cargo.toml for maturin packages). Fails with actionable message.\n\n4. Added just update-version recipe: per-package aware, handles\n pyproject.toml [project] + [tool.pixi.package], Cargo.toml\n [workspace.package] for maturin packages, runs uv lock.\n\nFixed three CI issues during iteration:\n- yarn.lock out of sync after removing @semantic-release/git\n- ANSI escape codes contaminating version string comparison\n- PyO3 0.23.5 incompatible with Python 3.14 on macos-15 runners\n (pinned to 3.11/3.12 via setup-python + maturin -i flags)\n\nCreated pnt-cli-v0.0.0 base tag on main for semantic-release.\nCommitted wheel-build.yaml to main and rebased feature branch.\nWheel build run 21693930817 triggered for validation.\n\nCommits: 51b2455..6b5ff56 (feature branch, post-rebase)","created_at":"2026-02-05T01:10:45Z"}]} -{"id":"pnt-wl6","title":"Audit and modernize justfile recipes","description":"Systematic review of all justfile recipes (91 total across 10 groups) to ensure each is functional, correctly grouped, and up-to-date with the current project structure. Recipes should work correctly for all template instantiation variants (single-package, monorepo, with/without pyo3). Cross-cutting concerns include hardcoded repo references, pnt-cli defaults in optional groups, CI/CD group overload, and emoji usage in recipe output.","status":"in_progress","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:10.207237-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T13:20:36.037845-05:00"} -{"id":"pnt-wl6.1","title":"CI/CD group: audit and restructure recipes","description":"Review and restructure the CI/CD recipe group (23 recipes). This is the largest and most overloaded group, containing at least 4 distinct concerns that should be evaluated for regrouping.\n\nRecipes to evaluate:\n- ci-build-category, list-packages-json, ci-sync, ci-lint, ci-test, ci-typecheck, ci-check (CI matrix and per-package CI)\n- scan-secrets, scan-staged, pre-commit (code quality gates)\n- gcloud-context, ghvars, ghsecrets (infrastructure configuration)\n- list-workflows, test-docs-build, test-docs-deploy (act-based local testing)\n- gh-docs-build, gh-workflow-status, gh-docs-watch, gh-docs-logs, gh-docs-rerun, gh-docs-cancel (GitHub workflow management)\n\nKnown concerns:\n- ghvars and ghsecrets hardcode repo as sciexp/python-nix-template; should derive dynamically or accept parameter without default\n- gh-docs-* recipes (6 recipes) are docs-workflow-specific but live in CI/CD; consider moving to docs group or creating a workflows group\n- ci-sync/ci-lint/ci-test/ci-typecheck/ci-check duplicate Python group recipes with uv run prefix; clarify when to use which\n- gcloud-context recipe references GCP_PROJECT_NAME env var but may be stale\n- list-workflows depends on act which may not be in all devshells\n\nDone means: each recipe tested or removed, group split if warranted, hardcoded values parameterized, descriptions updated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:21.926844-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:21.926844-05:00","dependencies":[{"issue_id":"pnt-wl6.1","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:03:21.927598-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.10","title":"Template group: audit and update recipes","description":"Review the Template recipe group (2 recipes).\n\nRecipes to evaluate:\n- template-init, template-verify\n\nKnown concerns:\n- template-init just echoes a command rather than executing it; consider making it executable or documenting why it is echo-only\n- template-init hardcodes omnix version v1.3.2 and github:sciexp/python-nix-template; should be parameterized or use a variable\n- template-verify uses om init which requires omnix; verify om is in devshell\n- template-verify creates tmp-verify-template directory; verify cleanup works if nix flake check fails (no trap)\n- Group is small; may need minimal changes\n\nDone means: each recipe tested, hardcoded values parameterized, cleanup robustness verified.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:34.025883-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:34.025883-05:00","dependencies":[{"issue_id":"pnt-wl6.10","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:34.026569-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.11","title":"Remove emoji characters from justfile recipe output","description":"Multiple recipes across the justfile use emoji characters in their output messages. This contradicts the project style conventions which prohibit emoji usage.\n\nAffected recipes (non-exhaustive):\n- validate-secrets: uses checkmark and cross emojis\n- sops-init: uses checkmark emoji\n- sops-add-key: uses checkmark, warning, and cross emojis\n- set-secret: uses checkmark emoji\n- rotate-secret: uses checkmark emoji\n- gcp-enable-drive-api: uses checkmark and warning emojis\n- gcp-sa-create: uses checkmark emoji\n- gcp-sa-storage-user: uses checkmark and warning emojis\n- gcp-sa-key-encrypt: uses checkmark emoji\n- gcp-sa-key-delete: uses checkmark emoji\n- updatekeys: uses checkmark emoji\n- export-secrets: writes comment header\n- conda-check: uses ANSI color code (green) for success message\n- data-sync: uses checkmark emoji\n\nReplace with plain text status indicators (e.g., 'OK', 'PASS', 'FAIL', 'WARN') or remove decorative output entirely.\n\nDone means: no emoji characters remain in justfile, output messages use plain text.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:43.267932-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:43.267932-05:00","dependencies":[{"issue_id":"pnt-wl6.11","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:43.268585-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.12","title":"Parameterize hardcoded repository references in justfile","description":"Several justfile recipes contain hardcoded references to sciexp/python-nix-template that should be derived dynamically or parameterized for template portability.\n\nAffected recipes:\n- ghvars: defaults repo to sciexp/python-nix-template\n- ghsecrets: defaults repo to sciexp/python-nix-template\n- template-init: hardcodes github:sciexp/python-nix-template and omnix version v1.3.2\n\nConsider using a justfile variable at the top of the file that derives the repo from git remote, or at minimum remove the default so users must explicitly provide their repo name.\n\nDone means: no hardcoded sciexp/python-nix-template references remain as defaults in recipes.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:51.216525-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:51.216525-05:00","dependencies":[{"issue_id":"pnt-wl6.12","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:51.217236-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.13","title":"Evaluate conditional recipe availability for optional features","description":"Recipes in the Containers and Rust groups default to pnt-cli which only exists in pyo3-enabled template instantiations. When the template is instantiated without pyo3 support, these recipes have no valid default target and will fail.\n\nAffected groups:\n- Containers (4 recipes): all default CONTAINER=pnt-cli\n- Rust (5 recipes): all default package=pnt-cli\n\nOptions to evaluate:\n1. Remove defaults entirely so users must specify the package name\n2. Use justfile conditionals or shell checks to detect available packages\n3. Document these groups as pyo3-only with clear prerequisites\n4. Consider generating justfile sections based on template parameters\n\nThis issue should be addressed after the per-group audits (pnt-wl6.3 and pnt-wl6.8) have identified the full scope of the problem.\n\nDone means: a decision is made and implemented for how optional-feature recipes behave in instantiations that lack those features.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:05:00.45547-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:05:00.45547-05:00","dependencies":[{"issue_id":"pnt-wl6.13","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:05:00.456135-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-wl6.13","depends_on_id":"pnt-wl6.3","type":"blocks","created_at":"2026-02-05T20:05:05.358571-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-wl6.13","depends_on_id":"pnt-wl6.8","type":"blocks","created_at":"2026-02-05T20:05:05.512008-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.14","title":"Clarify relationship between CI/CD and Python group recipes","description":"The CI/CD group contains per-package recipes (ci-sync, ci-lint, ci-test, ci-typecheck, ci-check) that duplicate Python group recipes (uv-sync/lint/test/type/check) with the addition of uv run prefix.\n\nCI/CD group versions use 'uv run' prefix (e.g., cd packages/{package} \u0026\u0026 uv run pytest).\nPython group versions use bare tool invocation (e.g., cd packages/{package} \u0026\u0026 pytest).\n\nThe distinction is presumably that CI/CD recipes work in a clean environment where tools need uv run to resolve, while Python group recipes assume the devshell provides tools directly. However this is not documented and the naming overlap is confusing.\n\nOptions to evaluate:\n1. Remove CI/CD per-package recipes and have CI call Python group recipes (if devshell provides tools)\n2. Keep both but rename to clarify context (e.g., local vs ci)\n3. Document the distinction in recipe comments\n4. Unify by always using uv run (works in both contexts)\n\nThis issue should be addressed after both pnt-wl6.1 and pnt-wl6.6 audits.\n\nDone means: the duplication is resolved or clearly documented with rationale.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:05:16.265644-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:05:16.265644-05:00","dependencies":[{"issue_id":"pnt-wl6.14","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:05:16.266475-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-wl6.14","depends_on_id":"pnt-wl6.1","type":"blocks","created_at":"2026-02-05T20:05:20.137332-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-wl6.14","depends_on_id":"pnt-wl6.6","type":"blocks","created_at":"2026-02-05T20:05:20.291492-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.2","title":"Conda group: audit and update recipes","description":"Review the Conda/pixi recipe group (9 recipes).\n\nRecipes to evaluate:\n- conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check\n\nKnown concerns:\n- All recipes default to package=python-nix-template; evaluate whether this is the right default or should be dynamic\n- conda-lock description says 'Update conda environment' which is misleading (it exports conda-explicit-spec)\n- pixi-lock description says 'Update pixi lockfile' but actually runs pixi list and pixi tree (no locking)\n- Verify pixi environments (test, lint, types) exist in package pyproject.toml\n- Verify pixi is available in devshell\n\nDone means: each recipe tested, misleading descriptions corrected, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:29.630916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:29.630916-05:00","dependencies":[{"issue_id":"pnt-wl6.2","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:03:29.631603-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.3","title":"Containers group: audit and update recipes","description":"Review the Containers recipe group (4 recipes).\n\nRecipes to evaluate:\n- container-build-production, container-load-production, container-push-production, container-matrix\n\nKnown concerns:\n- All parameterized recipes default to CONTAINER=pnt-cli which is an optional package (only present in pyo3-enabled instantiations)\n- container-matrix references .#containerMatrix flake output; verify this exists\n- container-push-production uses --impure flag; document why this is needed\n- These recipes are irrelevant for template instantiations without container support; consider conditional availability or documenting prerequisites\n\nDone means: each recipe tested or documented as optional, defaults evaluated, prerequisites documented.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:36.715993-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:36.715993-05:00","dependencies":[{"issue_id":"pnt-wl6.3","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:03:36.71685-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.4","title":"Docs group: audit and update recipes","description":"Review the Docs recipe group (10 recipes).\n\nRecipes to evaluate:\n- docs-extensions, docs-reference, docs-build, docs-local, docs-check, docs-dev, docs-deploy, docs-preview-deploy, data-sync, docs-sync\n\nKnown concerns:\n- docs-build depends on data-sync which requires DVC setup with GCP service account; this hard dependency means docs cannot be built without DVC configuration\n- data-sync and docs-sync both decrypt vars/dvc-sa.json and use uvx with dvc-gdrive,dvc-gs; consider whether DVC should be optional for docs builds\n- docs-dev and docs-deploy use bunx wrangler; verify bun/wrangler are in devshell\n- docs-preview-deploy uses wrangler versions upload with preview alias\n- docs-extensions runs quarto add which modifies project files; may not be idempotent\n\nDone means: each recipe tested, DVC dependency evaluated for optionality, prerequisites documented, tools verified in devshell.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:46.393111-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:46.393111-05:00","dependencies":[{"issue_id":"pnt-wl6.4","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:03:46.393789-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.5","title":"Nix group: audit and update recipes","description":"Review the Nix recipe group (4 recipes).\n\nRecipes to evaluate:\n- dev, flake-check, flake-update, ci\n\nKnown concerns:\n- ci recipe runs om ci (omnix); verify om is in devshell\n- flake-check is a comprehensive script that iterates all checks; verify it handles failures gracefully\n- dev recipe just runs nix develop which is redundant if user is already in direnv-managed shell\n- Group is small and clean; may need minimal changes\n\nDone means: each recipe tested, tools verified in devshell.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:52.621765-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:52.621765-05:00","dependencies":[{"issue_id":"pnt-wl6.5","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:03:52.622473-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.6","title":"Python group: audit and update recipes","description":"Review the Python recipe group (10 recipes).\n\nRecipes to evaluate:\n- test, test-all, uv-build, uv-sync, uv-lock, lint, lint-all, lint-fix, type, check\n\nKnown concerns:\n- All parameterized recipes default to package=python-nix-template; evaluate whether this is the right default\n- test recipe runs bare pytest (not uv run pytest); compare with ci-test which uses uv run pytest\n- lint runs bare ruff check; compare with ci-lint which uses uv run ruff check\n- type runs bare pyright; compare with ci-typecheck which uses uv run pyright\n- The distinction between bare tool invocation (Python group) and uv run invocation (CI/CD group) should be documented or unified\n- lint-all runs ruff check on entire packages/ directory; verify this works with independent-lock pattern\n- test-all iterates packages and runs pytest in each; verify this works without workspace-level uv.lock\n\nDone means: each recipe tested, relationship with CI/CD group recipes clarified, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:00.982412-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:00.982412-05:00","dependencies":[{"issue_id":"pnt-wl6.6","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:00.983084-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.7","title":"Release group: audit and update recipes","description":"Review the Release recipe group (8 recipes).\n\nRecipes to evaluate:\n- test-release, test-release-as-main, test-release-on-current-branch, test-release-direct, test-package-release, preview-version, release-package, update-version\n\nKnown concerns:\n- test-release, test-release-as-main, test-release-on-current-branch, test-release-direct all delegate to bun run scripts; verify these scripts exist in package.json\n- test-package-release defaults to package-name=python-nix-template\n- release-package runs bun install then delegates to bun run; verify bun is in devshell\n- update-version uses sed for in-place edits; verify correctness on macOS (sed -i'' vs sed -i)\n- update-version handles pyproject.toml [project] and [tool.pixi.package] versions plus Cargo.toml; verify all paths\n- preview-version delegates to scripts/preview-version.sh; verify this script exists\n\nDone means: each recipe tested or verified, bun scripts confirmed, sed portability checked.","status":"in_progress","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:08.993522-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T13:20:36.143188-05:00","dependencies":[{"issue_id":"pnt-wl6.7","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:08.994211-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.8","title":"Rust group: audit and update recipes","description":"Review the Rust recipe group (5 recipes).\n\nRecipes to evaluate:\n- cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check\n\nKnown concerns:\n- All recipes default to package=pnt-cli which is optional (only present in pyo3-enabled instantiations)\n- All recipes assume packages/{package}/crates directory structure; this is pnt-cli-specific\n- cargo-nextest uses --no-tests=pass flag; verify this is the intended behavior\n- These recipes are irrelevant for template instantiations without Rust/pyo3 support\n- Consider conditional availability or clear documentation that this group is pyo3-only\n\nDone means: each recipe tested in pnt-cli context, documented as optional/conditional, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:15.108397-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:15.108397-05:00","dependencies":[{"issue_id":"pnt-wl6.8","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:15.109077-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-wl6.9","title":"Secrets group: audit and restructure recipes","description":"Review and restructure the Secrets recipe group (20 recipes). This is the second largest group and contains two distinct concerns that should be evaluated for separation.\n\nRecipes to evaluate:\nCore sops management (10 recipes):\n- show-secrets, edit-secrets, new-secret, export-secrets, run-with-secrets, check-secrets, get-secret, validate-secrets, sops-init, sops-add-key, set-secret, rotate-secret, updatekeys\n\nGCP service account and DVC management (7 recipes):\n- gcp-enable-drive-api, gcp-sa-create, gcp-sa-storage-user, gcp-sa-key-download, gcp-sa-key-encrypt, gcp-sa-key-rotate, gcp-sa-key-delete, gcp-sa-keys-list, dvc-run\n\nKnown concerns:\n- GCP/DVC recipes are project-specific infrastructure that most template instantiations will not need; consider separating into a gcp or data group\n- sops-add-key uses interactive read which may not work in all environments\n- rotate-secret uses interactive read -s for hidden input\n- validate-secrets and sops-init use emoji characters in output (contradicts style conventions)\n- export-secrets writes to .secrets.env; verify this is in .gitignore\n- updatekeys iterates all files in vars/ not just yaml; could match non-sops files\n\nDone means: each recipe tested, group potentially split into sops-core and gcp/data subgroups, interactive recipes documented, emoji usage removed.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:26.827907-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:26.827907-05:00","dependencies":[{"issue_id":"pnt-wl6.9","depends_on_id":"pnt-wl6","type":"parent-child","created_at":"2026-02-05T20:04:26.828668-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-yty","title":"Align Cloudflare docs deployment with vanixiets preview-promote pattern","description":"Align python-nix-template docs deployment workflow with the preview-promote pattern from vanixiets and typescript-nix-template. Currently pnt has preview deployment but no production promotion logic, uses a two-job workflow with artifact upload, lacks link validation, and uses yarn-berry where vanixiets/tnt use bun.\n\nChanges required:\n\n1. Migrate from yarn-berry to bun:\n - Remove yarn.lock, .yarnrc.yml, and any yarn configuration\n - Add bun to the devShell (modules/devshell.nix)\n - Replace all yarn dlx wrangler / yarn dlx references with bunx wrangler / bunx\n - Update package.json scripts if they reference yarn\n - Generate bun.lock (or bun.lockb) from package.json\n - Update .gitignore for bun artifacts\n - Update CI workflows that reference yarn\n - This aligns tooling exactly with vanixiets and typescript-nix-template\n\n2. Add docs-deploy-production justfile recipe with version promotion logic:\n - Look up existing wrangler version by 12-char commit SHA tag\n - If found: promote to 100% production traffic (zero rebuild)\n - If not found: fall back to build and deploy directly\n - Reference: vanixiets scripts/docs/deploy-production.sh and tnt justfile docs-deploy-production\n\n3. Align docs-deploy-preview with vanixiets pattern:\n - Branch name sanitization (40-char subdomain-safe)\n - Git metadata capture (12-char SHA tag, commit message, clean/dirty status)\n - Use bunx wrangler (after yarn-to-bun migration)\n\n4. Refactor deploy-docs.yaml workflow:\n - Single-job pattern with environment branching (preview vs production)\n - Use setup-nix composite action instead of DeterminateSystems/nix-installer-action\n - Add link validation step (just docs-linkcheck or equivalent for Quarto)\n - Add cached-ci-job execution caching\n - Preview triggered on PR, production triggered on push to main/beta\n\n5. Evaluate wrangler.jsonc location:\n - Currently at repo root, vanixiets/tnt have it in packages/docs/\n - pnt docs are in docs/ (not packages/docs/), so repo root may be appropriate\n - Ensure assets.directory path is correct relative to wrangler.jsonc location\n\n6. Worker naming convention:\n - Current: python-nix-template (matches repo name)\n - vanixiets pattern: infra-docs, tnt pattern: ts-nix-docs\n - Choose appropriate worker name for the template\n\nReference implementations:\n- ~/projects/nix-workspace/vanixiets justfile (docs-deploy-preview, docs-deploy-production), deploy-docs.yaml, packages/docs/wrangler.jsonc, scripts/docs/deploy-production.sh\n- ~/projects/nix-workspace/typescript-nix-template justfile, deploy-docs.yaml, packages/docs/wrangler.jsonc\n\nNote: pnt uses Quarto (not Astro) so build commands differ, but the wrangler deployment pattern and bun tooling are framework-agnostic.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T18:23:43.437695-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T22:16:52.24175-05:00","closed_at":"2026-02-03T22:16:52.24175-05:00","close_reason":"Implemented across 18 commits on branch pnt-yty-cloudflare-docs-alignment (dd698bf..e03ca68). Phase 1: yarn-to-bun migration (devshell, package.json, justfile, lockfile, CI hash-sources). Phase 2: preview-promote docs deployment (docs-deploy-preview with branch sanitization and SHA tagging, docs-deploy-production with version promotion, single-job deploy-docs.yaml with environment branching, wrangler.jsonc schema and observability). Alignment: GitHub preview/production environments created, preview-docs job runs on every PR (removed label gate), ::notice annotations for predicted semantic-release versions, preview-version.sh ported from tnt with merge-tree simulation. CI verified green on PR 45 (run 21652296092). Fix for preview-release-version local branch requirement pushed (e03ca68), awaiting CI confirmation."} +{"id":"pnt-1q5","title":"Switch nixpkgs URL to optimized channel tarball format","description":"Current nixpkgs input uses github:NixOS/nixpkgs/nixos-unstable (GitHub archive format). Vanixiets uses https://channels.nixos.org/nixpkgs-unstable/nixexprs.tar.xz (channel tarball), which is smaller, faster to fetch, and avoids GitHub rate limiting.\n\nAdopt the tarball URL pattern from vanixiets for the primary nixpkgs input.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:35.584808-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:05:10.871297-05:00","closed_at":"2026-02-03T18:05:10.871297-05:00","close_reason":"Implemented in 293d46d","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3bd","title":"Add crane.inputs.nixpkgs.follows and align cache declarations with vanixiets","description":"Two related flake hygiene items:\n\n1. crane input has no follows directive, causing a redundant independent nixpkgs evaluation. Since crane is a build library with no upstream cache, adding inputs.nixpkgs.follows = nixpkgs eliminates the extra eval with no cache downside.\n\n2. Cache declarations are minimal (3 substituters) compared to vanixiets (9). Add cache.nixos.org explicitly, numtide.cachix.org, and cameronraysmith.cachix.org to nixConfig.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:33.582737-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:49.646325-05:00","closed_at":"2026-02-03T18:04:49.646325-05:00","close_reason":"Implemented in e3a9997, added crane/numtide/cache.nixos.org caches","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3jf","title":"Validate sciexp/data platform instantiation","description":"Final validation gate before v0.2.0 release. Instantiate template to create the sciexp data platform repository.\n\nTarget: ~/projects/sciexp/data\n\nValidation steps:\n- Instantiate template with configuration for omicsio, scilake, scimesh package structure\n- Verify independent locks work for each package\n- Verify Nix builds succeed for all packages\n- Verify CI patterns work correctly\n- Document any issues found and fix if minor, or create follow-up issues if significant\n\nThis issue is blocked by the other four polish issues. Successful completion means we are ready to manually create the v0.2.0 release tag.\n\nReference: ~/projects/sciexp/planning/contexts/sciexp-data-platform.md for sciexp/data requirements\n\nScope: ~3 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:48:01.905707-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:14:16.459237-05:00","closed_at":"2026-02-05T15:14:16.459237-05:00","close_reason":"Validated: template evaluation, test infrastructure (11/11 tests pass across 3 packages), and instantiation workflow confirmed working. Welcome text and README are consistent. 619014b","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3qp","title":"Investigate and validate optimal test strategy for PyO3 + Python hybrid packages","description":"The current devShell excludes pnt-cli from uv2nix editableOverlay because maturin packages are incompatible with pyprojectFixupEditableHook (expects EDITABLE_ROOT which maturin does not set). This means nix develop -c pytest cannot import pnt_cli._native, failing both locally and in CI.\n\nThis task requires investigation and experimentation to determine the optimal testing strategy for packages containing both Python and Rust code via PyO3 extension modules, using maturin as the build backend and crane for Rust build artifact caching.\n\nQuestions to answer through experimentation:\n\n1. Can we install pnt-cli non-editable in the devShell virtualenv (pre-built wheel via Nix) so pytest can import _native? What are the trade-offs for developer iteration speed?\n\n2. What is the correct split between cargo nextest (pure Rust unit tests in crates/) and pytest (Python integration tests that exercise the PyO3 bindings)? Should these be separate CI jobs or a unified test recipe?\n\n3. Can maturin develop be integrated into the devShell shellHook or a just recipe to build the extension in-place for iterative development? How does this interact with the uv2nix virtualenv?\n\n4. How do the reference implementations handle this?\n - ~/projects/nix-workspace/uv2nix — upstream patterns for maturin/PyO3 packages\n - ~/projects/nix-workspace/pyproject.nix — Python project tooling for Nix\n - ~/projects/nix-workspace/nix-cargo-crane — crane patterns for Rust builds\n - ~/projects/rust-workspace/ironstar — crane devShell integration (Rust-only but relevant caching patterns)\n\n5. For the template test (omnix init + validate): should instantiated templates use nix flake check (builds everything through Nix including maturin wheel), nix develop -c uv run pytest (uv builds the wheel), or a combination?\n\n6. Does the nix build path (nix flake check / nix build) already exercise both Rust compilation (via crane cargoArtifacts) and Python tests (via pytest in check phase)? If so, it may be sufficient for CI validation without needing devShell-based testing.\n\nAcceptance criteria:\n- Document the chosen test strategy with rationale\n- Validate that both cargo nextest (Rust unit tests) and pytest (Python integration tests) pass\n- Validate the strategy works both locally (nix develop) and in CI (template instantiation test)\n- Update devshell.nix, justfile, and template.yaml as needed to implement the chosen strategy\n- Ensure crane artifact caching is preserved (no unnecessary Rust rebuilds)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:20:11.038346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:51.054773-05:00","closed_at":"2026-02-03T11:07:51.054773-05:00","close_reason":"Resolved via test relocation: pnt-cli tests moved from src/pnt_cli/tests/ to tests/ (outside source namespace). This avoids source tree shadowing the installed wheel with _native.so. Strategy: Rust tests via cargo nextest (devShell + crane checks), Python tests via pytest from package dir (installed wheel). maturin develop not needed. nix flake check validates both build paths.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn","title":"Fix omnix template substitution and CI workflow gaps","description":"Discovered during hodosome instantiation (sciexp-042/sciexp-ww8). The omnix template spec has substitution gaps requiring 21+ manual fixup commits per instantiation, and CI workflows contain pre-existing issues. Fixing these ensures clean instantiation for future projects (sciexp/data next).","status":"inreview","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:36:48.63246-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T15:19:02.829004+00:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.1","title":"Add camelCase omnix template parameter for Nix variable names","description":"Nix modules use pythonNixTemplate camelCase variable names but omnix only substitutes kebab (python-nix-template) and snake (python_nix_template). Add a third param to modules/template.nix: { name = \"package-name-camel-case\"; placeholder = \"pythonNixTemplate\"; }. This eliminates 2 manual fixup commits per instantiation. Files affected: modules/packages.nix, modules/devshell.nix, and any other .nix files using pythonNixTemplate.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:02.791847-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:51:59.673636-05:00","closed_at":"2026-02-16T22:51:59.673636-05:00","close_reason":"Implemented in f5bf4a4","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.10","title":"Add execution cache and link validation to deploy-docs workflow","description":"Provisional — requires research before implementation. Integrate cached-ci-job composite action into the deploy-docs workflow to skip redundant builds when docs content has not changed. Hash sources should include docs content, setup-nix action, deploy-docs workflow, justfile, and scripts. Additionally, research whether Quarto has built-in link validation functionality (the reference implementations use Astro Starlight which supports link checking via just docs-linkcheck). If Quarto supports link validation natively or via a plugin, add a validation step before deployment. If no viable link validation exists for Quarto, drop that portion of this issue. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:51.835528-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T10:18:55.247101-05:00","closed_at":"2026-02-17T10:18:55.247101-05:00","close_reason":"Execution cache added in 921378c. Link validation dropped: Quarto lacks built-in support (upstream issue quarto-dev/quarto-cli#1319). Lychee identified as future option.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.2","title":"Replace Jinja-style doc placeholders with omnix-compatible literals","description":"Doc files in docs/ use {{package-name-kebab-case}} syntax which omnix does not process. Omnix performs literal string replacement using the placeholder field, not Jinja2/mustache templating. All {{package-name-kebab-case}} and {{package-name-snake-case}} occurrences in docs/ should be replaced with the literal strings python-nix-template and python_nix_template respectively. This eliminates 16 manual fixup commits per instantiation.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:03.823132-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:56:41.185276-05:00","closed_at":"2026-02-16T22:56:41.185276-05:00","close_reason":"Implemented in f5bf4a4..7d3990f","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.3","title":"Ensure package.json files use exact omnix placeholder strings","description":"The package.json files (root and per-package) contain description text that does not match the project-description placeholder string, so omnix does not substitute them. Ensure all package.json name and description fields contain the exact placeholder values from modules/template.nix so omnix catches them during instantiation. This eliminates 3 manual fixup commits per instantiation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:04.89314-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T22:58:45.278895-05:00","closed_at":"2026-02-16T22:58:45.278895-05:00","close_reason":"Implemented in 03f56ac","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.4","title":"Gate wheel-build.yaml workflow on pyo3-package template parameter","description":"The omnix template gates pyo3 package directory inclusion via the paths field on the pyo3-package param, but .github/workflows/wheel-build.yaml is not included in those paths. When users instantiate without pyo3 (or remove pyo3 packages post-instantiation), package-release.yaml still references wheel-build.yaml, causing CI failure. Add wheel-build.yaml to the pyo3-package paths list in modules/template.nix, and ensure package-release.yaml conditionally references it. Also consider adding rust-toolchain.toml to the pyo3-package paths if not already present.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:07.237944-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:07:14.976853-05:00","closed_at":"2026-02-16T23:07:14.976853-05:00","close_reason":"Implemented in 4554e94","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.5","title":"Fix shellcheck findings in CI workflow scripts","description":"Pre-existing shellcheck issues in CI workflows that propagate to all instantiated repos: SC2012 (ls vs find) in ci.yaml:176, SC2001 (sed vs parameter expansion) in ci.yaml:489, SC2086 (unquoted variables, multiple instances) in package-release.yaml:172,187, SC2129 (grouped redirects) in package-release.yaml. These are code quality issues, not functional bugs.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T22:37:08.32939-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T23:10:55.051435-05:00","closed_at":"2026-02-16T23:10:55.051435-05:00","close_reason":"Implemented in 1feaf21","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.6","title":"Align wrangler.jsonc with reference implementations","description":"Add missing fields to wrangler.jsonc: $schema, compatibility_flags, observability, dev port, workers_dev: false, and binding on assets config. Update compatibility_date. Note: pnt uses Quarto (static HTML output in docs/_site), not Astro Starlight like vanixiets/typescript-nix-template (which produce a worker bundle at dist/_worker.js/index.js). The main field (worker entry point) from the reference implementations likely does not apply to a static-assets-only deployment — research whether Cloudflare Workers static asset serving requires a main entry point or works with assets-only config. Consider relocating from repo root to a docs package directory to match reference patterns. Reference implementations: ~/projects/nix-workspace/vanixiets/packages/docs/wrangler.jsonc and ~/projects/nix-workspace/typescript-nix-template/packages/docs/wrangler.jsonc.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:46.775104-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:47:44.868798-05:00","closed_at":"2026-02-17T09:47:44.868798-05:00","close_reason":"Implemented in 6020c6d","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.7","title":"Align justfile deploy recipes with sops-based credential pattern","description":"Update docs-deploy-preview and docs-deploy-production justfile recipes to match the vanixiets/typescript-nix-template pattern: use sops exec-env to decrypt Cloudflare credentials from encrypted vars file instead of relying on direct GitHub secrets, add git metadata tagging (version tag and message) to wrangler uploads, handle branch name sanitization for preview aliases, and implement production promotion via wrangler versions deploy with traffic percentage. Note: pnt builds docs via Quarto (quarto render docs, output in docs/_site) not Astro (bun run build, output in dist/), so the build integration within the deploy recipes differs from reference implementations. The sops credential pattern, wrangler upload/deploy commands, and git metadata tagging apply regardless of build tool. Existing recipes (docs-preview-deploy, docs-deploy) use bare bunx wrangler without sops or metadata. Verification requirement: before this issue can be closed, the updated recipes must be demonstrated to work locally (at minimum just docs-deploy-preview must successfully build and upload a preview to Cloudflare from a local devshell). This local verification is the proof that the same recipes will work when called from CI/CD in pnt-3zn.8. Reference implementations: ~/projects/nix-workspace/vanixiets/justfile and ~/projects/nix-workspace/typescript-nix-template/justfile (docs-deploy-preview and docs-deploy-production recipes).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:47.936331-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T09:52:51.41033-05:00","closed_at":"2026-02-17T09:52:51.41033-05:00","close_reason":"Implemented in 6020c6d..73a3fa4. Sops credential path verified locally: docs-versions and docs-deployments both query Cloudflare API successfully.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.8","title":"Restructure deploy-docs.yaml to single-job direct deploy","description":"Replace the two-job artifact-relay architecture (build-docs uploads artifact, deploy-docs downloads and deploys via cloudflare/wrangler-action) with a single deploy-docs job that builds and deploys directly through justfile recipes. Add missing inputs: environment (preview/production), sanitized_branch (URL-safe alias), force_run (cache bypass). Add GitHub environment block with name and deployment URL. Remove cloudflare/wrangler-action dependency in favor of nix develop -c just docs-deploy-preview/production. Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/deploy-docs.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/deploy-docs.yaml.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:49.066173-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T10:13:36.248322-05:00","closed_at":"2026-02-17T10:13:36.248322-05:00","close_reason":"Implemented in 4089daa","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-3zn.9","title":"Update ci.yaml docs jobs to pass new deploy-docs inputs","description":"Update the preview-docs and deploy-docs jobs in ci.yaml to pass new deploy-docs.yaml inputs: environment (preview for PRs, production for main/beta pushes), sanitized_branch, and force_run. Add sanitized_branch computation to the set-variables job (URL-safe branch name with special characters replaced). Reference implementations: ~/projects/nix-workspace/vanixiets/.github/workflows/ci.yaml and ~/projects/nix-workspace/typescript-nix-template/.github/workflows/ci.yaml (preview-docs-deploy and production-docs-deploy jobs).","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T09:30:50.156674-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T10:18:55.091497-05:00","closed_at":"2026-02-17T10:18:55.091497-05:00","close_reason":"Implemented in 5bc8c88","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4jg","title":"Dependency model migration","description":"Migrate from single-lock uv workspace to independent-lock multi-package pattern following langchain/langgraph approach. Include pixi feature-based composition for conda ecosystem parity.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:40.744055-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:43.167289-05:00","closed_at":"2026-02-02T15:37:43.167289-05:00","close_reason":"All children closed: pnt-4jg.1 (uv workspace removal), pnt-4jg.2 (pixi feature composition), pnt-4jg.3 (distribution channel docs). Dependency model migration complete.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4jg.1","title":"Remove uv workspace, adopt path dependencies","description":"Remove [tool.uv.workspace] from root pyproject.toml. Each package gets own pyproject.toml with [tool.uv.sources] for sibling references using path sources with editable=true. Follow langchain pattern.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:07.344057-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T14:40:02.175394-05:00","closed_at":"2026-02-02T14:40:02.175394-05:00","close_reason":"Implemented in a8a823f. Removed root uv workspace, generated per-package locks, rewrote nix modules to Pattern 3 per-package loading.","comments":[{"id":1,"issue_id":"pnt-4jg.1","author":"Cameron Smith","text":"Post-close fixup commits (774ec26):\n- fix(ci): update lock file references for per-package federation (d0cab2a)\n- fixup! merge federated workspace deps: replace // with zipAttrsWith for extras-safe dep merging (7b3e7ae)\n- fixup! load packages independently: document version-conflict invariant in python.nix and architecture doc (36eb8a7, 774ec26)\n\nReview findings addressed: stale CI cache-dependency-glob paths, fragile shallow-merge dep specs, undocumented overlay composition invariant. Full CI redesign (nix develop + justfile symmetry) deferred to pnt-dre.4.","created_at":"2026-02-02T20:17:00Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4jg.2","title":"Configure pixi feature-based composition","description":"Implement pixi feature/environment pattern: [feature.X.dependencies] + [environments] composition. Single pixi.lock covering all environments. Per-feature task definitions. Target-specific dependencies for platform support.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:08.085592-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:36:49.459815-05:00","closed_at":"2026-02-02T15:36:49.459815-05:00","close_reason":"Verified pixi feature composition via nix develop -c just . Fixed: added missing feature tasks to python-nix-template, delegated justfile conda recipes to pixi task names for correct working directory, moved deprecated build channels to backend.channels.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4jg.3","title":"Document package distribution channels","description":"Document which packages support uv/pypi vs pixi/conda distribution. Note dependency graph differences between channels. Update README and package metadata.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:09.051203-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:37:38.374454-05:00","closed_at":"2026-02-02T15:37:38.374454-05:00","close_reason":"Documented in docs/notes/architecture/package-distribution-channels.md. Both packages support dual-channel (uv/PyPI + pixi/conda-forge) with independent locks. No blocking dependency graph differences between channels.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us","title":"Template v0.2.0 Release Polish","description":"Final polish and validation before v0.2.0 release. Prove template is production-ready for sciexp data platform instantiation and general use. Completing this epic enables the manual v0.2.0 tag creation.","status":"closed","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:40.344366-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:19:46.382817-05:00","closed_at":"2026-02-05T19:19:46.382817-05:00","close_reason":"All children closed. Template v0.2.0 release polish complete. af7b303","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.1","title":"Add pyo3-package template param to modules/template.nix","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.550401-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:07:22.809551-05:00","closed_at":"2026-02-05T19:07:22.809551-05:00","close_reason":"Implemented in 6fcdac4","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.2","title":"Add hasCli conditional guards to modules/python.nix","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.707539-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:08:24.466211-05:00","closed_at":"2026-02-05T19:08:24.466211-05:00","close_reason":"Implemented in be7c6d0","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.3","title":"Add hasCli conditional guard to modules/containers.nix","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:47.867613-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:09:29.970634-05:00","closed_at":"2026-02-05T19:09:29.970634-05:00","close_reason":"Implemented in b794759 (parallel session)","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.4","title":"Gate Rust tooling in modules/devshell.nix behind hasCli","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.01078-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:10:01.017053-05:00","closed_at":"2026-02-05T19:10:01.017053-05:00","close_reason":"Implemented in 40591c5","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.5","title":"Dynamize release-packages matrix in ci.yaml","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.170487-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:09:23.768755-05:00","closed_at":"2026-02-05T19:09:23.768755-05:00","close_reason":"Implemented in b794759","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-4us.6","title":"Verify template instantiation with pyo3-package false","description":null,"status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T19:05:48.309753-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T19:19:46.210854-05:00","closed_at":"2026-02-05T19:19:46.210854-05:00","close_reason":"Verified: both monorepo (pyo3:true) and single-package (pyo3:false) instantiations pass. af7b303","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-5vr","title":"Add production containers via nix2container and replace flocken tooling","description":"Add lightweight production/execution container images using nix2container (vanixiets pattern) and replace flocken manifest tooling. This does NOT touch nixpod-based dev containers.\n\nProduction containers (new):\n- nix2container.buildImage for minimal per-package execution images\n- Each user-facing package gets a container with only its runtime closure\n- pkgsCross for cross-compilation (eliminates QEMU dependency)\n- Per-container layer strategy: base layer (bash, coreutils) + app layer\n\nFlocken replacement (affects all containers):\n- crane-based mkMultiArchManifest replacing flocken mkDockerManifest\n- skopeo-nix2container with nix: transport for pushing\n- containerMatrix flake output for CI matrix generation (pure nix evaluation)\n- build-nix-images.yaml updated for nix2container workflow\n\nDoes NOT include:\n- Dev container migration (see pnt-xxx blocked issue)\n- Changes to buildMultiUserNixImage or nixpod integration\n- Existing dev container content or architecture\n\nReference: ~/projects/nix-workspace/vanixiets/modules/containers/default.nix\nReference: ~/projects/nix-workspace/vanixiets/lib/mk-multi-arch-manifest.nix\n\nAcceptance criteria:\n- nix2container flake input added\n- At least one production container defined via nix2container.buildImage\n- pkgsCross used for cross-compilation targets\n- lib/mk-multi-arch-manifest.nix ported from vanixiets\n- containerMatrix flake output for CI matrix generation\n- flocken replaced by crane-based manifests for production containers\n- Existing dev containers still build and work (no regression)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T20:24:12.624117-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T00:32:32.102656-05:00","closed_at":"2026-02-03T00:32:32.102656-05:00","close_reason":"Implemented in c760bd1. PR #44.","comments":[{"id":3,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02\n\nDone:\n- Researched vanixiets nix2container patterns (containers/default.nix, mk-multi-arch-manifest.nix, containers.yaml workflow)\n- Researched current pnt container infrastructure (containers.nix, build-nix-image action, build-nix-images workflow)\n- Identified scope mismatch between vanixiets lightweight tool containers and pnt dev containers\n- Rescoped to production containers + flocken replacement only (dev containers deferred to pnt-mgq)\n\nRemaining:\n- Add nix2container flake input\n- Create lib/mk-multi-arch-manifest.nix (port from vanixiets)\n- Define at least one production container via nix2container.buildImage (pnt-cli is the natural candidate)\n- Add pkgsCross targets and containerMatrix flake output\n- Replace flocken manifest tooling for existing dev containers (crane-based manifests)\n- Update build-nix-images.yaml workflow\n- Update build-nix-image composite action (QEMU no longer needed for production containers)\n- Add justfile recipes for container build/push (local/CI symmetry)\n\nContext for next agent:\n- vanixiets reference files are fully analyzed, see subagent outputs in this session\n- setup-nix action is already deployed on this branch stack (pnt-m3t-setup-nix merged into branch)\n- build-nix-image action already had redundant Nix install removed\n- Branch is pnt-5vr-nix2container, branched off pnt-m3t-setup-nix tip\n- Dev containers MUST NOT be touched — only production containers and manifest tooling","created_at":"2026-02-03T02:52:29Z"},{"id":4,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02 (continued)\n\nCompleted:\n- Added nix2container flake input, removed flocken as direct input\n- Created nix/lib/mk-multi-arch-manifest.nix (ported from vanixiets, generalized with mkSourceUri for mixed transport)\n- Added minimal CLI entrypoint to pnt-cli (main() exercising pyo3 greet/add bindings)\n- Defined pnt-cli production container via nix2container.buildImage with 2-layer strategy\n- Replaced flocken manifests with crane-based manifests for all containers (production: nix: transport, dev: docker-archive: transport)\n- Added containerMatrix flake output for CI matrix generation\n- Refactored build-nix-images.yaml to 3-job pattern (discover/build/manifest)\n- Removed obsolete build-nix-image composite action\n- Updated ci.yaml and package-release.yaml callers\n- Added justfile container recipes (build/load/push for production and dev, matrix display)\n\nKnown limitations:\n- Production containers built natively per-system (not pkgsCross) due to Python + maturin + Cargo cross-compilation complexity\n- docker-archive: transport for dev container manifests not yet tested against crane index append (may need validation)\n- Dev containers in CI still limited to x86_64-linux only (NIX_IMAGE_SYSTEMS override)\n\nRemaining for verification:\n- Linux builder needed to test actual container image builds (nix build .#pnt-cliProductionImage)\n- CI workflow run to validate end-to-end (discover -> build -> manifest push)\n- Verify docker-archive: transport works with skopeo + crane manifest list creation","created_at":"2026-02-03T03:52:51Z"},{"id":5,"issue_id":"pnt-5vr","author":"Cameron Smith","text":"Checkpoint: session 2026-02-02 (CI refactoring)\n\nDone:\n- Fixed template test failure: added [project] and [tool.uv.workspace] to root pyproject.toml\n- Simplified template.yaml: replaced GitGuardian with setup-nix action, removed scan/set-variables jobs\n- Created scripts/ci/ci-build-category.sh for category-based matrix builds\n- Added justfile recipes: ci-build-category, scan-secrets, scan-staged, preview-version, release-package\n- Added gitleaks to devshell for local/CI parity\n- Refactored ci.yaml: replaced omnix/nixci with 3-entry category matrix (packages, checks, devshells), replaced GitGuardian with gitleaks via nix develop, added flake-validation and bootstrap-verification jobs, added preview-release-version job, reduced top-level permissions to contents:read\n- Refactored package-release.yaml: replaced setup-uv and setup-yarn actions with nix develop via setup-nix, added cached-ci-job support, fixed artifact upload path\n- Fixed permissions chain: build-nix-images.yaml needs packages:write from callers, added to build-pr-images and test-release-packages\n\nRemaining:\n- CI run verification: latest push (4bc84a3) should resolve startup_failure from permissions chain. Need to verify CI passes end-to-end.\n- Iterative fixes: if nix category builds or test-release-packages fail at runtime, diagnose from logs and fix\n- Close pnt-5vr once CI confirmed working\n- Container workflow 3-job pattern (discover -> build -> manifest) not yet tested in CI\n\nContext for next agent:\n- Branch is pnt-5vr-nix2container with PR #44\n- The CI architecture now matches vanixiets/typescript-nix-template patterns\n- Three parallel startup_failures were caused by permissions chain issues (build-nix-images.yaml declares packages:write at workflow level, GitHub validates entire call chain at parse time)\n- run 21617100530 was from an intermediate push before the full refactoring landed\n- The secrets-scan job uses nix develop -c just scan-secrets (gitleaks is in devshell)\n- The nix job uses a static 3-entry matrix calling just ci-build-category\n- package-release.yaml now uses nix develop for all tool access (yarn, uv)\n- To check CI: gh run list --workflow \"CI/CD\" --limit 3 --repo sciexp/python-nix-template\n- To download logs: gh api \"repos/sciexp/python-nix-template/actions/runs//logs\" > logs.zip","created_at":"2026-02-03T04:45:03Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-5wx","title":"Add rust-toolchain.toml for explicit Rust version","description":"Add explicit rust-toolchain.toml to provide Rust version specification outside of Nix context.\n\nReference: ~/projects/rust-workspace/ironstar/rust-toolchain.toml\n\nImplementation:\n- Create rust-toolchain.toml with channel matching flake.nix Rust version\n- Include components: rustfmt, clippy, rust-analyzer, rust-src\n- Verify version consistency with flake.nix Rust specification\n\nThis helps IDEs and standalone Rust tools work correctly without requiring Nix.\n\nScope: ~15 minutes","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:47.549292-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:06:29.635123-05:00","closed_at":"2026-02-05T15:06:29.635123-05:00","close_reason":"Implemented in a0dd498","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-6yk","title":"Remove teller references and cleanup","description":"Remove outdated teller references since the project has migrated to sops-nix.\n\nChanges needed:\n- Update README.md: change 'teller shell' to 'sops environment' in the check-secrets recipe documentation\n- Verify if teller package in modules/devshell.nix is still needed; remove if unused since sops is the actual secrets manager\n- Search for any other teller config remnants and remove them\n\nScope: ~30 minutes","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:43.905379-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:06:11.313308-05:00","closed_at":"2026-02-05T15:06:11.313308-05:00","close_reason":"Implemented in 1dc676c","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-8um","title":"Align setup-nix action with vanixiets canonical","description":"Bring .github/actions/setup-nix/action.yml and all workflow call sites into alignment with vanixiets. Keep extra-conf as pnt-specific extension. Remove extra-pull-names. Update action pins, restore type annotations and inline comments.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T01:24:30.820655-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T01:29:00.587728-05:00","closed_at":"2026-02-16T01:29:00.587728-05:00","close_reason":"Implemented in 9bdc018..a53ced8 on branch pnt-8um-align-setup-nix","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-btz","title":"pyo3/Rust extension integration","description":"Add Rust extension module support via maturin + pyo3, demonstrating Nix build integration with crane cargoArtifacts sharing and uv2nix overlay composition.\n\nArchitecture documented in: docs/notes/architecture/crane-uv2nix-integration.md\n\nKey patterns:\n- Per-package Rust workspace (crates/ inside Python package)\n- crane buildDepsOnly for artifact caching\n- uv2nix overlay injection for maturin builds\n- CI matrix with rust-deps/rust-checks/python-wheel categories\n\nReference implementations:\n- ~/projects/rust-workspace/ironstar (crane patterns)\n- ~/projects/planning-workspace/langchain (federated Python)\n","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:41.426256-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:45:01.187149-05:00","closed_at":"2026-02-02T20:45:01.187149-05:00","close_reason":"All 3 children complete. Crane + uv2nix + maturin integration fully operational.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-btz.1","title":"Create pnt-cli package scaffold with Rust crates","description":"Create packages/pnt-cli/ with federated structure:\n\nDirectory structure:\n- packages/pnt-cli/pyproject.toml (maturin build-backend, manifest-path binding)\n- packages/pnt-cli/src/pnt_cli/__init__.py (Python wrapper)\n- packages/pnt-cli/crates/Cargo.toml ([workspace] with member crates)\n- packages/pnt-cli/crates/pnt-cli-core/Cargo.toml (pure Rust library)\n- packages/pnt-cli/crates/pnt-cli-py/Cargo.toml (pyo3 bindings, depends on core)\n\npyproject.toml configuration:\n- [build-system] requires maturin>=1.5\n- [tool.maturin] manifest-path = \"crates/pnt-cli-py/Cargo.toml\"\n- [tool.maturin] module-name = \"pnt_cli._native\"\n\nMinimal proof-of-concept: expose a simple function from Rust to Python.\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:17.885691-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:30:16.311977-05:00","closed_at":"2026-02-02T20:30:16.311977-05:00","close_reason":"Implemented in a3e79c3. Scaffold verified: cargo check, cargo test (2/2 pass), cargo clippy clean.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-btz.2","title":"Implement crane + uv2nix Nix modules","description":"Create Nix modules implementing the crane + uv2nix integration pattern.\n\nFiles to create:\n- nix/packages/pnt-cli/rust.nix (crane configuration)\n- nix/packages/pnt-cli/default.nix (Python + Rust composition)\n- nix/modules/rust/lib.nix (shared crane utilities, optional)\n\nrust.nix pattern:\n- crane-lib.buildDepsOnly for cargoArtifacts caching\n- commonArgs pattern for derivation hash consistency\n- crane-lib.vendorCargoDeps for maturin's cargo invocation\n- Export cargoArtifacts, cargoVendorDir, clippy, nextest\n\ndefault.nix pattern:\n- Import rust.nix\n- Create overlay injecting cargoVendorDir and CARGO_TARGET_DIR\n- Export overlay and checks for flake composition\n\nUpdate nix/modules/python.nix:\n- Load pnt-cli workspace independently (federated pattern)\n- Compose Rust overlay with uv2nix overlays\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:18.885252-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:41:16.274515-05:00","closed_at":"2026-02-02T20:41:16.274515-05:00","close_reason":"Implemented in 8d8a814. Crane checks (clippy, nextest) build. Full maturin wheel builds via nix build .#default. Python import verified: greet('nix') and add(2,3) work end-to-end.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-btz.3","title":"Validate integration and update CI","description":"Validate the full crane + uv2nix + maturin integration and update CI.\n\nValidation checklist:\n- [ ] nix build .#pnt-cli produces working wheel\n- [ ] Python import succeeds: from pnt_cli._native import ...\n- [ ] Rust changes trigger minimal rebuilds (cargoArtifacts cached)\n- [ ] Python-only changes don't rebuild Rust\n- [ ] cargoClippy and cargoNextest checks pass\n\nCI updates (.github/workflows/ci.yaml):\n- Add rust-deps matrix category for cargoArtifacts caching\n- Add rust-checks matrix category for clippy/nextest\n- Ensure proper cache key based on Cargo.lock hash\n- Follow ironstar CI matrix pattern\n\nDocumentation updates:\n- Add usage example to README\n- Document development workflow (uv sync + maturin develop vs nix build)\n- Note editable install limitations\n\nSee: docs/notes/architecture/crane-uv2nix-integration.md\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:55:19.746622-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T20:44:56.18025-05:00","closed_at":"2026-02-02T20:44:56.18025-05:00","close_reason":"Validated in 1b7b12e. All acceptance criteria pass: nix build produces working wheel, Python import succeeds, clippy/nextest checks pass, justfile recipes work via nix develop -c. CI updated with Rust path filters and hash-sources.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-bxq","title":"Fix template instantiation workflow and documentation","description":"Fix CI template.yaml workflow and improve instantiation documentation.\n\nCRITICAL: The current template.yaml workflow expects pytest to run from repo root, which FAILS in the federated monorepo pattern (no root pyproject.toml). Must update to use 'just test-all' instead.\n\nReference: ~/projects/sciexp/pnt-mono-8dbebca/python-nix-template-instantiation-experience-8dbebca.md documents the instantiation pain points and experience.\n\nCode changes:\n- Update .github/workflows/template.yaml to use 'nix develop -c just test-all' instead of expecting pytest from repo root\n\nDocumentation improvements:\n- Add explicit 'uv lock' post-instantiation step in README (each package needs individual locking)\n- Clarify this is independent-lock pattern, NOT uv workspaces\n- Add cachix cache creation guidance for instantiated projects\n- Document domain-organized package structure for multi-domain monorepos (like sciexp/data with io/, lake/, mesh/ subdirectories)\n- Consider omnix post-init hook for auto-locking packages if feasible\n\nScope: ~2 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:57.902854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:10:28.749501-05:00","closed_at":"2026-02-05T15:10:28.749501-05:00","close_reason":"Implemented in 38e7d56","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-cu0","title":"Replace maturin-action with nix-native wheel builds","description":"The current wheel-build.yaml uses PyO3/maturin-action@v1 and actions/setup-python@v5, third-party GitHub Actions with no local testing parity. The preferred pattern across the ecosystem (vanixiets, typescript-nix-template) is nix develop -c just [recipe] so that builds are reproducible locally, on any machine, and in CI.\n\nResearch these reference implementations for Nix-native maturin/crane wheel building:\n- ~/projects/nix-workspace/pyperscan-uses-crane-maturin (crane + maturin integration)\n- ~/projects/nix-workspace/crane-maturin (dedicated crane-maturin library)\n- ~/projects/maturin (maturin source with Nix build examples)\n\nDesign an approach consistent with uv2nix, pyproject.nix, and crane that could produce cross-platform wheels via nix build or nix develop -c just build-wheels. The goal: replace everything in wheel-build.yaml except the actions/checkout and actions/upload-artifact steps with a single nix develop -c just build-wheels invocation.\n\nConsiderations:\n- Cross-compilation targets: linux-x86_64, linux-aarch64, macos-x86_64, macos-aarch64\n- Whether Nix cross-compilation can replace the current multi-runner matrix strategy\n- Integration with crane vendorCargoDeps for offline builds\n- How pyproject.nix and uv2nix handle maturin wheel metadata\n- Whether sdist generation should also be Nix-native","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-04T20:34:33.483691-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T21:09:15.823081-05:00","closed_at":"2026-02-04T21:09:15.823081-05:00","close_reason":"Research confirms Nix-native builds cannot produce manylinux-compatible wheels for PyPI. crane-maturin explicitly sets --manylinux off. The hybrid approach (crane-maturin for local/Nix, maturin-action for PyPI) implemented in pnt-wbq is the correct architecture. No further action needed.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre","title":"Infrastructure alignment","description":"Align Makefile, justfile, scripts/, and CI with vanixiets and typescript-nix-template patterns. Makefile bootstrap-only, grouped justfile recipes, cached-ci-job CI pattern, omnix template integration.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:39.841346-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:56:26.823947-05:00","closed_at":"2026-02-02T15:56:26.823947-05:00","close_reason":"All children closed: pnt-dre.1 (Makefile), pnt-dre.2 (justfile), pnt-dre.3 (scripts), pnt-dre.4 (cached-ci-job/CI), pnt-dre.5 (omnix template). Infrastructure alignment complete.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre.1","title":"Refactor Makefile to bootstrap-only pattern","description":"Restrict Makefile to bootstrap targets only: install-nix, install-direnv, verify, setup-user, check-secrets, clean. Move all other targets to justfile.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:54.237851-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:39:45.088007-05:00","closed_at":"2026-02-02T15:39:45.088007-05:00","close_reason":"Added verify, setup-user, check-secrets targets aligned with vanixiets. Updated bootstrap output with numbered next-steps. Makefile was already bootstrap-only; no targets removed.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre.2","title":"Adopt grouped justfile recipe pattern","description":"Reorganize justfile with grouped recipes and section headers following vanixiets pattern: nix, python, conda, docs, secrets, ci/cd groups. Add help comments for each recipe.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:55.145094-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:42:24.899403-05:00","closed_at":"2026-02-02T15:42:24.899403-05:00","close_reason":"Aligned group naming (conda package→conda, python package→python), fixed Documentation→Docs header, demoted GCP sub-section, corrected type recipe comment, moved helper to EOF.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre.3","title":"Reorganize scripts/ directory structure","description":"Move scripts into subdirectories: scripts/ci/, scripts/docs/, scripts/sops/. IMPORTANT: scripts/bootstrap.sh must remain at stable path for curl one-liner URL. Update justfile and CI references.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:55.839371-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:45:23.076616-05:00","closed_at":"2026-02-02T15:45:23.076616-05:00","close_reason":"Created scripts/bootstrap.sh (stable URL for curl one-liner) and scripts/ci/maximize-build-space.sh (canonical version of duplicated CI logic). Workflow inline references deferred to pnt-dre.4 CI redesign due to pre-checkout step ordering. scripts/sops/ and scripts/docs/ skipped — no duplication issues warranting extraction.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre.4","title":"Implement cached-ci-job composite action pattern","description":"Add .github/actions/cached-ci-job composite action following typescript-nix-template pattern. Content-addressed caching with hash-sources and force-run support. Update CI to use category-based matrix builds.\n\nPost-federation CI adaptation: the migration from uv workspace to per-package independent locks (pnt-4jg.1) means CI must now discover and iterate packages under packages/. The matrix strategy needs a package axis in addition to the category axis, producing either a {package} x {category} matrix or per-package reusable workflow dispatches. Review how ci.yaml currently enumerates packages and ensure the composite action pattern supports per-package resolution of lock files, dependency caches, and build artifacts.\n\nAcceptance criteria:\n- .github/actions/cached-ci-job composite action implemented\n- Content-addressed caching with hash-sources and force-run support\n- CI matrix discovers packages/ dynamically (not hardcoded)\n- Matrix crosses package x category dimensions\n- Per-package uv.lock files used for cache keys (not root lock)\n- Category-based builds follow typescript-nix-template pattern","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:56.79376-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:55:30.748155-05:00","closed_at":"2026-02-02T15:55:30.748155-05:00","close_reason":"Implemented cached-ci-job composite action (ported from typescript-nix-template), per-package CI justfile recipes (ci-sync, ci-lint, ci-test, ci-typecheck, ci-check, list-packages-json), rewrote python-test.yaml to use nix develop -c just , added dynamic package discovery and force_run to ci.yaml. All CI steps expressible as nix develop -c just .","comments":[{"id":2,"issue_id":"pnt-dre.4","author":"Cameron Smith","text":"Minimal CI path fixes applied in d0cab2a as part of pnt-4jg.1 fixups: cache-dependency-glob updated to packages/*/uv.lock, uv sync/lint/test moved into per-package working-directory, ci.yaml path filters updated.\n\nRemaining for pnt-dre.4: replace setup-python/setup-uv actions with nix develop -c just pattern, add justfile recipes for per-package sync/test/lint/typecheck, implement cached-ci-job composite action, dynamic package discovery.","created_at":"2026-02-02T20:17:02Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dre.5","title":"Add omnix template integration","description":"Configure om.templates in flake with parameter definitions. Add template-verify justfile recipe. Create .github/workflows/template.yaml for CI validation.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-01-19T11:54:57.668262-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T15:56:15.624906-05:00","closed_at":"2026-02-02T15:56:15.624906-05:00","close_reason":"om.templates, template-verify recipe, and template.yaml workflow already existed. Fixed stale path-ignore filters for per-package lock pattern.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-dtx","title":"Simplify .envrc and remove set-git-env indirection","description":"Replace 41-line .envrc with 15-line version matching reference repos. Move git metadata exports to devshell shellHook as direct exports. Delete modules/git-env.nix. Remove set-git-env from devshell packages and shellHook.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T22:46:42.329044-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T22:49:14.40069-05:00","closed_at":"2026-02-05T22:49:14.40069-05:00","close_reason":"Simplified .envrc from 41 to 14 lines, inlined git metadata exports, removed git-env.nix. 94f3298","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-e06","title":"Fix crane version placeholder warning in pnt-cli nix derivation","description":"crane-maturin's buildMaturinPackage invokes crateNameFromCargoToml which cannot resolve version from the workspace-only Cargo.toml during the dummySrc phase. Pass version explicitly by reading it from the workspace Cargo.toml via builtins.fromTOML.","status":"closed","priority":2,"issue_type":"bug","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-16T21:04:25.204989-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T21:04:58.049709-05:00","closed_at":"2026-02-16T21:04:58.049709-05:00","close_reason":"Implemented in 8901dd5","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-edl","title":"Modernize nix module architecture and template validation","description":"Migrate python-nix-template to dendritic flake-parts architecture (import-tree) matching vanixiets, ironstar, and typescript-nix-template conventions. Fix template.yaml workflow to properly validate instantiated templates including PyO3/maturin extensions.\n\nMotivation: Current nix/modules/ uses hand-rolled readDir discovery instead of import-tree. Template CI test (test-omnix-template) fails because it runs nix develop -c pytest which cannot load PyO3 _native extension (maturin packages are excluded from editableOverlay by design). Both issues block PR #44 from being fully validated.\n\nReference implementations:\n- vanixiets: modules/ with import-tree, 200+ auto-discovered modules\n- ironstar: modules/ with import-tree, crane for Rust builds\n- typescript-nix-template: modules/ with import-tree, two-variant template testing\n\nSequencing: Migration first (structural), then template workflow fix (validation). Template test depends on knowing the final module layout.","status":"closed","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:09:57.390595-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T17:47:25.690809-05:00","closed_at":"2026-02-03T17:47:25.690809-05:00","close_reason":"All children complete: pnt-j6f (dendritic flake-parts migration), pnt-3qp (test strategy validation), pnt-m1w (template workflow fix). Nix module architecture modernized with import-tree and conditional package composition.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-h2o","title":"Migrate from yarn to bun monorepo for semantic-release tooling","description":"The python-nix-template currently uses yarn@4.6.0 as its JavaScript package manager for semantic-release tooling, while vanixiets and typescript-nix-template both use bun@1.3.4. This divergence:\n- Complicates porting scripts between repositories (e.g., preview-version.sh needed bun-to-yarn adaptation)\n- Means the python-nix-template cannot use the exact same scripts/preview-version.sh as the other repos\n- Introduces yarn-specific configuration (.yarnrc.yml, yarn.lock) that differs from the ecosystem standard\n\nMigration scope:\n- Replace yarn.lock with bun.lockb\n- Update packageManager field in all package.json files from yarn to bun\n- Update all justfile recipes that reference yarn (preview-version, release-package, test-package-release, etc.)\n- Update scripts/preview-version.sh to use bun instead of yarn\n- Update CI workflows referencing yarn\n- Remove .yarnrc.yml and yarn-specific configuration\n- Verify semantic-release, semantic-release-monorepo, and all plugins work correctly under bun\n\nReference: vanixiets and typescript-nix-template for the target bun configuration.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-04T20:34:43.898129-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T21:09:06.495921-05:00","closed_at":"2026-02-04T21:09:06.495921-05:00","close_reason":"Implemented in 06324ed. Migrated from yarn@4.6.0 to bun@1.3.4 across devShell, package.json (root + 3 packages), justfile, preview-version.sh, CI workflows, gitignore, and gitattributes.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-h2q","title":"Remove nixpkgs follows from pyproject-nix chain to restore cache hits","description":"The pyproject-nix, uv2nix, and pyproject-build-systems inputs all declare inputs.nixpkgs.follows = nixpkgs, which forces them to use our nixpkgs revision. Since pyproject-nix.cachix.org builds against their own pinned nixpkgs, the follows override causes derivation hash mismatches, forcing source rebuilds of maturin, python-libcst, and other build-system packages.\n\nRemove the nixpkgs follows from all three inputs while keeping the internal cross-references (pyproject-build-systems.inputs.pyproject-nix.follows and .uv2nix.follows) since those are co-released.\n\nBefore: source rebuilds of maturin/libcst on every devshell entry.\nAfter: cache hits from pyproject-nix.cachix.org for build-system packages.\nTradeoff: second nixpkgs evaluation during flake eval (acceptable for build tool cache hits).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:30.164416-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:04:48.434561-05:00","closed_at":"2026-02-03T18:04:48.434561-05:00","close_reason":"Implemented in e3a9997","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-j6f","title":"Migrate to dendritic flake-parts with import-tree","description":"Restructure nix module architecture to match reference implementations (vanixiets, ironstar, typescript-nix-template).\n\nChanges required:\n- Add import-tree as flake input (github:vic/import-tree or equivalent)\n- Move nix/modules/*.nix to modules/*.nix (top-level)\n- Replace readDir-based discovery in flake.nix with: flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules)\n- Add systems.nix module (extract system list from flake.nix)\n- Add flake-parts.nix module (external module imports like nix-unit)\n- Keep nix/packages/pnt-cli/ and nix/lib/ as non-module utilities (imported explicitly by python.nix)\n- Update all relative paths in modules that reference nix/packages/ or nix/lib/ (now one level up)\n- containers.nix is 355 lines — evaluate splitting into containers/dev.nix and containers/production.nix\n- Update template.nix conditional paths to reflect new module locations\n- Verify nix flake check passes after restructure\n- Update .github/workflows/ path filters if they reference nix/modules/\n\nKey architectural decisions:\n- Modules communicate through _module.args (python.nix exports) and config namespace (pre-commit.devShell)\n- import-tree auto-discovers all .nix files in modules/ tree\n- No manual imports list in flake.nix — adding a file to modules/ auto-includes it\n- nix/packages/ stays as explicit utility imports (not auto-discovered modules)","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:10:03.187287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T11:07:43.74843-05:00","closed_at":"2026-02-03T11:07:43.74843-05:00","close_reason":"Implemented in b27f3c8. Dendritic migration, root pyproject.toml removal, ruff.toml, per-package justfile recipes, editable root fix.","comments":[{"id":6,"issue_id":"pnt-j6f","author":"Cameron Smith","text":"Removing root pyproject.toml: vestigial workspace declaration contradicts federation model in python.nix","created_at":"2026-02-03T16:01:31Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-m1w","title":"Fix template.yaml workflow for proper PyO3 and multi-variant validation","description":"Align template.yaml with typescript-nix-template patterns and fix the test-omnix-template job.\n\nRoot cause resolved (pnt-3qp): The PyO3 _native import failure was caused by pytest collecting tests from the source namespace, shadowing the installed wheel. Fixed by relocating pnt-cli tests to tests/ (outside src/). The editable overlay root was also fixed to use per-package paths ($REPO_ROOT/packages/).\n\nRemaining work:\n- Replace nix develop -c pytest with nix flake check --accept-flake-config in template test\n- nix flake check exercises all Nix builds including maturin wheel, validating PyO3 integration\n- Add set-variables job (debug flags, skip-ci, checkout details)\n- Test TWO variants matching monorepo-package boolean parameter:\n 1. Full monorepo (monorepo-package=true): includes pnt-functional + pnt-cli\n 2. Single package (monorepo-package=false): main package only\n- Fix cachix reference: instantiated template tries pnt-mono.cachix.org which 401s (expected for fresh project, but should be parameterized or removed)\n- Consider adding lightweight smoke test after flake check: nix develop -c python -c 'import pnt_mono'\n- Root pyproject.toml has been removed; template assertion now checks ruff.toml\n- Per-package justfile recipes are now the standard pattern (test, lint, type take package parameter)\n\nReference: typescript-nix-template .github/workflows/template.yaml tests full and minimal variants with git init, bun install, nix flake check sequence.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T10:10:08.916223-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T17:47:13.700141-05:00","closed_at":"2026-02-03T17:47:13.700141-05:00","close_reason":"Implemented in 3a0873e. Template workflow single-package variant fixed via builtins.pathExists guard on pnt-functional references in modules/python.nix. Both Template and CI/CD workflows passing.","comments":[{"id":7,"issue_id":"pnt-m1w","author":"Cameron Smith","text":"Checkpoint: 2026-02-03 session\n\nDone:\n- Rewrote template.yaml aligned with typescript-nix-template pattern\n- Added set-variables job, cached-ci-job integration, workflow-level concurrency, force_run input\n- Replaced nix develop -c pytest with nix flake check + import smoke tests\n- Fixed per-package uv lock (federation model has no root pyproject.toml)\n- Disabled dev containers (catppuccin-starship build failure via nixpod) to unblock nix flake check\n- Archived dev container code to nix/disabled/containers-dev.nix.txt\n- Removed nixpod flake input and dev container justfile recipes\n\nRemaining:\n- CI run 21646259884 is in progress, needs to pass\n- If CI passes: close pnt-m1w and pnt-edl\n- If CI fails: debug and iterate\n\nCommits this session: 5eaab99..ee0295d (7 commits)","created_at":"2026-02-03T20:19:44Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-m3t","title":"Adopt setup-nix composite action with nothing-but-nix pattern","description":"Port the vanixiets setup-nix composite action to python-nix-template, replacing inline Nix installation across all workflows.\n\nCurrent state:\n- ci.yaml, python-test.yaml, build-nix-images.yaml each inline DeterminateSystems/nix-installer-action\n- build-nix-images.yaml uses ad-hoc maximize-build-space shell script\n- scripts/ci/maximize-build-space.sh exists but is not wired into workflows\n\nTarget state (matching vanixiets):\n- .github/actions/setup-nix/action.yml composite action\n- Uses wimpysworld/nothing-but-nix for space reclamation (replaces maximize-build-space.sh)\n- Uses cachix/install-nix-action with pinned Nix version\n- Configures build-dir = /nix/build (nothing-but-nix workaround)\n- Integrates magic-nix-cache and cachix setup\n- Hatchet protocol support for configurable space levels\n- All workflows delegate Nix setup to this single action\n\nAcceptance criteria:\n- .github/actions/setup-nix/action.yml implemented (port from vanixiets)\n- ci.yaml nixci job uses setup-nix action\n- python-test.yaml uses setup-nix action\n- build-nix-images.yaml uses setup-nix action (replaces inline maximize-build-space)\n- .github/actions/build-nix-image/ updated (its Nix install steps replaced by setup-nix)\n- scripts/ci/maximize-build-space.sh removed (superseded by nothing-but-nix)\n- setup-python-uv action evaluated for removal (if all Python CI runs via nix develop)\n\nReference: ~/projects/nix-workspace/vanixiets/.github/actions/setup-nix/action.yml","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T20:24:06.14337-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T21:16:20.627824-05:00","closed_at":"2026-02-02T21:16:20.627824-05:00","close_reason":"Implemented in 0b1e4fa, setup-nix action ported from vanixiets","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-m7j","title":"Sync mergify.yml with vanixiets/typescript-nix-template patterns","description":"Upgrade mergify.yml from basic 26-line config to full-featured ~120-line config matching vanixiets and typescript-nix-template patterns.\n\nReference files:\n- ~/projects/nix-workspace/vanixiets/.github/mergify.yml\n- ~/projects/nix-workspace/typescript-nix-template/.github/mergify.yml\n\nChanges needed:\n- Add YAML anchors for base_conditions, required_checks, human_author_conditions, bot_author_conditions\n- Expand required_checks to cover all CI jobs (secrets-scan, set-variables, check-fast-forward, flake-validation, bootstrap-verification, etc.)\n- Split pull_request_rules into separate rules for human vs bot authors\n- Create separate queue rules: default for humans (batch_size: 1), bot-updates for bots (batch_size: 10)\n- Update checks_timeout format to match vanixiets pattern\n\nScope: ~2 hours","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T13:47:53.370062-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T15:07:28.214895-05:00","closed_at":"2026-02-05T15:07:28.214895-05:00","close_reason":"Implemented in f369393","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-mgq","title":"Migrate dev containers to nix2container via upgraded nixpod","description":"Update the dev container builds (containerImage, devcontainerImage) to use nix2container once nixpod itself has completed its nix2container migration.\n\nCurrent state:\n- nix/modules/containers.nix imports buildMultiUserNixImage from nixpod\n- nixpod uses dockerTools.buildLayeredImageWithNixDb internally\n- flocken handles multi-arch manifest creation for dev containers\n- Dev containers include multi-user Nix daemon, home-manager activation, s6-overlay\n\nBlocked on: nixpod completing its nix2container migration (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template's dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (from pnt-5vr production container work)\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- Dev containers build using nixpod's nix2container-based API\n- flocken fully removed from flake.nix (production containers handled by pnt-5vr)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n\nReference: ~/projects/nix-workspace/nixpod-home/docs/notes/development/container-build-refactoring.md\nReference: ~/projects/nix-workspace/nixpod-home/containers/nix.nix","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T21:47:38.830624-05:00","created_by":"Cameron Smith","updated_at":"2026-02-02T21:47:38.830624-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-nu7","title":"Add update-flake-inputs workflow and fix Mergify check names","description":"Add the update-flake-inputs GitHub Actions workflow matching the canonical pattern from vanixiets/tnt/ironstar. Fix Mergify check name mismatch for test-python matrix jobs using regex matching. Rename mergify.yml and labeler.yml to .yaml extension. Add flake updater secrets to upload scripts.","status":"in_progress","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-12T15:22:03.939445-05:00","created_by":"Cameron Smith","updated_at":"2026-02-12T15:24:45.602214-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-pzl","title":"Evaluate pkgs-by-name-for-flake-parts adoption for package auto-discovery","description":"Vanixiets uses pkgs-by-name-for-flake-parts for automatic package discovery from pkgs/by-name/. Python-nix-template currently hard-codes package paths in modules/python.nix, requiring manual updates for each new package.\n\nDirect adoption is feasible but python-nix-template packages need Python-specific overlay composition (crane integration, maturin compatibility, editable overlay exclusion). Requires designing a Python-aware discovery layer or adapting the pkgs-by-name pattern to emit overlays rather than standalone derivations.\n\nThis is architectural preparation for multi-package growth. Lower priority than cache and follows fixes.","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T15:48:39.744987-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T18:07:32.63938-05:00","closed_at":"2026-02-03T18:07:32.63938-05:00","close_reason":"Won't-fix: pkgs-by-name auto-discovery is incompatible with uv2nix overlay composition model. Packages are overlays composed into a shared set, not standalone derivations. Two-file Rust pattern (rust.nix + default.nix) also incompatible with single-file-per-package structure.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-rvh","title":"Align renovate config with ecosystem conventions","description":"Migrate .github/renovate.json from minimal config:base to full ecosystem pattern matching typescript-nix-template and ironstar. Subsumes Renovate auto-migration PR #69.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-12T15:49:19.073091-05:00","created_by":"Cameron Smith","updated_at":"2026-02-12T15:53:21.231244-05:00","closed_at":"2026-02-12T15:53:21.231244-05:00","close_reason":"Implemented in cbf07c5","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wbq","title":"Cross-compile and release pnt-cli wheels for all major platforms via crane pkgsCross","description":"Build and release platform-specific Python wheels for pnt-cli (PyO3/maturin package with Rust extension modules) across all four major targets: x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin.\n\nCurrent state: pnt-cli builds and tests on a single platform via hand-rolled crane + maturin + uv2nix overlay composition (nix/packages/pnt-cli/rust.nix and default.nix). It has never been released. semantic-release is configured in packages/pnt-cli/package.json but predicts no pending release.\n\nResearch findings: Nix pkgsCross is not viable for PyPI wheel distribution. No project in the ecosystem uses Nix cross-compilation to produce manylinux-compatible wheels. The industry standard is GitHub Actions + maturin-action with manylinux containers for Linux and native runners for macOS. crane-maturin (vlaci/crane-maturin) provides a thin wrapper over crane that eliminates hand-rolled boilerplate for maturin builds.\n\nScope (three phases):\n\nPhase A — crane-maturin refactor (no new capabilities):\n- Add vlaci/crane-maturin as flake input (pinned)\n- Replace nix/packages/pnt-cli/rust.nix + default.nix with single buildMaturinPackage call via mkLib\n- Update modules/python.nix overlay composition to use crane-maturin's output pattern\n- Verify nix flake check and nix develop -c pytest pass for all 3 packages\n- Benefit: automatic two-phase cargo caching, PYO3_PYTHON handling, passthru.tests (pytest, clippy, doc, fmt, test, audit)\n\nPhase B — CI wheel build workflow (new capability):\n- New workflow: .github/workflows/wheel-build.yaml\n- Matrix: linux-x86_64, linux-aarch64, macos-x86_64, macos-aarch64\n- Linux: maturin-action with manylinux: auto (pure Rust, no custom containers needed)\n- macOS: native runners (macos-15 for arm64)\n- Python 3.12 only (template users extend as needed)\n- Artifact upload per platform\n- Concrete for pnt-cli but with clear parameterization points (package name, maturin args as workflow variables)\n\nPhase C — release pipeline:\n- Coordinate with existing package-release.yaml\n- Trigger: semantic-release creates tag → dispatches wheel builds → collects artifacts\n- Publish to PyPI via uv publish with trusted publishing (OIDC)\n- Include sdist alongside wheels\n- Existing packages/pnt-cli/package.json semantic-release config drives versioning\n\nReference implementations:\n- ~/projects/nix-workspace/crane-maturin — vlaci/crane-maturin source (mkLib API, buildMaturinPythonPackage.nix)\n- ~/projects/nix-workspace/pyperscan-uses-crane-maturin — flake.nix overlay pattern, CI workflow structure\n- pydantic-core, polars, cryptography — industry standard maturin-action CI patterns\n\nOut of scope:\n- Nix cross-build outputs (nix build .#packages.aarch64-linux.pnt-cli from x86_64-linux) — separate concern\n- Multiple Python version matrix — start with 3.12, extend later\n- omnix template parameterization — edit-in-place customization","status":"closed","priority":3,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-02T23:00:13.965286-05:00","created_by":"Cameron Smith","updated_at":"2026-02-04T15:21:02.210086-05:00","closed_at":"2026-02-04T15:21:02.210086-05:00","close_reason":"Implemented across phases A (60894ef), B (b4e9a4c), C (a2b936d, b7441d5).\n\nPhase A: crane-maturin + nixpkgsPrebuilt eliminates dual Rust compilation.\nPhase B: wheel-build.yaml with maturin-action matrix (4 platforms + sdist).\nPhase C: package-release.yaml gains build-wheels pipeline with OIDC trusted publishing.\n\nActivation prerequisites (operational, not code):\n1. Configure PyPI trusted publishing for package-release.yaml workflow in pypi environment\n2. Consider adding @semantic-release/git to pnt-cli package.json to update pyproject.toml version before wheel builds","comments":[{"id":8,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Checkpoint: Phase A complete, Phase B in progress\n\nDone (Phase A — crane-maturin refactor):\n- Moved Cargo workspace root from packages/pnt-cli/crates/ to packages/pnt-cli/ so pyproject.toml and Cargo.toml share the same src root (required by crane-maturin)\n- Added vlaci/crane-maturin as pinned flake input\n- Replaced rust.nix + default.nix with single crane-maturin integration in default.nix\n- Overlay uses hybrid approach: augments uv2nix base via overrideAttrs (preserving pyproject-nix resolver metadata for devShell) while pulling cargoVendorDir and passthru.tests from crane-maturin's standalone buildMaturinPackage\n- nix flake check passes with expanded test suite: pnt-cli-{clippy,doc,fmt,pytest,test(nextest)}\n- nix develop -c python confirms native module loads correctly\n- 3 clean atomic commits: Cargo restructure, flake input, crane-maturin refactor\n\nKey learning:\n- crane-maturin's buildMaturinPackage cannot directly replace the uv2nix overlay entry because pyproject-nix's resolveVirtualEnv needs passthru.dependencies metadata that buildPythonPackage does not produce\n- The hybrid approach works: crane-maturin for standalone build + test suite, uv2nix overrideAttrs for the overlay entry with crane's cargoVendorDir injected via preBuild\n- crane-maturin's `pname` parameter silences crane workspace name warnings\n\nRemaining (Phase B + C):\n- Phase B: wheel-build.yaml with maturin-action matrix (linux + macOS, Python 3.12)\n- Phase C: release pipeline coordination with package-release.yaml\n\nBranch: pnt-wbq-cross-compile-wheels (3 commits ahead of pnt-5vr-nix2container)","created_at":"2026-02-04T18:43:17Z"},{"id":9,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Checkpoint: nixpkgsPrebuilt refactor complete, Phase B pending\n\nDone (Phase A continued):\n- Replaced overrideAttrs overlay with pyproject-nix hacks.nixpkgsPrebuilt\n- Eliminates dual Rust compilation: crane-maturin builds once, nixpkgsPrebuilt adapts for uv2nix resolver\n- Added workspace.metadata.crane.name to silence placeholder warnings\n- Validated: nix flake check (6/6), nix develop -c pytest (2/2), nix build .#default all pass\n- Confirmed nixpkgsPrebuilt preserves passthru.dependencies for mkVirtualEnv\n\nKey learning:\n- pyproject-nix's hacks.nixpkgsPrebuilt is the correct adapter between nixpkgs buildPythonPackage outputs and pyproject-nix package sets\n- The previous overrideAttrs approach compiled Rust twice (once in cmPackage, once in the overlay via pyprojectHook + maturin)\n- nixpkgsPrebuilt strips nixpkgs propagation/wrapping and copies site-packages, taking passthru from prev\n- Cargo workspace-only root pattern (no [package] in root Cargo.toml) works with crane-maturin via manifest-path in pyproject.toml\n\nRemaining (Phase B + C):\n- Phase B: wheel-build.yaml with maturin-action matrix (linux + macOS, Python 3.12)\n- Phase C: release pipeline coordination with package-release.yaml\n\nBranch: pnt-wbq-cross-compile-wheels (4 commits ahead of pnt-yty-cloudflare-docs-alignment)","created_at":"2026-02-04T20:06:38Z"},{"id":10,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Phase B + C complete\n\nDone (Phase B — wheel-build workflow):\n- Created .github/workflows/wheel-build.yaml with maturin-action\n- Matrix: linux-x86_64 (ubuntu-latest), linux-aarch64 (ubuntu-24.04-arm), macos-x86_64 (macos-15-intel), macos-aarch64 (macos-15)\n- Callable via workflow_dispatch + workflow_call for release pipeline integration\n- Builds sdist + 4 platform wheels, uploads as artifacts (wheels-* pattern)\n- PACKAGE_PATH env var as template customization point\n\nDone (Phase C — release pipeline integration):\n- Added build-wheels input to package-release.yaml (follows build-images pattern)\n- When build-wheels=true: skips single-platform uv build/publish, calls wheel-build.yaml with release tag, then publishes all artifacts via uv publish --trusted-publishing always (OIDC)\n- Added pnt-cli to ci.yaml release-packages matrix with build-wheels: true\n- Existing pure Python packages unaffected (python-nix-template, pnt-functional use existing uv build path)\n\nNote: PyPI trusted publishing requires configuring the OIDC trust relationship on PyPI for the publish-wheels job (environment: pypi). pnt-cli's package.json lacks @semantic-release/git so pyproject.toml version is not updated by semantic-release — this is a pre-existing concern for all packages.\n\nBranch: pnt-wbq-cross-compile-wheels (4 new commits)","created_at":"2026-02-04T20:20:07Z"},{"id":11,"issue_id":"pnt-wbq","author":"Cameron Smith","text":"Post-closure session: release pipeline hardening\n\nInvestigated CI run 21687459543 where all preview-release-version jobs\nfailed silently. Root cause: the preview-version justfile recipe ran\nsemantic-release directly on the PR branch without merge simulation,\nso semantic-release rejected the non-release branch.\n\nImplemented four components to fix the release pipeline:\n\n1. Ported scripts/preview-version.sh from vanixiets (merge simulation\n via git merge-tree, worktree, temporary ref updates, yarn instead\n of bun, GITHUB_OUTPUT integration)\n\n2. Removed @semantic-release/git from all package.json files and\n package-release.yaml. Adopted pre-merge version bump pattern:\n developer runs just update-version as part of the PR.\n\n3. Added version consistency check step to preview-release-version CI\n job. Compares previewed next version against pyproject.toml (and\n Cargo.toml for maturin packages). Fails with actionable message.\n\n4. Added just update-version recipe: per-package aware, handles\n pyproject.toml [project] + [tool.pixi.package], Cargo.toml\n [workspace.package] for maturin packages, runs uv lock.\n\nFixed three CI issues during iteration:\n- yarn.lock out of sync after removing @semantic-release/git\n- ANSI escape codes contaminating version string comparison\n- PyO3 0.23.5 incompatible with Python 3.14 on macos-15 runners\n (pinned to 3.11/3.12 via setup-python + maturin -i flags)\n\nCreated pnt-cli-v0.0.0 base tag on main for semantic-release.\nCommitted wheel-build.yaml to main and rebased feature branch.\nWheel build run 21693930817 triggered for validation.\n\nCommits: 51b2455..6b5ff56 (feature branch, post-rebase)","created_at":"2026-02-05T01:10:45Z"}],"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6","title":"Audit and modernize justfile recipes","description":"Systematic review of all justfile recipes (91 total across 10 groups) to ensure each is functional, correctly grouped, and up-to-date with the current project structure. Recipes should work correctly for all template instantiation variants (single-package, monorepo, with/without pyo3). Cross-cutting concerns include hardcoded repo references, pnt-cli defaults in optional groups, CI/CD group overload, and emoji usage in recipe output.","status":"in_progress","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:10.207237-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T13:20:36.037845-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.1","title":"CI/CD group: audit and restructure recipes","description":"Review and restructure the CI/CD recipe group (23 recipes). This is the largest and most overloaded group, containing at least 4 distinct concerns that should be evaluated for regrouping.\n\nRecipes to evaluate:\n- ci-build-category, list-packages-json, ci-sync, ci-lint, ci-test, ci-typecheck, ci-check (CI matrix and per-package CI)\n- scan-secrets, scan-staged, pre-commit (code quality gates)\n- gcloud-context, ghvars, ghsecrets (infrastructure configuration)\n- list-workflows, test-docs-build, test-docs-deploy (act-based local testing)\n- gh-docs-build, gh-workflow-status, gh-docs-watch, gh-docs-logs, gh-docs-rerun, gh-docs-cancel (GitHub workflow management)\n\nKnown concerns:\n- ghvars and ghsecrets hardcode repo as sciexp/python-nix-template; should derive dynamically or accept parameter without default\n- gh-docs-* recipes (6 recipes) are docs-workflow-specific but live in CI/CD; consider moving to docs group or creating a workflows group\n- ci-sync/ci-lint/ci-test/ci-typecheck/ci-check duplicate Python group recipes with uv run prefix; clarify when to use which\n- gcloud-context recipe references GCP_PROJECT_NAME env var but may be stale\n- list-workflows depends on act which may not be in all devshells\n\nDone means: each recipe tested or removed, group split if warranted, hardcoded values parameterized, descriptions updated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:21.926844-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:21.926844-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.10","title":"Template group: audit and update recipes","description":"Review the Template recipe group (2 recipes).\n\nRecipes to evaluate:\n- template-init, template-verify\n\nKnown concerns:\n- template-init just echoes a command rather than executing it; consider making it executable or documenting why it is echo-only\n- template-init hardcodes omnix version v1.3.2 and github:sciexp/python-nix-template; should be parameterized or use a variable\n- template-verify uses om init which requires omnix; verify om is in devshell\n- template-verify creates tmp-verify-template directory; verify cleanup works if nix flake check fails (no trap)\n- Group is small; may need minimal changes\n\nDone means: each recipe tested, hardcoded values parameterized, cleanup robustness verified.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:34.025883-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:34.025883-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.11","title":"Remove emoji characters from justfile recipe output","description":"Multiple recipes across the justfile use emoji characters in their output messages. This contradicts the project style conventions which prohibit emoji usage.\n\nAffected recipes (non-exhaustive):\n- validate-secrets: uses checkmark and cross emojis\n- sops-init: uses checkmark emoji\n- sops-add-key: uses checkmark, warning, and cross emojis\n- set-secret: uses checkmark emoji\n- rotate-secret: uses checkmark emoji\n- gcp-enable-drive-api: uses checkmark and warning emojis\n- gcp-sa-create: uses checkmark emoji\n- gcp-sa-storage-user: uses checkmark and warning emojis\n- gcp-sa-key-encrypt: uses checkmark emoji\n- gcp-sa-key-delete: uses checkmark emoji\n- updatekeys: uses checkmark emoji\n- export-secrets: writes comment header\n- conda-check: uses ANSI color code (green) for success message\n- data-sync: uses checkmark emoji\n\nReplace with plain text status indicators (e.g., 'OK', 'PASS', 'FAIL', 'WARN') or remove decorative output entirely.\n\nDone means: no emoji characters remain in justfile, output messages use plain text.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:43.267932-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:43.267932-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.12","title":"Parameterize hardcoded repository references in justfile","description":"Several justfile recipes contain hardcoded references to sciexp/python-nix-template that should be derived dynamically or parameterized for template portability.\n\nAffected recipes:\n- ghvars: defaults repo to sciexp/python-nix-template\n- ghsecrets: defaults repo to sciexp/python-nix-template\n- template-init: hardcodes github:sciexp/python-nix-template and omnix version v1.3.2\n\nConsider using a justfile variable at the top of the file that derives the repo from git remote, or at minimum remove the default so users must explicitly provide their repo name.\n\nDone means: no hardcoded sciexp/python-nix-template references remain as defaults in recipes.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:51.216525-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:51.216525-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.13","title":"Evaluate conditional recipe availability for optional features","description":"Recipes in the Containers and Rust groups default to pnt-cli which only exists in pyo3-enabled template instantiations. When the template is instantiated without pyo3 support, these recipes have no valid default target and will fail.\n\nAffected groups:\n- Containers (4 recipes): all default CONTAINER=pnt-cli\n- Rust (5 recipes): all default package=pnt-cli\n\nOptions to evaluate:\n1. Remove defaults entirely so users must specify the package name\n2. Use justfile conditionals or shell checks to detect available packages\n3. Document these groups as pyo3-only with clear prerequisites\n4. Consider generating justfile sections based on template parameters\n\nThis issue should be addressed after the per-group audits (pnt-wl6.3 and pnt-wl6.8) have identified the full scope of the problem.\n\nDone means: a decision is made and implemented for how optional-feature recipes behave in instantiations that lack those features.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:05:00.45547-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:05:00.45547-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.14","title":"Clarify relationship between CI/CD and Python group recipes","description":"The CI/CD group contains per-package recipes (ci-sync, ci-lint, ci-test, ci-typecheck, ci-check) that duplicate Python group recipes (uv-sync/lint/test/type/check) with the addition of uv run prefix.\n\nCI/CD group versions use 'uv run' prefix (e.g., cd packages/{package} && uv run pytest).\nPython group versions use bare tool invocation (e.g., cd packages/{package} && pytest).\n\nThe distinction is presumably that CI/CD recipes work in a clean environment where tools need uv run to resolve, while Python group recipes assume the devshell provides tools directly. However this is not documented and the naming overlap is confusing.\n\nOptions to evaluate:\n1. Remove CI/CD per-package recipes and have CI call Python group recipes (if devshell provides tools)\n2. Keep both but rename to clarify context (e.g., local vs ci)\n3. Document the distinction in recipe comments\n4. Unify by always using uv run (works in both contexts)\n\nThis issue should be addressed after both pnt-wl6.1 and pnt-wl6.6 audits.\n\nDone means: the duplication is resolved or clearly documented with rationale.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:05:16.265644-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:05:16.265644-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.2","title":"Conda group: audit and update recipes","description":"Review the Conda/pixi recipe group (9 recipes).\n\nRecipes to evaluate:\n- conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check\n\nKnown concerns:\n- All recipes default to package=python-nix-template; evaluate whether this is the right default or should be dynamic\n- conda-lock description says 'Update conda environment' which is misleading (it exports conda-explicit-spec)\n- pixi-lock description says 'Update pixi lockfile' but actually runs pixi list and pixi tree (no locking)\n- Verify pixi environments (test, lint, types) exist in package pyproject.toml\n- Verify pixi is available in devshell\n\nDone means: each recipe tested, misleading descriptions corrected, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:29.630916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:29.630916-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.3","title":"Containers group: audit and update recipes","description":"Review the Containers recipe group (4 recipes).\n\nRecipes to evaluate:\n- container-build-production, container-load-production, container-push-production, container-matrix\n\nKnown concerns:\n- All parameterized recipes default to CONTAINER=pnt-cli which is an optional package (only present in pyo3-enabled instantiations)\n- container-matrix references .#containerMatrix flake output; verify this exists\n- container-push-production uses --impure flag; document why this is needed\n- These recipes are irrelevant for template instantiations without container support; consider conditional availability or documenting prerequisites\n\nDone means: each recipe tested or documented as optional, defaults evaluated, prerequisites documented.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:36.715993-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:36.715993-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.4","title":"Docs group: audit and update recipes","description":"Review the Docs recipe group (10 recipes).\n\nRecipes to evaluate:\n- docs-extensions, docs-reference, docs-build, docs-local, docs-check, docs-dev, docs-deploy, docs-preview-deploy, data-sync, docs-sync\n\nKnown concerns:\n- docs-build depends on data-sync which requires DVC setup with GCP service account; this hard dependency means docs cannot be built without DVC configuration\n- data-sync and docs-sync both decrypt vars/dvc-sa.json and use uvx with dvc-gdrive,dvc-gs; consider whether DVC should be optional for docs builds\n- docs-dev and docs-deploy use bunx wrangler; verify bun/wrangler are in devshell\n- docs-preview-deploy uses wrangler versions upload with preview alias\n- docs-extensions runs quarto add which modifies project files; may not be idempotent\n\nDone means: each recipe tested, DVC dependency evaluated for optionality, prerequisites documented, tools verified in devshell.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:46.393111-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:46.393111-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.5","title":"Nix group: audit and update recipes","description":"Review the Nix recipe group (4 recipes).\n\nRecipes to evaluate:\n- dev, flake-check, flake-update, ci\n\nKnown concerns:\n- ci recipe runs om ci (omnix); verify om is in devshell\n- flake-check is a comprehensive script that iterates all checks; verify it handles failures gracefully\n- dev recipe just runs nix develop which is redundant if user is already in direnv-managed shell\n- Group is small and clean; may need minimal changes\n\nDone means: each recipe tested, tools verified in devshell.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:03:52.621765-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:03:52.621765-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.6","title":"Python group: audit and update recipes","description":"Review the Python recipe group (10 recipes).\n\nRecipes to evaluate:\n- test, test-all, uv-build, uv-sync, uv-lock, lint, lint-all, lint-fix, type, check\n\nKnown concerns:\n- All parameterized recipes default to package=python-nix-template; evaluate whether this is the right default\n- test recipe runs bare pytest (not uv run pytest); compare with ci-test which uses uv run pytest\n- lint runs bare ruff check; compare with ci-lint which uses uv run ruff check\n- type runs bare pyright; compare with ci-typecheck which uses uv run pyright\n- The distinction between bare tool invocation (Python group) and uv run invocation (CI/CD group) should be documented or unified\n- lint-all runs ruff check on entire packages/ directory; verify this works with independent-lock pattern\n- test-all iterates packages and runs pytest in each; verify this works without workspace-level uv.lock\n\nDone means: each recipe tested, relationship with CI/CD group recipes clarified, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:00.982412-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:00.982412-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.7","title":"Release group: audit and update recipes","description":"Review the Release recipe group (8 recipes).\n\nRecipes to evaluate:\n- test-release, test-release-as-main, test-release-on-current-branch, test-release-direct, test-package-release, preview-version, release-package, update-version\n\nKnown concerns:\n- test-release, test-release-as-main, test-release-on-current-branch, test-release-direct all delegate to bun run scripts; verify these scripts exist in package.json\n- test-package-release defaults to package-name=python-nix-template\n- release-package runs bun install then delegates to bun run; verify bun is in devshell\n- update-version uses sed for in-place edits; verify correctness on macOS (sed -i'' vs sed -i)\n- update-version handles pyproject.toml [project] and [tool.pixi.package] versions plus Cargo.toml; verify all paths\n- preview-version delegates to scripts/preview-version.sh; verify this script exists\n\nDone means: each recipe tested or verified, bun scripts confirmed, sed portability checked.","status":"in_progress","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:08.993522-05:00","created_by":"Cameron Smith","updated_at":"2026-02-16T13:20:36.143188-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.8","title":"Rust group: audit and update recipes","description":"Review the Rust recipe group (5 recipes).\n\nRecipes to evaluate:\n- cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check\n\nKnown concerns:\n- All recipes default to package=pnt-cli which is optional (only present in pyo3-enabled instantiations)\n- All recipes assume packages/{package}/crates directory structure; this is pnt-cli-specific\n- cargo-nextest uses --no-tests=pass flag; verify this is the intended behavior\n- These recipes are irrelevant for template instantiations without Rust/pyo3 support\n- Consider conditional availability or clear documentation that this group is pyo3-only\n\nDone means: each recipe tested in pnt-cli context, documented as optional/conditional, defaults evaluated.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:15.108397-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:15.108397-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-wl6.9","title":"Secrets group: audit and restructure recipes","description":"Review and restructure the Secrets recipe group (20 recipes). This is the second largest group and contains two distinct concerns that should be evaluated for separation.\n\nRecipes to evaluate:\nCore sops management (10 recipes):\n- show-secrets, edit-secrets, new-secret, export-secrets, run-with-secrets, check-secrets, get-secret, validate-secrets, sops-init, sops-add-key, set-secret, rotate-secret, updatekeys\n\nGCP service account and DVC management (7 recipes):\n- gcp-enable-drive-api, gcp-sa-create, gcp-sa-storage-user, gcp-sa-key-download, gcp-sa-key-encrypt, gcp-sa-key-rotate, gcp-sa-key-delete, gcp-sa-keys-list, dvc-run\n\nKnown concerns:\n- GCP/DVC recipes are project-specific infrastructure that most template instantiations will not need; consider separating into a gcp or data group\n- sops-add-key uses interactive read which may not work in all environments\n- rotate-secret uses interactive read -s for hidden input\n- validate-secrets and sops-init use emoji characters in output (contradicts style conventions)\n- export-secrets writes to .secrets.env; verify this is in .gitignore\n- updatekeys iterates all files in vars/ not just yaml; could match non-sops files\n\nDone means: each recipe tested, group potentially split into sops-core and gcp/data subgroups, interactive recipes documented, emoji usage removed.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-05T20:04:26.827907-05:00","created_by":"Cameron Smith","updated_at":"2026-02-05T20:04:26.827907-05:00","closed_at":null,"close_reason":null,"comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-yty","title":"Align Cloudflare docs deployment with vanixiets preview-promote pattern","description":"Align python-nix-template docs deployment workflow with the preview-promote pattern from vanixiets and typescript-nix-template. Currently pnt has preview deployment but no production promotion logic, uses a two-job workflow with artifact upload, lacks link validation, and uses yarn-berry where vanixiets/tnt use bun.\n\nChanges required:\n\n1. Migrate from yarn-berry to bun:\n - Remove yarn.lock, .yarnrc.yml, and any yarn configuration\n - Add bun to the devShell (modules/devshell.nix)\n - Replace all yarn dlx wrangler / yarn dlx references with bunx wrangler / bunx\n - Update package.json scripts if they reference yarn\n - Generate bun.lock (or bun.lockb) from package.json\n - Update .gitignore for bun artifacts\n - Update CI workflows that reference yarn\n - This aligns tooling exactly with vanixiets and typescript-nix-template\n\n2. Add docs-deploy-production justfile recipe with version promotion logic:\n - Look up existing wrangler version by 12-char commit SHA tag\n - If found: promote to 100% production traffic (zero rebuild)\n - If not found: fall back to build and deploy directly\n - Reference: vanixiets scripts/docs/deploy-production.sh and tnt justfile docs-deploy-production\n\n3. Align docs-deploy-preview with vanixiets pattern:\n - Branch name sanitization (40-char subdomain-safe)\n - Git metadata capture (12-char SHA tag, commit message, clean/dirty status)\n - Use bunx wrangler (after yarn-to-bun migration)\n\n4. Refactor deploy-docs.yaml workflow:\n - Single-job pattern with environment branching (preview vs production)\n - Use setup-nix composite action instead of DeterminateSystems/nix-installer-action\n - Add link validation step (just docs-linkcheck or equivalent for Quarto)\n - Add cached-ci-job execution caching\n - Preview triggered on PR, production triggered on push to main/beta\n\n5. Evaluate wrangler.jsonc location:\n - Currently at repo root, vanixiets/tnt have it in packages/docs/\n - pnt docs are in docs/ (not packages/docs/), so repo root may be appropriate\n - Ensure assets.directory path is correct relative to wrangler.jsonc location\n\n6. Worker naming convention:\n - Current: python-nix-template (matches repo name)\n - vanixiets pattern: infra-docs, tnt pattern: ts-nix-docs\n - Choose appropriate worker name for the template\n\nReference implementations:\n- ~/projects/nix-workspace/vanixiets justfile (docs-deploy-preview, docs-deploy-production), deploy-docs.yaml, packages/docs/wrangler.jsonc, scripts/docs/deploy-production.sh\n- ~/projects/nix-workspace/typescript-nix-template justfile, deploy-docs.yaml, packages/docs/wrangler.jsonc\n\nNote: pnt uses Quarto (not Astro) so build commands differ, but the wrangler deployment pattern and bun tooling are framework-agnostic.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-03T18:23:43.437695-05:00","created_by":"Cameron Smith","updated_at":"2026-02-03T22:16:52.24175-05:00","closed_at":"2026-02-03T22:16:52.24175-05:00","close_reason":"Implemented across 18 commits on branch pnt-yty-cloudflare-docs-alignment (dd698bf..e03ca68). Phase 1: yarn-to-bun migration (devshell, package.json, justfile, lockfile, CI hash-sources). Phase 2: preview-promote docs deployment (docs-deploy-preview with branch sanitization and SHA tagging, docs-deploy-production with version promotion, single-job deploy-docs.yaml with environment branching, wrangler.jsonc schema and observability). Alignment: GitHub preview/production environments created, preview-docs job runs on every PR (removed label gate), ::notice annotations for predicted semantic-release versions, preview-version.sh ported from tnt with merge-tree simulation. CI verified green on PR 45 (run 21652296092). Fix for preview-release-version local branch requirement pushed (e03ca68), awaiting CI confirmation.","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} From f637fb5e8bae7e92133c428872320a8f2c935b94 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Tue, 17 Feb 2026 11:21:53 -0500 Subject: [PATCH 55/55] fix(docs): use recursive glob for quarto_ipynb gitignore pattern --- docs/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.gitignore b/docs/.gitignore index 402c3bb..1200ea1 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -6,5 +6,5 @@ development/notes/ objects.json objects.txt /_freeze -*.quarto_ipynb +**/*.quarto_ipynb .jupyter_cache/