From f03617b26f14a665f479b9d5f552d11da779299c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:12:24 -0500 Subject: [PATCH 01/39] refactor(nix): replace hardcoded package enumeration with readDir discovery Replace hasFunctional/hasCli pathExists checks and hardcoded packageWorkspaces entries with builtins.readDir-based discovery. Packages are classified as maturin (Cargo.toml present) or pure Python automatically. Expose packageNames, maturinPackageNames, purePackageNames, and hasMaturinPackages via _module.args for downstream consumers (devshell.nix, containers.nix). --- modules/python.nix | 98 ++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/modules/python.nix b/modules/python.nix index 0ca2a14b..b9e60bf2 100644 --- a/modules/python.nix +++ b/modules/python.nix @@ -19,6 +19,20 @@ py313 = pkgs.python313; }; + # Discover packages from packages/ directory. Each subdirectory is a + # Python package. Packages containing Cargo.toml are maturin/pyo3 + # packages requiring a corresponding nix/packages/{name}/default.nix + # module that exports { overlay, checks }. + packageDirs = builtins.readDir ../packages; + packageNames = builtins.filter (name: packageDirs.${name} == "directory") ( + builtins.attrNames packageDirs + ); + + isMaturin = name: builtins.pathExists (../packages + "/${name}/Cargo.toml"); + maturinPackageNames = builtins.filter isMaturin packageNames; + purePackageNames = builtins.filter (name: !(isMaturin name)) packageNames; + hasMaturinPackages = maturinPackageNames != [ ]; + # Load each Python package independently (no root workspace). # Each package directory contains its own pyproject.toml and uv.lock, # resolved independently following the LangChain federation model. @@ -39,39 +53,24 @@ }; }; - hasFunctional = builtins.pathExists ../packages/pnt-functional; - hasCli = builtins.pathExists ../packages/pnt-cli; - - packageWorkspaces = { - python-nix-template = loadPackage "python-nix-template" ../packages/python-nix-template; - } - // lib.optionalAttrs hasCli { - pnt-cli = loadPackage "pnt-cli" ../packages/pnt-cli; - } - // lib.optionalAttrs hasFunctional { - pnt-functional = loadPackage "pnt-functional" ../packages/pnt-functional; - }; - - # Per-package Nix modules with optional Rust overlays. - # Packages with Rust extensions get a dedicated module in nix/packages/ - # that encapsulates crane configuration and exports an overlay + checks. - # When pnt-cli is absent (pyo3-package: false), returns an inert module - # with no-op overlay and empty checks to avoid import path errors. - emptyModule = { - overlay = _final: _prev: { }; - checks = { }; - }; + packageWorkspaces = lib.genAttrs packageNames (name: loadPackage name (../packages + "/${name}")); + # Per-package Nix modules with Rust overlays. Each maturin package + # requires nix/packages/{name}/default.nix exporting { overlay, checks }. + # Eval-time error when Cargo.toml exists but the module is missing. mkPackageModule = - python: - if hasCli then - import ../nix/packages/pnt-cli { + name: python: + let + modulePath = ../nix/packages + "/${name}/default.nix"; + in + if builtins.pathExists modulePath then + import modulePath { inherit pkgs lib python; crane = inputs.crane; inherit (inputs) crane-maturin pyproject-nix; } else - emptyModule; + throw "Maturin package ${name} requires nix/packages/${name}/default.nix"; # Compose per-package uv2nix overlays with shared overrides. # @@ -92,49 +91,38 @@ [ inputs.pyproject-build-systems.overlays.default ] - ++ lib.optional hasCli packageWorkspaces.pnt-cli.overlay - ++ lib.optional hasFunctional packageWorkspaces.pnt-functional.overlay + ++ map (name: packageWorkspaces.${name}.overlay) packageNames + ++ map (name: (mkPackageModule name python).overlay) maturinPackageNames ++ [ - packageWorkspaces.python-nix-template.overlay - # Rust integration overlay for pnt-cli (crane + maturin) - (mkPackageModule python).overlay packageOverrides sdistOverrides ] ) ); - # Editable set excludes pnt-cli: maturin packages are incompatible with - # uv2nix's editable overlay (pyprojectFixupEditableHook expects EDITABLE_ROOT - # which maturin's build process does not set). pnt-cli is built as a regular - # wheel in the devshell; use `maturin develop` for iterative Rust development. + # Editable set excludes maturin packages: maturin packages are + # incompatible with uv2nix's editable overlay (pyprojectFixupEditableHook + # expects EDITABLE_ROOT which maturin's build process does not set). + # Maturin packages are built as regular wheels in the devshell; use + # `maturin develop` for iterative Rust development. mkEditablePythonSet = python: (mkPythonSet python).overrideScope ( lib.composeManyExtensions ( - lib.optional hasFunctional packageWorkspaces.pnt-functional.editableOverlay + map (name: packageWorkspaces.${name}.editableOverlay) purePackageNames ++ [ - packageWorkspaces.python-nix-template.editableOverlay ( final: prev: - { - python-nix-template = prev.python-nix-template.overrideAttrs (old: { - nativeBuildInputs = - old.nativeBuildInputs - ++ final.resolveBuildSystem { - editables = [ ]; - }; - }); - } - // lib.optionalAttrs hasFunctional { - pnt-functional = prev.pnt-functional.overrideAttrs (old: { + lib.genAttrs purePackageNames ( + name: + prev.${name}.overrideAttrs (old: { nativeBuildInputs = old.nativeBuildInputs ++ final.resolveBuildSystem { editables = [ ]; }; - }); - } + }) + ) ) ] ) @@ -144,10 +132,12 @@ editablePythonSets = lib.mapAttrs (_: mkEditablePythonSet) pythonVersions; # Rust checks from per-package modules (using default Python version) - rustChecks = (mkPackageModule pythonVersions.py313).checks; + rustChecks = lib.foldl' ( + acc: name: acc // (mkPackageModule name pythonVersions.py313).checks + ) { } maturinPackageNames; in { - checks = lib.optionalAttrs hasCli rustChecks; + checks = lib.optionalAttrs hasMaturinPackages rustChecks; _module.args = { inherit @@ -155,6 +145,10 @@ pythonSets editablePythonSets pythonVersions + packageNames + maturinPackageNames + purePackageNames + hasMaturinPackages ; defaultPython = pythonVersions.py313; }; From 015dfcb6f8aa662c02430a5047202df7213e1fd5 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:06:53 -0500 Subject: [PATCH 02/39] refactor(justfile): remove pnt-cli defaults from Rust recipes Rust recipes (cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check) now require an explicit package parameter instead of defaulting to pnt-cli. --- justfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index 14813a4e..494b4427 100644 --- a/justfile +++ b/justfile @@ -406,27 +406,27 @@ check package="python-nix-template": (lint package) (type package) (test package # Build Rust crates for a package [group('rust')] -cargo-build package="pnt-cli": +cargo-build package: cd packages/{{package}}/crates && cargo build # Run Rust tests via cargo test [group('rust')] -cargo-test package="pnt-cli": +cargo-test package: cd packages/{{package}}/crates && cargo test # Run Rust clippy lints [group('rust')] -cargo-clippy package="pnt-cli": +cargo-clippy package: cd packages/{{package}}/crates && cargo clippy --all-targets -- --deny warnings # Run Rust tests via cargo-nextest [group('rust')] -cargo-nextest package="pnt-cli": +cargo-nextest package: cd packages/{{package}}/crates && cargo nextest run --no-tests=pass # Run all Rust checks (clippy, test) [group('rust')] -cargo-check package="pnt-cli": (cargo-clippy package) (cargo-test package) +cargo-check package: (cargo-clippy package) (cargo-test package) @printf "\nAll Rust checks passed for {{package}}.\n" ## Secrets From 3cb6b5dd7d8362cdcb8d2ada9adeb861c3766700 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:07:12 -0500 Subject: [PATCH 03/39] refactor(justfile): remove pnt-cli defaults from container recipes Container recipes (container-build-production, container-load-production, container-push-production) now require an explicit CONTAINER parameter instead of defaulting to pnt-cli. --- justfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/justfile b/justfile index 494b4427..0009524e 100644 --- a/justfile +++ b/justfile @@ -293,17 +293,17 @@ conda-check package="python-nix-template": (conda-lint package) (conda-type pack # Build production container image [group('containers')] -container-build-production CONTAINER="pnt-cli": +container-build-production CONTAINER: nix build ".#{{CONTAINER}}ProductionImage" -L # Load production container to local Docker daemon [group('containers')] -container-load-production CONTAINER="pnt-cli": +container-load-production CONTAINER: nix run ".#{{CONTAINER}}ProductionImage.copyToDockerDaemon" # Push production container manifest (requires registry auth) [group('containers')] -container-push-production CONTAINER="pnt-cli" VERSION="0.0.0" +TAGS="": +container-push-production CONTAINER VERSION="0.0.0" +TAGS="": VERSION={{VERSION}} TAGS={{TAGS}} nix run --impure ".#{{CONTAINER}}Manifest" -L # Display container CI matrix From 8a13df687554666a247de965299ca9305817d181 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:07:27 -0500 Subject: [PATCH 04/39] feat(justfile): add maturin field to list-packages-json output Annotate each package with a maturin boolean based on Cargo.toml presence in the package directory. --- justfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 0009524e..91bc2091 100644 --- a/justfile +++ b/justfile @@ -212,7 +212,8 @@ list-packages-json: @ls -d packages/*/pyproject.toml | while read f; do \ d=$(dirname "$f"); \ n=$(basename "$d"); \ - printf '{"name":"%s","path":"%s"}\n' "$n" "$d"; \ + if [ -f "$d/Cargo.toml" ]; then m=true; else m=false; fi; \ + printf '{"name":"%s","path":"%s","maturin":%s}\n' "$n" "$d" "$m"; \ done | jq -sc '.' # Sync dependencies for a package via uv From d64722eb287ee08a9a777a86ed59354324a1284d Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:07:41 -0500 Subject: [PATCH 05/39] feat(justfile): add list-maturin-packages convenience recipe Filters list-packages-json to only maturin-enabled packages. --- justfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/justfile b/justfile index 91bc2091..6508baab 100644 --- a/justfile +++ b/justfile @@ -216,6 +216,11 @@ list-packages-json: printf '{"name":"%s","path":"%s","maturin":%s}\n' "$n" "$d" "$m"; \ done | jq -sc '.' +# Discover maturin (Rust/pyo3) packages as JSON array +[group('CI/CD')] +list-maturin-packages: + @just list-packages-json | jq '[.[] | select(.maturin)]' + # Sync dependencies for a package via uv [group('CI/CD')] ci-sync package: From b5f4df4f0ada9a132bd34ab8d2d6b82d29ad4a84 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:06:41 -0500 Subject: [PATCH 06/39] feat(ci): add is_maturin field to discover-packages output Probe for Cargo.toml in each package directory during CI discovery and include the result as a boolean is_maturin field in the JSON matrix output. Downstream jobs can use this to conditionally route maturin packages to Rust-specific build steps. --- .github/workflows/ci.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b908e6c1..9a240dbc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -186,6 +186,10 @@ jobs: d=$(dirname "$f") n=$(basename "$d") + # Detect maturin/pyo3 package by Cargo.toml presence + is_maturin="false" + if [ -f "$d/Cargo.toml" ]; then is_maturin="true"; fi + # Read per-package CI metadata from .ci.json if present ci_json="$d/.ci.json" if [ -f "$ci_json" ]; then @@ -199,9 +203,10 @@ jobs: jq -nc \ --arg name "$n" \ --arg path "$d" \ + --argjson is_maturin "$is_maturin" \ --arg build_images "$build_images" \ --argjson images "$images" \ - '{name: $name, path: $path, "build-images": $build_images, images: ($images | tojson)}' + '{name: $name, path: $path, "is_maturin": $is_maturin, "build-images": $build_images, images: ($images | tojson)}' done | jq -sc '.') echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" echo "Discovered packages: $PACKAGES" From 6814d4f7e1ee8f62f577e0df6100a2ec3aa3c11b Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:20:04 -0500 Subject: [PATCH 07/39] chore(beads): close pnt-kaf.1, pnt-kaf.4, pnt-kaf.5 after wave 1 implementation --- .beads/issues.jsonl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 3a22300d..983140cd 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -46,12 +46,12 @@ {"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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:51:43.949969-05:00"} -{"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:02.76287-05:00","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"in_progress","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:05:32.598219-05:00"} +{"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:14.654722-05:00","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:26.815361-05:00","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2\u003e\u00261 | grep -q 'error' # should fail without argument\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:38.288741-05:00","dependencies":[{"issue_id":"pnt-kaf.4","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:38.290369-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] \u0026\u0026 is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:52.376497-05:00","dependencies":[{"issue_id":"pnt-kaf.5","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:52.377273-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2\u003e\u00261 | grep -q 'error' # should fail without argument\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","dependencies":[{"issue_id":"pnt-kaf.4","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:38.290369-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] \u0026\u0026 is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","dependencies":[{"issue_id":"pnt-kaf.5","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:52.377273-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:53:06.147195-05:00","dependencies":[{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:06.147883-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:31.740448-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:53:21.519266-05:00","dependencies":[{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:21.521466-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.900176-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.2","type":"blocks","created_at":"2026-02-18T11:53:32.062964-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.3","type":"blocks","created_at":"2026-02-18T11:53:32.219856-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.4","type":"blocks","created_at":"2026-02-18T11:53:32.382676-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:32.556841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.6","type":"blocks","created_at":"2026-02-18T11:53:32.720394-05:00","created_by":"Cameron Smith"}]} {"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"}]} From 21a0288be27118f16acb7eec23ab02c873182dea Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:22:09 -0500 Subject: [PATCH 08/39] refactor(devshell): replace hardcoded hasCli with discovery-based hasMaturinPackages Consume hasMaturinPackages from _module.args exposed by python.nix instead of using builtins.pathExists ../packages/pnt-cli. Removes the last hardcoded package name reference from devshell.nix. --- modules/devshell.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/devshell.nix b/modules/devshell.nix index b9380004..ff703952 100644 --- a/modules/devshell.nix +++ b/modules/devshell.nix @@ -12,11 +12,10 @@ packageWorkspaces, editablePythonSets, pythonVersions, + hasMaturinPackages ? false, ... }: let - hasCli = builtins.pathExists ../packages/pnt-cli; - # Merge deps from all independent package workspaces, unioning extras lists # for shared dependency names rather than silently dropping via // allDeps = lib.foldlAttrs ( @@ -55,10 +54,10 @@ sops ssh-to-age ] - ++ lib.optionals hasCli ( + ++ lib.optionals hasMaturinPackages ( with pkgs; [ - # Rust tooling for pnt-cli pyo3 extension + # Rust tooling for maturin/pyo3 packages cargo rustc clippy From 5292a0a56586b1a904d701d31ebea5c7bc5c9171 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:22:40 -0500 Subject: [PATCH 09/39] refactor(containers): replace hardcoded container defs with maturin package discovery Discover maturin packages by scanning packages/ for Cargo.toml presence, mirroring the discovery pattern in python.nix. Each discovered maturin package automatically gets a production container definition. Removes the hardcoded hasCli pathExists check and pnt-cli container definition. --- modules/containers.nix | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/modules/containers.nix b/modules/containers.nix index cc01aa5a..e5fc1c7c 100644 --- a/modules/containers.nix +++ b/modules/containers.nix @@ -7,17 +7,23 @@ let gitHubOrg = "sciexp"; repoName = "python-nix-template"; - hasCli = builtins.pathExists ../packages/pnt-cli; - - # Production container definitions (nix2container) - # Add new containers here; containerMatrix auto-discovers them. - productionContainerDefs = lib.optionalAttrs hasCli { - pnt-cli = { - name = "pnt-cli"; - entrypoint = "pnt-cli"; - description = "pnt-cli with pyo3 native bindings"; - }; - }; + # Discover maturin packages from packages/ directory. Each subdirectory + # containing a Cargo.toml is a maturin/pyo3 package that gets a production + # container. This mirrors the discovery logic in python.nix. + packageDirs = builtins.readDir ../packages; + packageNames = builtins.filter (name: packageDirs.${name} == "directory") ( + builtins.attrNames packageDirs + ); + isMaturin = name: builtins.pathExists (../packages + "/${name}/Cargo.toml"); + maturinPackageNames = builtins.filter isMaturin packageNames; + + # Production container definitions derived from discovered maturin packages. + # Each maturin package exposes a CLI binary via pyo3 and gets a container. + productionContainerDefs = lib.genAttrs maturinPackageNames (name: { + inherit name; + entrypoint = name; + description = "${name} with pyo3 native bindings"; + }); in { perSystem = From 9a4d8bb65c81bf6e9167574ad93d1a80b4e6909b Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:22:43 -0500 Subject: [PATCH 10/39] refactor(mergify): replace hardcoded package names with wildcard regex Consolidate three per-package test-python check conditions into a single regex pattern that matches all test-python matrix job names generically. --- .github/mergify.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/mergify.yml b/.github/mergify.yml index e041b87b..43c311a6 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -24,14 +24,8 @@ shared: - check-success=nix (x86_64-linux, ubuntu-latest, devshells) - check-skipped=nix (x86_64-linux, ubuntu-latest, devshells) - or: - - "check-success~=^test-python \\(python-nix-template, packages/python-nix-template.* / test$" - - "check-skipped~=^test-python \\(python-nix-template, packages/python-nix-template.* / test$" - - or: - - "check-success~=^test-python \\(pnt-functional, packages/pnt-functional.* / test$" - - "check-skipped~=^test-python \\(pnt-functional, packages/pnt-functional.* / test$" - - or: - - "check-success~=^test-python \\(pnt-cli, packages/pnt-cli.* / test$" - - "check-skipped~=^test-python \\(pnt-cli, packages/pnt-cli.* / test$" + - "check-success~=^test-python \\(.* / test$" + - "check-skipped~=^test-python \\(.* / test$" - or: - check-success=test-omnix-template - check-skipped=test-omnix-template From f7051853b9d7b2df450b77a22aabc157968cf986 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:24:52 -0500 Subject: [PATCH 11/39] chore(beads): close pnt-kaf.2, pnt-kaf.3, pnt-kaf.6 after wave 2 implementation --- .beads/issues.jsonl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 983140cd..742ecc22 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -48,11 +48,11 @@ {"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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"in_progress","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:05:32.598219-05:00"} {"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:14.654722-05:00","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:52:26.815361-05:00","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2\u003e\u00261 | grep -q 'error' # should fail without argument\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","dependencies":[{"issue_id":"pnt-kaf.4","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:38.290369-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] \u0026\u0026 is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","dependencies":[{"issue_id":"pnt-kaf.5","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:52.377273-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:53:06.147195-05:00","dependencies":[{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:06.147883-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:31.740448-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:45.125678-05:00","closed_at":"2026-02-18T12:24:45.125678-05:00","close_reason":"Implemented in 9a4d8bb","dependencies":[{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:06.147883-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:31.740448-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:53:21.519266-05:00","dependencies":[{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:21.521466-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.900176-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.2","type":"blocks","created_at":"2026-02-18T11:53:32.062964-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.3","type":"blocks","created_at":"2026-02-18T11:53:32.219856-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.4","type":"blocks","created_at":"2026-02-18T11:53:32.382676-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:32.556841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.6","type":"blocks","created_at":"2026-02-18T11:53:32.720394-05:00","created_by":"Cameron Smith"}]} {"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"} From 65f1533d220c88721a6dcd7674acc1674f8fd337 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:30:32 -0500 Subject: [PATCH 12/39] chore(beads): close pnt-kaf.7 after integration verification --- .beads/issues.jsonl | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 742ecc22..26c5f4d0 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,86 +1,86 @@ -{"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":"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-17T10:19:03.637507-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":"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.","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":"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","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":"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","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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"in_progress","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:05:32.598219-05:00"} -{"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2\u003e\u00261 | grep -q 'error' # should fail without argument\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","dependencies":[{"issue_id":"pnt-kaf.4","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:38.290369-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] \u0026\u0026 is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","dependencies":[{"issue_id":"pnt-kaf.5","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:52.377273-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:45.125678-05:00","closed_at":"2026-02-18T12:24:45.125678-05:00","close_reason":"Implemented in 9a4d8bb","dependencies":[{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:06.147883-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:31.740448-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T11:53:21.519266-05:00","dependencies":[{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:21.521466-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.900176-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.2","type":"blocks","created_at":"2026-02-18T11:53:32.062964-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.3","type":"blocks","created_at":"2026-02-18T11:53:32.219856-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.4","type":"blocks","created_at":"2026-02-18T11:53:32.382676-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:32.556841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.6","type":"blocks","created_at":"2026-02-18T11:53:32.720394-05:00","created_by":"Cameron Smith"}]} -{"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":"Migrate dev container builds (containerImage, devcontainerImage) to nix2container once nixpod completes its nix2container migration. Also align the CI workflow (build-nix-images.yaml) with the vanixiets containers.yaml pattern.\n\nCurrent state:\n- modules/containers.nix already uses nix2container for production containers (pnt-cli) with mk-multi-arch-manifest.nix providing crane/skopeo-based manifest pushing\n- Dev containers still import buildMultiUserNixImage from nixpod, which 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- Container image builds disabled in CI via .ci.json \"build-images\": false (pnt-mgq.1, commit a7afe48) as interim fix\n\nDiscovered during CI investigation (2026-02-17):\n- The build-nix-images.yaml manifest job fails because setup-nix default hatchet (cleave, level 2) removes Docker before the manifest job runs docker login ghcr.io (exit 127 on docker binary)\n- The docker login step (lines 155-157) is actually redundant: mk-multi-arch-manifest.nix handles auth internally via skopeo login and crane auth login using GITHUB_TOKEN env var, matching the vanixiets pattern exactly\n- The vanixiets containers.yaml manifest job has no Docker dependency at all: it sets GITHUB_TOKEN as env var and runs nix run .#...Manifest, which authenticates via skopeo/crane under the hood\n- When vanixiets genuinely needs Docker (test-cluster.yaml for k3d), the compensatory pattern is: holster hatchet (level 0), mnt-safe-haven 15360, Docker prune, explicit docker version verification\n- The python-nix-template setup-nix action is already aligned with vanixiets (identical hatchet/safe-haven parameters)\n\nBlocked on: nixpod completing its nix2container migration for dev containers (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- Production containers: already nix2container-based, CI workflow aligned with vanixiets (remove docker login, env-var auth only)\n- Dev containers: nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally), python-nix-template dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (mk-multi-arch-manifest.nix already supports this)\n- flocken fully removed from flake.nix\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- build-nix-images.yaml manifest job uses env-var auth (GITHUB_TOKEN) without docker login, matching vanixiets containers.yaml pattern\n- build-nix-images.yaml has no Docker dependency in any job (discover, build, manifest)\n- Dev containers build using nixpod nix2container-based API\n- flocken fully removed from flake.nix (production containers already handle this via mk-multi-arch-manifest.nix)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n- .ci.json \"build-images\" re-enabled to true after migration complete\n- CI workflow passes end-to-end with default cleave hatchet\n\nKey files:\n- python-nix-template: .github/workflows/build-nix-images.yaml (manifest job lines 132-171)\n- python-nix-template: .github/actions/setup-nix/action.yml (hatchet input)\n- python-nix-template: modules/containers.nix (production containers already nix2container)\n- python-nix-template: nix/lib/mk-multi-arch-manifest.nix (skopeo/crane auth, no Docker)\n- python-nix-template: packages/python-nix-template/.ci.json (build-images toggle)\n- vanixiets: .github/workflows/containers.yaml (reference Docker-free manifest job)\n- vanixiets: .github/workflows/test-cluster.yaml (reference holster pattern for Docker needs)","status":"in_progress","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-17T12:09:55.057323-05:00"} -{"id":"pnt-mgq.1","title":"Disable container image builds in CI until nix2container migration","description":"The manifest job in build-nix-images.yaml fails because setup-nix cleave hatchet removes Docker before docker login runs (exit 127). Since container image builds are not needed while nix2container migration is planned (pnt-mgq), disable build-images in packages/python-nix-template/.ci.json.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:01:54.423936-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:02:39.630912-05:00","closed_at":"2026-02-17T12:02:39.630912-05:00","close_reason":"Implemented in a7afe48","dependencies":[{"issue_id":"pnt-mgq.1","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:01:54.424779-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-mgq.2","title":"Remove docker login from build-nix-images.yaml manifest job","description":"Remove the docker login step (lines 155-157) from the manifest job in .github/workflows/build-nix-images.yaml. This step runs docker login ghcr.io which fails with exit 127 because the default cleave hatchet removes Docker from the runner.\n\nThe docker login is redundant because mk-multi-arch-manifest.nix already handles authentication internally via skopeo login and crane auth login, reading credentials from the GITHUB_TOKEN env var that is already set on the manifest job (line 161). This matches the vanixiets containers.yaml pattern where the manifest job has no Docker steps at all.\n\nChanges needed:\n- Remove the \"Login to GitHub Container Registry\" step (lines 155-157)\n- Verify the GITHUB_TOKEN env var is still set on the \"Push manifest\" step (it already is)\n- The manifest job should have: checkout, setup-nix, push manifest (with GITHUB_TOKEN env var)\n\nReference: vanixiets .github/workflows/containers.yaml manifest job (lines 149-170) for the target pattern.\nReference: nix/lib/mk-multi-arch-manifest.nix for how auth works (skopeo login + crane auth login using registry.password = \"$GITHUB_TOKEN\").","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:06.640149-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:06.640149-05:00","dependencies":[{"issue_id":"pnt-mgq.2","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:06.640881-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-mgq.3","title":"Remove QEMU setup from build job for production containers","description":"The build job in build-nix-images.yaml has a QEMU setup step (lines 107-110) conditionally enabled for type == dev containers. Production containers use pkgsCross for cross-compilation (no QEMU needed). When dev containers are migrated to nix2container, they should also use pkgsCross rather than QEMU emulation, matching the vanixiets pattern.\n\nEvaluate whether the QEMU setup step can be removed entirely once dev containers are migrated. If dev containers will use nix2container with pkgsCross (as production containers do), the QEMU step is no longer needed.\n\nThis aligns with the vanixiets containers.yaml build job which has no QEMU setup at all — it uses pkgsCross for all architectures.\n\nChanges needed:\n- Remove the Setup QEMU step and the docker/setup-qemu-action dependency\n- Remove the conditional extra-platforms aarch64-linux nix config (line 118) that was needed for QEMU emulation\n- Verify that cross-compilation via pkgsCross works for dev container builds\n\nThis depends on dev container migration to nix2container being complete.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:17.65854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:17.65854-05:00","dependencies":[{"issue_id":"pnt-mgq.3","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:17.659273-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-mgq.4","title":"Align build-nix-images.yaml workflow structure with vanixiets containers.yaml","description":"After removing docker login (pnt-mgq.2) and QEMU setup (pnt-mgq.3), further align the build-nix-images.yaml workflow with the vanixiets containers.yaml reference pattern.\n\nDifferences to address:\n- Add concurrency group (vanixiets has: group: container-${{ github.ref }}, cancel-in-progress: true)\n- Add defaults.run.shell: bash (vanixiets convention)\n- Remove the apt-get install zstd step (lines 100-104) if it is no longer needed without Docker/QEMU\n- Align the build job to not use fetch-depth: 0 on checkout (vanixiets uses default shallow checkout for builds)\n- Add architecture verification step matching vanixiets pattern (verify OCI arch metadata)\n- Consider renaming workflow from \"Build Nix Images\" to \"Container Images\" to match vanixiets\n\nThe workflow should produce the same discover → build → manifest pipeline structure but without any Docker dependency, relying entirely on nix2container for building and skopeo/crane for pushing.\n\nReference: vanixiets .github/workflows/containers.yaml for the full target pattern.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:28.933224-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:28.933224-05:00","dependencies":[{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:28.93436-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq.2","type":"blocks","created_at":"2026-02-17T12:10:58.368013-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq.3","type":"blocks","created_at":"2026-02-17T12:10:58.521015-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-mgq.5","title":"Migrate dev containers from dockerTools to nix2container via upgraded nixpod","description":"Core migration task: update dev container builds to use nix2container once nixpod completes its internal migration from dockerTools.buildLayeredImageWithNixDb to nix2container.\n\nCurrent state:\n- modules/containers.nix production containers already use nix2container (mkProductionContainer function)\n- Dev containers still use nixpod buildMultiUserNixImage which internally uses dockerTools\n- flocken handles multi-arch manifest creation for dev containers\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template dev containers consume upgraded nixpod seamlessly\n- Dev container manifests use mk-multi-arch-manifest.nix (crane/skopeo-based, matching production containers)\n- flocken removed from flake.nix and flake.lock\n\nBlocked on: nixpod completing its nix2container migration (sciexp-h0g). The nixpod refactor-container-builds branch has research docs with full API mapping and implementation plan.\n\nChanges needed:\n- Update nixpod input version in flake.nix to post-migration release\n- Update modules/containers.nix dev container definitions to use new nixpod API (if API surface changes)\n- Replace flocken-based dev container manifest generation with mk-multi-arch-manifest.nix\n- Remove flocken from flake inputs\n- Preserve dev container functionality: multi-user Nix daemon, home-manager activation, s6-overlay, Jupyter, code-server\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-17T12:10:40.469904-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:40.469904-05:00","dependencies":[{"issue_id":"pnt-mgq.5","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:40.470902-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-mgq.6","title":"Re-enable build-images in .ci.json and validate end-to-end CI","description":"After all workflow and container migration changes are complete, re-enable container image builds by setting \"build-images\": true in packages/python-nix-template/.ci.json (currently false, set by pnt-mgq.1 commit a7afe48 as interim fix).\n\nValidation checklist:\n- Set \"build-images\": true in packages/python-nix-template/.ci.json\n- Trigger build-nix-images.yaml workflow with push: false to verify discover + build jobs pass\n- Trigger with push: true to verify manifest job authenticates and pushes without Docker\n- Confirm all jobs run successfully with default cleave hatchet (no Docker on runner)\n- Verify multi-arch manifests are correctly created in ghcr.io\n- Confirm dev container images (once migrated) also build and push correctly\n\nThis is the final validation gate for the epic. All other pnt-mgq children must be complete before this issue can start.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:50.883513-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:50.883513-05:00","dependencies":[{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:50.884185-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.2","type":"blocks","created_at":"2026-02-17T12:10:58.674666-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.3","type":"blocks","created_at":"2026-02-17T12:10:58.83841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.4","type":"blocks","created_at":"2026-02-17T12:10:59.000711-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.5","type":"blocks","created_at":"2026-02-17T12:10:59.156801-05:00","created_by":"Cameron Smith"}]} -{"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-17T10:19:03.637507-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-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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"inreview","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T17:30:32.709257+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-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2>&1 | grep -q 'error' # should fail without argument\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] && is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:45.125678-05:00","closed_at":"2026-02-18T12:24:45.125678-05:00","close_reason":"Implemented in 9a4d8bb","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:30:23.648642-05:00","closed_at":"2026-02-18T12:30:23.648642-05:00","close_reason":"Verified in f705185 — all nix eval, justfile, CI, and residual-reference checks pass","comments":null,"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":"Migrate dev container builds (containerImage, devcontainerImage) to nix2container once nixpod completes its nix2container migration. Also align the CI workflow (build-nix-images.yaml) with the vanixiets containers.yaml pattern.\n\nCurrent state:\n- modules/containers.nix already uses nix2container for production containers (pnt-cli) with mk-multi-arch-manifest.nix providing crane/skopeo-based manifest pushing\n- Dev containers still import buildMultiUserNixImage from nixpod, which 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- Container image builds disabled in CI via .ci.json \"build-images\": false (pnt-mgq.1, commit a7afe48) as interim fix\n\nDiscovered during CI investigation (2026-02-17):\n- The build-nix-images.yaml manifest job fails because setup-nix default hatchet (cleave, level 2) removes Docker before the manifest job runs docker login ghcr.io (exit 127 on docker binary)\n- The docker login step (lines 155-157) is actually redundant: mk-multi-arch-manifest.nix handles auth internally via skopeo login and crane auth login using GITHUB_TOKEN env var, matching the vanixiets pattern exactly\n- The vanixiets containers.yaml manifest job has no Docker dependency at all: it sets GITHUB_TOKEN as env var and runs nix run .#...Manifest, which authenticates via skopeo/crane under the hood\n- When vanixiets genuinely needs Docker (test-cluster.yaml for k3d), the compensatory pattern is: holster hatchet (level 0), mnt-safe-haven 15360, Docker prune, explicit docker version verification\n- The python-nix-template setup-nix action is already aligned with vanixiets (identical hatchet/safe-haven parameters)\n\nBlocked on: nixpod completing its nix2container migration for dev containers (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- Production containers: already nix2container-based, CI workflow aligned with vanixiets (remove docker login, env-var auth only)\n- Dev containers: nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally), python-nix-template dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (mk-multi-arch-manifest.nix already supports this)\n- flocken fully removed from flake.nix\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- build-nix-images.yaml manifest job uses env-var auth (GITHUB_TOKEN) without docker login, matching vanixiets containers.yaml pattern\n- build-nix-images.yaml has no Docker dependency in any job (discover, build, manifest)\n- Dev containers build using nixpod nix2container-based API\n- flocken fully removed from flake.nix (production containers already handle this via mk-multi-arch-manifest.nix)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n- .ci.json \"build-images\" re-enabled to true after migration complete\n- CI workflow passes end-to-end with default cleave hatchet\n\nKey files:\n- python-nix-template: .github/workflows/build-nix-images.yaml (manifest job lines 132-171)\n- python-nix-template: .github/actions/setup-nix/action.yml (hatchet input)\n- python-nix-template: modules/containers.nix (production containers already nix2container)\n- python-nix-template: nix/lib/mk-multi-arch-manifest.nix (skopeo/crane auth, no Docker)\n- python-nix-template: packages/python-nix-template/.ci.json (build-images toggle)\n- vanixiets: .github/workflows/containers.yaml (reference Docker-free manifest job)\n- vanixiets: .github/workflows/test-cluster.yaml (reference holster pattern for Docker needs)","status":"in_progress","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-17T12:09:55.057323-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-mgq.1","title":"Disable container image builds in CI until nix2container migration","description":"The manifest job in build-nix-images.yaml fails because setup-nix cleave hatchet removes Docker before docker login runs (exit 127). Since container image builds are not needed while nix2container migration is planned (pnt-mgq), disable build-images in packages/python-nix-template/.ci.json.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:01:54.423936-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:02:39.630912-05:00","closed_at":"2026-02-17T12:02:39.630912-05:00","close_reason":"Implemented in a7afe48","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} +{"id":"pnt-mgq.2","title":"Remove docker login from build-nix-images.yaml manifest job","description":"Remove the docker login step (lines 155-157) from the manifest job in .github/workflows/build-nix-images.yaml. This step runs docker login ghcr.io which fails with exit 127 because the default cleave hatchet removes Docker from the runner.\n\nThe docker login is redundant because mk-multi-arch-manifest.nix already handles authentication internally via skopeo login and crane auth login, reading credentials from the GITHUB_TOKEN env var that is already set on the manifest job (line 161). This matches the vanixiets containers.yaml pattern where the manifest job has no Docker steps at all.\n\nChanges needed:\n- Remove the \"Login to GitHub Container Registry\" step (lines 155-157)\n- Verify the GITHUB_TOKEN env var is still set on the \"Push manifest\" step (it already is)\n- The manifest job should have: checkout, setup-nix, push manifest (with GITHUB_TOKEN env var)\n\nReference: vanixiets .github/workflows/containers.yaml manifest job (lines 149-170) for the target pattern.\nReference: nix/lib/mk-multi-arch-manifest.nix for how auth works (skopeo login + crane auth login using registry.password = \"$GITHUB_TOKEN\").","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:06.640149-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:06.640149-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-mgq.3","title":"Remove QEMU setup from build job for production containers","description":"The build job in build-nix-images.yaml has a QEMU setup step (lines 107-110) conditionally enabled for type == dev containers. Production containers use pkgsCross for cross-compilation (no QEMU needed). When dev containers are migrated to nix2container, they should also use pkgsCross rather than QEMU emulation, matching the vanixiets pattern.\n\nEvaluate whether the QEMU setup step can be removed entirely once dev containers are migrated. If dev containers will use nix2container with pkgsCross (as production containers do), the QEMU step is no longer needed.\n\nThis aligns with the vanixiets containers.yaml build job which has no QEMU setup at all — it uses pkgsCross for all architectures.\n\nChanges needed:\n- Remove the Setup QEMU step and the docker/setup-qemu-action dependency\n- Remove the conditional extra-platforms aarch64-linux nix config (line 118) that was needed for QEMU emulation\n- Verify that cross-compilation via pkgsCross works for dev container builds\n\nThis depends on dev container migration to nix2container being complete.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:17.65854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:17.65854-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-mgq.4","title":"Align build-nix-images.yaml workflow structure with vanixiets containers.yaml","description":"After removing docker login (pnt-mgq.2) and QEMU setup (pnt-mgq.3), further align the build-nix-images.yaml workflow with the vanixiets containers.yaml reference pattern.\n\nDifferences to address:\n- Add concurrency group (vanixiets has: group: container-${{ github.ref }}, cancel-in-progress: true)\n- Add defaults.run.shell: bash (vanixiets convention)\n- Remove the apt-get install zstd step (lines 100-104) if it is no longer needed without Docker/QEMU\n- Align the build job to not use fetch-depth: 0 on checkout (vanixiets uses default shallow checkout for builds)\n- Add architecture verification step matching vanixiets pattern (verify OCI arch metadata)\n- Consider renaming workflow from \"Build Nix Images\" to \"Container Images\" to match vanixiets\n\nThe workflow should produce the same discover → build → manifest pipeline structure but without any Docker dependency, relying entirely on nix2container for building and skopeo/crane for pushing.\n\nReference: vanixiets .github/workflows/containers.yaml for the full target pattern.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:28.933224-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:28.933224-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-mgq.5","title":"Migrate dev containers from dockerTools to nix2container via upgraded nixpod","description":"Core migration task: update dev container builds to use nix2container once nixpod completes its internal migration from dockerTools.buildLayeredImageWithNixDb to nix2container.\n\nCurrent state:\n- modules/containers.nix production containers already use nix2container (mkProductionContainer function)\n- Dev containers still use nixpod buildMultiUserNixImage which internally uses dockerTools\n- flocken handles multi-arch manifest creation for dev containers\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template dev containers consume upgraded nixpod seamlessly\n- Dev container manifests use mk-multi-arch-manifest.nix (crane/skopeo-based, matching production containers)\n- flocken removed from flake.nix and flake.lock\n\nBlocked on: nixpod completing its nix2container migration (sciexp-h0g). The nixpod refactor-container-builds branch has research docs with full API mapping and implementation plan.\n\nChanges needed:\n- Update nixpod input version in flake.nix to post-migration release\n- Update modules/containers.nix dev container definitions to use new nixpod API (if API surface changes)\n- Replace flocken-based dev container manifest generation with mk-multi-arch-manifest.nix\n- Remove flocken from flake inputs\n- Preserve dev container functionality: multi-user Nix daemon, home-manager activation, s6-overlay, Jupyter, code-server\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-17T12:10:40.469904-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:40.469904-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-mgq.6","title":"Re-enable build-images in .ci.json and validate end-to-end CI","description":"After all workflow and container migration changes are complete, re-enable container image builds by setting \"build-images\": true in packages/python-nix-template/.ci.json (currently false, set by pnt-mgq.1 commit a7afe48 as interim fix).\n\nValidation checklist:\n- Set \"build-images\": true in packages/python-nix-template/.ci.json\n- Trigger build-nix-images.yaml workflow with push: false to verify discover + build jobs pass\n- Trigger with push: true to verify manifest job authenticates and pushes without Docker\n- Confirm all jobs run successfully with default cleave hatchet (no Docker on runner)\n- Verify multi-arch manifests are correctly created in ghcr.io\n- Confirm dev container images (once migrated) also build and push correctly\n\nThis is the final validation gate for the epic. All other pnt-mgq children must be complete before this issue can start.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:50.883513-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:50.883513-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 05836ec8be12d981bb2530d17c3b51d0f6b43dbd Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 12:35:09 -0500 Subject: [PATCH 13/39] chore(beads): checkpoint pnt-kaf epic completion --- .beads/issues.jsonl | 172 ++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 26c5f4d0..ce666a50 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,86 +1,86 @@ -{"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-17T10:19:03.637507-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-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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"inreview","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T17:30:32.709257+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-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2>&1 | grep -q 'error' # should fail without argument\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] && is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:45.125678-05:00","closed_at":"2026-02-18T12:24:45.125678-05:00","close_reason":"Implemented in 9a4d8bb","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:30:23.648642-05:00","closed_at":"2026-02-18T12:30:23.648642-05:00","close_reason":"Verified in f705185 — all nix eval, justfile, CI, and residual-reference checks pass","comments":null,"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":"Migrate dev container builds (containerImage, devcontainerImage) to nix2container once nixpod completes its nix2container migration. Also align the CI workflow (build-nix-images.yaml) with the vanixiets containers.yaml pattern.\n\nCurrent state:\n- modules/containers.nix already uses nix2container for production containers (pnt-cli) with mk-multi-arch-manifest.nix providing crane/skopeo-based manifest pushing\n- Dev containers still import buildMultiUserNixImage from nixpod, which 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- Container image builds disabled in CI via .ci.json \"build-images\": false (pnt-mgq.1, commit a7afe48) as interim fix\n\nDiscovered during CI investigation (2026-02-17):\n- The build-nix-images.yaml manifest job fails because setup-nix default hatchet (cleave, level 2) removes Docker before the manifest job runs docker login ghcr.io (exit 127 on docker binary)\n- The docker login step (lines 155-157) is actually redundant: mk-multi-arch-manifest.nix handles auth internally via skopeo login and crane auth login using GITHUB_TOKEN env var, matching the vanixiets pattern exactly\n- The vanixiets containers.yaml manifest job has no Docker dependency at all: it sets GITHUB_TOKEN as env var and runs nix run .#...Manifest, which authenticates via skopeo/crane under the hood\n- When vanixiets genuinely needs Docker (test-cluster.yaml for k3d), the compensatory pattern is: holster hatchet (level 0), mnt-safe-haven 15360, Docker prune, explicit docker version verification\n- The python-nix-template setup-nix action is already aligned with vanixiets (identical hatchet/safe-haven parameters)\n\nBlocked on: nixpod completing its nix2container migration for dev containers (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- Production containers: already nix2container-based, CI workflow aligned with vanixiets (remove docker login, env-var auth only)\n- Dev containers: nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally), python-nix-template dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (mk-multi-arch-manifest.nix already supports this)\n- flocken fully removed from flake.nix\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- build-nix-images.yaml manifest job uses env-var auth (GITHUB_TOKEN) without docker login, matching vanixiets containers.yaml pattern\n- build-nix-images.yaml has no Docker dependency in any job (discover, build, manifest)\n- Dev containers build using nixpod nix2container-based API\n- flocken fully removed from flake.nix (production containers already handle this via mk-multi-arch-manifest.nix)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n- .ci.json \"build-images\" re-enabled to true after migration complete\n- CI workflow passes end-to-end with default cleave hatchet\n\nKey files:\n- python-nix-template: .github/workflows/build-nix-images.yaml (manifest job lines 132-171)\n- python-nix-template: .github/actions/setup-nix/action.yml (hatchet input)\n- python-nix-template: modules/containers.nix (production containers already nix2container)\n- python-nix-template: nix/lib/mk-multi-arch-manifest.nix (skopeo/crane auth, no Docker)\n- python-nix-template: packages/python-nix-template/.ci.json (build-images toggle)\n- vanixiets: .github/workflows/containers.yaml (reference Docker-free manifest job)\n- vanixiets: .github/workflows/test-cluster.yaml (reference holster pattern for Docker needs)","status":"in_progress","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-17T12:09:55.057323-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-mgq.1","title":"Disable container image builds in CI until nix2container migration","description":"The manifest job in build-nix-images.yaml fails because setup-nix cleave hatchet removes Docker before docker login runs (exit 127). Since container image builds are not needed while nix2container migration is planned (pnt-mgq), disable build-images in packages/python-nix-template/.ci.json.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:01:54.423936-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:02:39.630912-05:00","closed_at":"2026-02-17T12:02:39.630912-05:00","close_reason":"Implemented in a7afe48","comments":null,"parent_id":null,"children":null,"design_doc":null,"deps":null,"relates_to":null} -{"id":"pnt-mgq.2","title":"Remove docker login from build-nix-images.yaml manifest job","description":"Remove the docker login step (lines 155-157) from the manifest job in .github/workflows/build-nix-images.yaml. This step runs docker login ghcr.io which fails with exit 127 because the default cleave hatchet removes Docker from the runner.\n\nThe docker login is redundant because mk-multi-arch-manifest.nix already handles authentication internally via skopeo login and crane auth login, reading credentials from the GITHUB_TOKEN env var that is already set on the manifest job (line 161). This matches the vanixiets containers.yaml pattern where the manifest job has no Docker steps at all.\n\nChanges needed:\n- Remove the \"Login to GitHub Container Registry\" step (lines 155-157)\n- Verify the GITHUB_TOKEN env var is still set on the \"Push manifest\" step (it already is)\n- The manifest job should have: checkout, setup-nix, push manifest (with GITHUB_TOKEN env var)\n\nReference: vanixiets .github/workflows/containers.yaml manifest job (lines 149-170) for the target pattern.\nReference: nix/lib/mk-multi-arch-manifest.nix for how auth works (skopeo login + crane auth login using registry.password = \"$GITHUB_TOKEN\").","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:06.640149-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:06.640149-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-mgq.3","title":"Remove QEMU setup from build job for production containers","description":"The build job in build-nix-images.yaml has a QEMU setup step (lines 107-110) conditionally enabled for type == dev containers. Production containers use pkgsCross for cross-compilation (no QEMU needed). When dev containers are migrated to nix2container, they should also use pkgsCross rather than QEMU emulation, matching the vanixiets pattern.\n\nEvaluate whether the QEMU setup step can be removed entirely once dev containers are migrated. If dev containers will use nix2container with pkgsCross (as production containers do), the QEMU step is no longer needed.\n\nThis aligns with the vanixiets containers.yaml build job which has no QEMU setup at all — it uses pkgsCross for all architectures.\n\nChanges needed:\n- Remove the Setup QEMU step and the docker/setup-qemu-action dependency\n- Remove the conditional extra-platforms aarch64-linux nix config (line 118) that was needed for QEMU emulation\n- Verify that cross-compilation via pkgsCross works for dev container builds\n\nThis depends on dev container migration to nix2container being complete.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:17.65854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:17.65854-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-mgq.4","title":"Align build-nix-images.yaml workflow structure with vanixiets containers.yaml","description":"After removing docker login (pnt-mgq.2) and QEMU setup (pnt-mgq.3), further align the build-nix-images.yaml workflow with the vanixiets containers.yaml reference pattern.\n\nDifferences to address:\n- Add concurrency group (vanixiets has: group: container-${{ github.ref }}, cancel-in-progress: true)\n- Add defaults.run.shell: bash (vanixiets convention)\n- Remove the apt-get install zstd step (lines 100-104) if it is no longer needed without Docker/QEMU\n- Align the build job to not use fetch-depth: 0 on checkout (vanixiets uses default shallow checkout for builds)\n- Add architecture verification step matching vanixiets pattern (verify OCI arch metadata)\n- Consider renaming workflow from \"Build Nix Images\" to \"Container Images\" to match vanixiets\n\nThe workflow should produce the same discover → build → manifest pipeline structure but without any Docker dependency, relying entirely on nix2container for building and skopeo/crane for pushing.\n\nReference: vanixiets .github/workflows/containers.yaml for the full target pattern.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:28.933224-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:28.933224-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-mgq.5","title":"Migrate dev containers from dockerTools to nix2container via upgraded nixpod","description":"Core migration task: update dev container builds to use nix2container once nixpod completes its internal migration from dockerTools.buildLayeredImageWithNixDb to nix2container.\n\nCurrent state:\n- modules/containers.nix production containers already use nix2container (mkProductionContainer function)\n- Dev containers still use nixpod buildMultiUserNixImage which internally uses dockerTools\n- flocken handles multi-arch manifest creation for dev containers\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template dev containers consume upgraded nixpod seamlessly\n- Dev container manifests use mk-multi-arch-manifest.nix (crane/skopeo-based, matching production containers)\n- flocken removed from flake.nix and flake.lock\n\nBlocked on: nixpod completing its nix2container migration (sciexp-h0g). The nixpod refactor-container-builds branch has research docs with full API mapping and implementation plan.\n\nChanges needed:\n- Update nixpod input version in flake.nix to post-migration release\n- Update modules/containers.nix dev container definitions to use new nixpod API (if API surface changes)\n- Replace flocken-based dev container manifest generation with mk-multi-arch-manifest.nix\n- Remove flocken from flake inputs\n- Preserve dev container functionality: multi-user Nix daemon, home-manager activation, s6-overlay, Jupyter, code-server\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-17T12:10:40.469904-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:40.469904-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-mgq.6","title":"Re-enable build-images in .ci.json and validate end-to-end CI","description":"After all workflow and container migration changes are complete, re-enable container image builds by setting \"build-images\": true in packages/python-nix-template/.ci.json (currently false, set by pnt-mgq.1 commit a7afe48 as interim fix).\n\nValidation checklist:\n- Set \"build-images\": true in packages/python-nix-template/.ci.json\n- Trigger build-nix-images.yaml workflow with push: false to verify discover + build jobs pass\n- Trigger with push: true to verify manifest job authenticates and pushes without Docker\n- Confirm all jobs run successfully with default cleave hatchet (no Docker on runner)\n- Verify multi-arch manifests are correctly created in ghcr.io\n- Confirm dev container images (once migrated) also build and push correctly\n\nThis is the final validation gate for the epic. All other pnt-mgq children must be complete before this issue can start.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:50.883513-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:50.883513-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} +{"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":"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-17T10:19:03.637507-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":"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.","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":"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","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":"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","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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"inreview","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:30:39.363-05:00"} +{"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.4","title":"Remove hardcoded pnt-cli defaults from justfile Rust and container recipes","description":"Remove hardcoded `pnt-cli` default values from justfile Rust and container recipe parameters. Extend `list-packages-json` to annotate maturin status.\n\n## Scope\n\n- Remove `=\"pnt-cli\"` defaults from: cargo-build, cargo-test, cargo-clippy, cargo-nextest, cargo-check (lines 409-430)\n- Remove `CONTAINER=\"pnt-cli\"` defaults from: container-build-production, container-load-production, container-push-production (lines ~296-307)\n- Rust and container recipes become required-parameter recipes (invoker must specify package name)\n- Extend `list-packages-json` recipe to emit `maturin` boolean field per package based on `Cargo.toml` presence\n- Consider adding a `list-maturin-packages` convenience recipe that filters to maturin-only packages\n\n## Acceptance criteria\n\n- `just cargo-build` without arguments produces a usage error, not a reference to pnt-cli\n- `just cargo-build pnt-cli` works when packages/pnt-cli exists\n- `just list-packages-json` output includes `\"maturin\": true/false` for each package\n- No hardcoded reference to `pnt-cli` as a default value remains in the justfile\n\n## Verification\n\n```bash\njust list-packages-json | jq '.[].maturin'\njust cargo-build 2\u003e\u00261 | grep -q 'error' # should fail without argument\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:38.288741-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.356577-05:00","closed_at":"2026-02-18T12:19:58.356577-05:00","close_reason":"Implemented in d64722e","dependencies":[{"issue_id":"pnt-kaf.4","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:38.290369-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.5","title":"Add is_maturin field to CI discover-packages step","description":"Add Cargo.toml presence detection to the CI discover-packages step in `.github/workflows/ci.yaml` so the CI matrix annotates which packages are maturin/pyo3 packages.\n\n## Scope\n\n- In the discover-packages step (ci.yaml lines 182-206), add a `Cargo.toml` probe:\n ```bash\n is_maturin=\"false\"\n if [ -f \"\\$d/Cargo.toml\" ]; then is_maturin=\"true\"; fi\n ```\n- Include `is_maturin` in the jq output object for each package\n- Downstream CI jobs can use this field to conditionally run Rust checks, skip maturin packages from uv-build, etc.\n- Verify that `package-release.yaml` detect-maturin step (lines 215-243) remains consistent with the new field\n\n## Acceptance criteria\n\n- CI discover-packages output includes `is_maturin` boolean per package\n- The field is `true` for packages with `Cargo.toml`, `false` otherwise\n- No CI behavioral change for existing workflows (the field is additive information)\n\n## Verification\n\nRun the discover-packages logic locally:\n```bash\nfind packages -maxdepth 2 -name pyproject.toml -path '*/*/pyproject.toml' | sort | while read -r f; do\n d=$(dirname \"$f\"); n=$(basename \"$d\")\n is_maturin=\"false\"\n [ -f \"$d/Cargo.toml\" ] \u0026\u0026 is_maturin=\"true\"\n printf '{\"name\":\"%s\",\"is_maturin\":%s}\\n' \"$n\" \"$is_maturin\"\ndone | jq -sc '.'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | clear | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | deep | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:52.376497-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.543923-05:00","closed_at":"2026-02-18T12:19:58.543923-05:00","close_reason":"Implemented in b5f4df4","dependencies":[{"issue_id":"pnt-kaf.5","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:52.377273-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.6","title":"Replace hardcoded pnt-cli check conditions in mergify.yml","description":"Replace the hardcoded pnt-cli and pnt-functional check-success/check-skipped conditions in `.github/mergify.yml` (lines 27-34) with a pattern that does not reference specific package names.\n\n## Scope\n\n- Lines 27-28 reference python-nix-template by name\n- Lines 30-31 reference pnt-functional by name\n- Lines 33-34 reference pnt-cli by name\n- Replace with either:\n a) A single wildcard regex matching all test-python checks: \\`check-success~=^test-python \\\\\\\\(.*\\`\n b) A dynamically generated mergify config (more complex, future consideration)\n c) Accept that mergify is manually maintained when packages change (pragmatic, acceptable for low-churn repos)\n- Evaluate which approach fits the project's merge queue requirements\n- The base package (python-nix-template placeholder) will always exist, so at minimum one concrete check can remain\n\n## Acceptance criteria\n\n- Mergify conditions do not reference pnt-cli or pnt-functional by name\n- PRs can still merge when all required checks pass\n- Missing packages (due to template toggle) do not block the merge queue\n\n## Verification\n\nReview mergify config syntax and test with a PR after changes are merged.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:06.147195-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:45.125678-05:00","closed_at":"2026-02-18T12:24:45.125678-05:00","close_reason":"Implemented in 9a4d8bb","dependencies":[{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:06.147883-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.6","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:31.740448-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-kaf.7","title":"Verify template instantiation with generalized discovery","description":"End-to-end verification that the generalized package discovery works correctly across both template variants and the post-instantiation pyo3 addition workflow.\n\n## Scope\n\n- Instantiate template with monorepo: true, pyo3: true — verify all packages discovered, Nix builds succeed, CI matrix correct\n- Instantiate template with monorepo: true, pyo3: false — verify pure Python packages discovered, no maturin-related errors, Rust tooling absent from devshell\n- Instantiate with pyo3: false, then manually add a pyo3 package directory with Cargo.toml and nix/packages/{name}/default.nix — verify infrastructure activates\n- Confirm template test in template.nix still passes\n- Verify flake inputs (crane, crane-maturin) are harmless when no maturin packages exist\n\n## Acceptance criteria\n\n- Both template variants instantiate without errors\n- \\`nix flake check\\` passes for both variants\n- \\`just test-all\\` passes for both variants\n- Post-instantiation pyo3 addition is detected by the discovery mechanism\n- Template omnix test passes: \\`nix flake check\\` (which runs template.nix tests)\n\n## Verification\n\n```bash\n# Full template test\nnix flake check --no-build\n\n# Or targeted template verification\njust template-verify\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:53:21.519266-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:30:23.648642-05:00","closed_at":"2026-02-18T12:30:23.648642-05:00","close_reason":"Verified in f705185 — all nix eval, justfile, CI, and residual-reference checks pass","dependencies":[{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:53:21.521466-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.900176-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.2","type":"blocks","created_at":"2026-02-18T11:53:32.062964-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.3","type":"blocks","created_at":"2026-02-18T11:53:32.219856-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.4","type":"blocks","created_at":"2026-02-18T11:53:32.382676-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.5","type":"blocks","created_at":"2026-02-18T11:53:32.556841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.7","depends_on_id":"pnt-kaf.6","type":"blocks","created_at":"2026-02-18T11:53:32.720394-05:00","created_by":"Cameron Smith"}]} +{"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":"Migrate dev container builds (containerImage, devcontainerImage) to nix2container once nixpod completes its nix2container migration. Also align the CI workflow (build-nix-images.yaml) with the vanixiets containers.yaml pattern.\n\nCurrent state:\n- modules/containers.nix already uses nix2container for production containers (pnt-cli) with mk-multi-arch-manifest.nix providing crane/skopeo-based manifest pushing\n- Dev containers still import buildMultiUserNixImage from nixpod, which 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- Container image builds disabled in CI via .ci.json \"build-images\": false (pnt-mgq.1, commit a7afe48) as interim fix\n\nDiscovered during CI investigation (2026-02-17):\n- The build-nix-images.yaml manifest job fails because setup-nix default hatchet (cleave, level 2) removes Docker before the manifest job runs docker login ghcr.io (exit 127 on docker binary)\n- The docker login step (lines 155-157) is actually redundant: mk-multi-arch-manifest.nix handles auth internally via skopeo login and crane auth login using GITHUB_TOKEN env var, matching the vanixiets pattern exactly\n- The vanixiets containers.yaml manifest job has no Docker dependency at all: it sets GITHUB_TOKEN as env var and runs nix run .#...Manifest, which authenticates via skopeo/crane under the hood\n- When vanixiets genuinely needs Docker (test-cluster.yaml for k3d), the compensatory pattern is: holster hatchet (level 0), mnt-safe-haven 15360, Docker prune, explicit docker version verification\n- The python-nix-template setup-nix action is already aligned with vanixiets (identical hatchet/safe-haven parameters)\n\nBlocked on: nixpod completing its nix2container migration for dev containers (refactor-container-builds branch has research docs with full API mapping and implementation plan)\n\nTarget state:\n- Production containers: already nix2container-based, CI workflow aligned with vanixiets (remove docker login, env-var auth only)\n- Dev containers: nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally), python-nix-template dev containers consume upgraded nixpod\n- Dev container manifests use crane-based tooling (mk-multi-arch-manifest.nix already supports this)\n- flocken fully removed from flake.nix\n- s6-overlay, home-manager activation, multi-user Nix preserved in container content\n\nAcceptance criteria:\n- build-nix-images.yaml manifest job uses env-var auth (GITHUB_TOKEN) without docker login, matching vanixiets containers.yaml pattern\n- build-nix-images.yaml has no Docker dependency in any job (discover, build, manifest)\n- Dev containers build using nixpod nix2container-based API\n- flocken fully removed from flake.nix (production containers already handle this via mk-multi-arch-manifest.nix)\n- No regression in dev container functionality (Jupyter, code-server, etc.)\n- Multi-arch publishing works via nix2container transport\n- .ci.json \"build-images\" re-enabled to true after migration complete\n- CI workflow passes end-to-end with default cleave hatchet\n\nKey files:\n- python-nix-template: .github/workflows/build-nix-images.yaml (manifest job lines 132-171)\n- python-nix-template: .github/actions/setup-nix/action.yml (hatchet input)\n- python-nix-template: modules/containers.nix (production containers already nix2container)\n- python-nix-template: nix/lib/mk-multi-arch-manifest.nix (skopeo/crane auth, no Docker)\n- python-nix-template: packages/python-nix-template/.ci.json (build-images toggle)\n- vanixiets: .github/workflows/containers.yaml (reference Docker-free manifest job)\n- vanixiets: .github/workflows/test-cluster.yaml (reference holster pattern for Docker needs)","status":"in_progress","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-17T12:09:55.057323-05:00"} +{"id":"pnt-mgq.1","title":"Disable container image builds in CI until nix2container migration","description":"The manifest job in build-nix-images.yaml fails because setup-nix cleave hatchet removes Docker before docker login runs (exit 127). Since container image builds are not needed while nix2container migration is planned (pnt-mgq), disable build-images in packages/python-nix-template/.ci.json.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:01:54.423936-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:02:39.630912-05:00","closed_at":"2026-02-17T12:02:39.630912-05:00","close_reason":"Implemented in a7afe48","dependencies":[{"issue_id":"pnt-mgq.1","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:01:54.424779-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-mgq.2","title":"Remove docker login from build-nix-images.yaml manifest job","description":"Remove the docker login step (lines 155-157) from the manifest job in .github/workflows/build-nix-images.yaml. This step runs docker login ghcr.io which fails with exit 127 because the default cleave hatchet removes Docker from the runner.\n\nThe docker login is redundant because mk-multi-arch-manifest.nix already handles authentication internally via skopeo login and crane auth login, reading credentials from the GITHUB_TOKEN env var that is already set on the manifest job (line 161). This matches the vanixiets containers.yaml pattern where the manifest job has no Docker steps at all.\n\nChanges needed:\n- Remove the \"Login to GitHub Container Registry\" step (lines 155-157)\n- Verify the GITHUB_TOKEN env var is still set on the \"Push manifest\" step (it already is)\n- The manifest job should have: checkout, setup-nix, push manifest (with GITHUB_TOKEN env var)\n\nReference: vanixiets .github/workflows/containers.yaml manifest job (lines 149-170) for the target pattern.\nReference: nix/lib/mk-multi-arch-manifest.nix for how auth works (skopeo login + crane auth login using registry.password = \"$GITHUB_TOKEN\").","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:06.640149-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:06.640149-05:00","dependencies":[{"issue_id":"pnt-mgq.2","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:06.640881-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-mgq.3","title":"Remove QEMU setup from build job for production containers","description":"The build job in build-nix-images.yaml has a QEMU setup step (lines 107-110) conditionally enabled for type == dev containers. Production containers use pkgsCross for cross-compilation (no QEMU needed). When dev containers are migrated to nix2container, they should also use pkgsCross rather than QEMU emulation, matching the vanixiets pattern.\n\nEvaluate whether the QEMU setup step can be removed entirely once dev containers are migrated. If dev containers will use nix2container with pkgsCross (as production containers do), the QEMU step is no longer needed.\n\nThis aligns with the vanixiets containers.yaml build job which has no QEMU setup at all — it uses pkgsCross for all architectures.\n\nChanges needed:\n- Remove the Setup QEMU step and the docker/setup-qemu-action dependency\n- Remove the conditional extra-platforms aarch64-linux nix config (line 118) that was needed for QEMU emulation\n- Verify that cross-compilation via pkgsCross works for dev container builds\n\nThis depends on dev container migration to nix2container being complete.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:17.65854-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:17.65854-05:00","dependencies":[{"issue_id":"pnt-mgq.3","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:17.659273-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-mgq.4","title":"Align build-nix-images.yaml workflow structure with vanixiets containers.yaml","description":"After removing docker login (pnt-mgq.2) and QEMU setup (pnt-mgq.3), further align the build-nix-images.yaml workflow with the vanixiets containers.yaml reference pattern.\n\nDifferences to address:\n- Add concurrency group (vanixiets has: group: container-${{ github.ref }}, cancel-in-progress: true)\n- Add defaults.run.shell: bash (vanixiets convention)\n- Remove the apt-get install zstd step (lines 100-104) if it is no longer needed without Docker/QEMU\n- Align the build job to not use fetch-depth: 0 on checkout (vanixiets uses default shallow checkout for builds)\n- Add architecture verification step matching vanixiets pattern (verify OCI arch metadata)\n- Consider renaming workflow from \"Build Nix Images\" to \"Container Images\" to match vanixiets\n\nThe workflow should produce the same discover → build → manifest pipeline structure but without any Docker dependency, relying entirely on nix2container for building and skopeo/crane for pushing.\n\nReference: vanixiets .github/workflows/containers.yaml for the full target pattern.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:28.933224-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:28.933224-05:00","dependencies":[{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:28.93436-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq.2","type":"blocks","created_at":"2026-02-17T12:10:58.368013-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.4","depends_on_id":"pnt-mgq.3","type":"blocks","created_at":"2026-02-17T12:10:58.521015-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-mgq.5","title":"Migrate dev containers from dockerTools to nix2container via upgraded nixpod","description":"Core migration task: update dev container builds to use nix2container once nixpod completes its internal migration from dockerTools.buildLayeredImageWithNixDb to nix2container.\n\nCurrent state:\n- modules/containers.nix production containers already use nix2container (mkProductionContainer function)\n- Dev containers still use nixpod buildMultiUserNixImage which internally uses dockerTools\n- flocken handles multi-arch manifest creation for dev containers\n\nTarget state:\n- nixpod exports nix2container-based builders (buildMultiUserNixImage rewritten internally)\n- python-nix-template dev containers consume upgraded nixpod seamlessly\n- Dev container manifests use mk-multi-arch-manifest.nix (crane/skopeo-based, matching production containers)\n- flocken removed from flake.nix and flake.lock\n\nBlocked on: nixpod completing its nix2container migration (sciexp-h0g). The nixpod refactor-container-builds branch has research docs with full API mapping and implementation plan.\n\nChanges needed:\n- Update nixpod input version in flake.nix to post-migration release\n- Update modules/containers.nix dev container definitions to use new nixpod API (if API surface changes)\n- Replace flocken-based dev container manifest generation with mk-multi-arch-manifest.nix\n- Remove flocken from flake inputs\n- Preserve dev container functionality: multi-user Nix daemon, home-manager activation, s6-overlay, Jupyter, code-server\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-17T12:10:40.469904-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:40.469904-05:00","dependencies":[{"issue_id":"pnt-mgq.5","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:40.470902-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-mgq.6","title":"Re-enable build-images in .ci.json and validate end-to-end CI","description":"After all workflow and container migration changes are complete, re-enable container image builds by setting \"build-images\": true in packages/python-nix-template/.ci.json (currently false, set by pnt-mgq.1 commit a7afe48 as interim fix).\n\nValidation checklist:\n- Set \"build-images\": true in packages/python-nix-template/.ci.json\n- Trigger build-nix-images.yaml workflow with push: false to verify discover + build jobs pass\n- Trigger with push: true to verify manifest job authenticates and pushes without Docker\n- Confirm all jobs run successfully with default cleave hatchet (no Docker on runner)\n- Verify multi-arch manifests are correctly created in ghcr.io\n- Confirm dev container images (once migrated) also build and push correctly\n\nThis is the final validation gate for the epic. All other pnt-mgq children must be complete before this issue can start.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-17T12:10:50.883513-05:00","created_by":"Cameron Smith","updated_at":"2026-02-17T12:10:50.883513-05:00","dependencies":[{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq","type":"parent-child","created_at":"2026-02-17T12:10:50.884185-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.2","type":"blocks","created_at":"2026-02-17T12:10:58.674666-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.3","type":"blocks","created_at":"2026-02-17T12:10:58.83841-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.4","type":"blocks","created_at":"2026-02-17T12:10:59.000711-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-mgq.6","depends_on_id":"pnt-mgq.5","type":"blocks","created_at":"2026-02-17T12:10:59.156801-05:00","created_by":"Cameron Smith"}]} +{"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."} From 8eb9bf37e2f697b82703ee80845222feb3bb4d84 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 13:52:10 -0500 Subject: [PATCH 14/39] chore(beads): checkpoint pnt-kaf with follow-up template substitution context --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index ce666a50..059ae7fa 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -46,7 +46,7 @@ {"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-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"inreview","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:30:39.363-05:00"} +{"id":"pnt-kaf","title":"Generalize package discovery to eliminate hardcoded names","description":"Replace all hardcoded package names (pnt-cli, pnt-functional, python-nix-template) across Nix modules, justfile, CI workflows, and mergify with dynamic discovery based on builtins.readDir and Cargo.toml presence detection.\n\n## Design\n\nThe canonical marker for maturin/pyo3 packages is `packages/{name}/Cargo.toml`. All layers discover packages dynamically:\n\n- Nix modules enumerate `packages/` via `builtins.readDir`, classify by `Cargo.toml` presence\n- Justfile recipes lose hardcoded defaults, `list-packages-json` annotates maturin status\n- CI `discover-packages` step adds `is_maturin` field to matrix output\n- Mergify conditions no longer reference specific package names\n- Convention: each maturin package requires `nix/packages/{name}/default.nix` returning `{ overlay, checks }`\n- Flake inputs (crane, crane-maturin) remain always present regardless of template toggle\n\n## Relationship to pnt-wl6\n\nThis epic may supersede some pnt-wl6 children (wl6.8, wl6.12, wl6.13, wl6.3). Reassess pnt-wl6 after this epic completes.\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18)\n\nWhat was done: All 7 children implemented and verified. PR #92 merged to main after CI passed (CI/CD + Template workflows). Epic branch pnt-kaf-generalized-discovery contains 12 implementation commits replacing hardcoded package names across python.nix, devshell.nix, containers.nix, justfile, ci.yaml, and mergify.yml with builtins.readDir-based discovery and Cargo.toml classification.\n\nWhat was learned: The containers.nix module replicates discovery logic at module level rather than consuming _module.args because flake.containerMatrix operates outside perSystem scope. This is a known architectural constraint of flake-parts module composition.\n\nWhat remains: Epic is complete and eligible for closure. However, a follow-up workstream was identified: the template substitution mechanism in modules/template.nix conflates repository name with primary package name. When instantiated with a different repo name than package name (e.g. sciexp/data hosting package omicsio), 14 post-instantiation fixes are needed. Evidence exists at ~/projects/sciexp/data (init branch). Next session should examine those fix commits, classify the substitution contexts (repo-name, platform-identity, template-reference), and design a repo-name parameter with backward-compatible default. This may extend pnt-kaf or become a new epic depending on scope assessment.\n\nDownstream impact: The new _module.args exports (packageNames, maturinPackageNames, purePackageNames, hasMaturinPackages) are consumed by devshell.nix and containers.nix. Any future Nix modules needing package classification should consume these args rather than reimplementing discovery.\n\u003c!-- /checkpoint-context --\u003e","status":"inreview","priority":2,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:51:28.720914-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T13:52:04.516504-05:00"} {"id":"pnt-kaf.1","title":"Replace hardcoded package enumeration in python.nix with readDir discovery","description":"Core Nix module change. Replace all hardcoded `builtins.pathExists ../packages/pnt-cli` and `builtins.pathExists ../packages/pnt-functional` declarations in `modules/python.nix` with dynamic discovery using `builtins.readDir ../packages`.\n\n## Scope\n\n- Add package discovery logic: enumerate `packages/` via `builtins.readDir`, filter directories, classify as maturin (`Cargo.toml` present) vs pure Python\n- Generalize `packageWorkspaces`: iterate discovered package names through `loadPackage` instead of hardcoding three entries (lines 45-53)\n- Generalize `mkPackageModule`: iterate `maturinPackageNames`, import `nix/packages/{name}/default.nix` for each, compose overlays and checks (lines 65-74)\n- Generalize `mkPythonSet` overlay composition: replace `lib.optional hasCli packageWorkspaces.pnt-cli.overlay` pattern with iteration over discovered packages (lines 91-104)\n- Generalize `mkEditablePythonSet`: iterate `purePackageNames` only (maturin packages excluded per existing convention at line 107-110)\n- Generalize `rustChecks` collection: iterate all maturin package modules (lines 146-150)\n- Expose `hasMaturinPackages`, `maturinPackageNames`, `purePackageNames` via `_module.args` for devshell.nix and containers.nix\n- Add eval-time error when `Cargo.toml` exists but `nix/packages/{name}/default.nix` is missing\n- The base package name (currently `python-nix-template`) is the omnix placeholder — it must participate in discovery like any other package, not be hardcoded separately\n\n## Acceptance criteria\n\n- `nix eval .#packages.x86_64-linux --json | jq 'keys'` succeeds and includes all existing package outputs\n- `nix eval .#checks.x86_64-linux --json | jq 'keys'` includes pnt-cli checks when packages/pnt-cli exists\n- `nix build .#packages.x86_64-linux.default` succeeds\n- Adding a new pure Python package to `packages/` is picked up without editing python.nix\n- Removing `packages/pnt-cli` causes maturin-related overlays and checks to disappear without errors\n\n## Verification\n\n```bash\nnix flake check --no-build\nnix eval .#packages.x86_64-darwin --json | jq 'keys'\nnix eval .#checks.x86_64-darwin --json | jq 'keys'\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:02.76287-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:19:58.165915-05:00","closed_at":"2026-02-18T12:19:58.165915-05:00","close_reason":"Implemented in f03617b","dependencies":[{"issue_id":"pnt-kaf.1","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:02.7641-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.2","title":"Replace hardcoded hasCli in devshell.nix with discovery-based detection","description":"Replace `hasCli = builtins.pathExists ../packages/pnt-cli` in `modules/devshell.nix` (line 18) with `hasMaturinPackages` consumed from `_module.args` as exposed by the generalized python.nix.\n\n## Scope\n\n- Remove local `hasCli` declaration\n- Consume `hasMaturinPackages` from `_module.args` (provided by pnt-kaf.1)\n- Replace `lib.optionals hasCli` (line 58) with `lib.optionals hasMaturinPackages`\n- Update comment on line 61 from \"Rust tooling for pnt-cli pyo3 extension\" to generic \"Rust tooling for maturin/pyo3 packages\"\n\n## Acceptance criteria\n\n- `nix develop` enters devshell successfully\n- When `packages/pnt-cli` exists: cargo, rustc, clippy, cargo-nextest, maturin are on PATH\n- When no maturin packages exist: Rust tools absent from PATH\n- No hardcoded reference to `pnt-cli` remains in devshell.nix\n\n## Verification\n\n```bash\nnix develop -c which cargo # should succeed when maturin packages exist\nnix develop -c which maturin\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:14.654722-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.792724-05:00","closed_at":"2026-02-18T12:24:44.792724-05:00","close_reason":"Implemented in 21a0288","dependencies":[{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:14.655494-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.2","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.425769-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-kaf.3","title":"Replace hardcoded container definitions in containers.nix with discovery","description":"Replace the hardcoded `productionContainerDefs` attrset in `modules/containers.nix` (lines 14-20) with a discovery-based mechanism that derives container definitions from per-package metadata rather than naming `pnt-cli` explicitly.\n\n## Scope\n\n- Remove local `hasCli = builtins.pathExists ../packages/pnt-cli` declaration (line 10)\n- Replace hardcoded `productionContainerDefs` with discovery. Two approaches to evaluate:\n a) Per-package `.container.nix` or `.ci.json` metadata declaring entrypoint and description\n b) Derive from `[project.scripts]` in `pyproject.toml` via Nix evaluation\n Option (a) aligns with existing `.ci.json` convention used in CI discover-packages.\n- Consume `maturinPackageNames` or similar from `_module.args` if container definitions should be restricted to maturin packages, or generalize to allow any package to declare a container\n- `containerMatrix` flake output should reflect dynamically discovered containers\n\n## Acceptance criteria\n\n- `nix eval .#containerMatrix --json` reflects discovered packages\n- No hardcoded reference to `pnt-cli` remains in containers.nix\n- When `packages/pnt-cli` exists with container metadata: container appears in matrix\n- When no container-capable packages exist: empty matrix, no errors\n\n## Verification\n\n```bash\nnix eval .#containerMatrix --json | jq .\n```\n\n\u003c!-- stigmergic-signals --\u003e\n| Signal | Value | Updated |\n|---|---|---|\n| schema-version | 1 | 2026-02-18 |\n| cynefin | complicated | 2026-02-18 |\n| surprise | 0.0 | 2026-02-18 |\n| progress | not-started | 2026-02-18 |\n| escalation | none | -- |\n| planning-depth | medium | 2026-02-18 |\n\u003c!-- /stigmergic-signals --\u003e","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T11:52:26.815361-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T12:24:44.965436-05:00","closed_at":"2026-02-18T12:24:44.965436-05:00","close_reason":"Implemented in 5292a0a","dependencies":[{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf","type":"parent-child","created_at":"2026-02-18T11:52:26.816289-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-kaf.3","depends_on_id":"pnt-kaf.1","type":"blocks","created_at":"2026-02-18T11:53:31.581192-05:00","created_by":"Cameron Smith"}]} From 823609e51417aec96216599b96449a0247193a7c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 14:39:27 -0500 Subject: [PATCH 15/39] chore(beads): create pnt-2nw epic for repo-name/package-name disambiguation --- .beads/issues.jsonl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 059ae7fa..6a4fe4ca 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,4 +1,10 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:09.771537-05:00"} +{"id":"pnt-2nw.1","title":"Rename primary package from python-nix-template to pnt-core","description":"Move packages/python-nix-template/ to packages/pnt-core/. Rename src/python_nix_template/ to src/pnt_core/. Update pyproject.toml name, scripts entry point, build paths, test paths, coverage paths. Update package.json name and repository URL. Create dummy semantic-release tag pnt-core-v0.2.1 on HEAD for version contiguity with the last python-nix-template-v0.2.1 release.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:19.514833-05:00","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.2","title":"Update Nix module references for renamed package","description":"Rename hardcoded Nix attributes: pythonNixTemplate312 to pntCore312, pythonNixTemplate313 to pntCore313 in modules/packages.nix and modules/devshell.nix. Update string references like mkVirtualEnv name args. Update docs/_quarto.yml quartodoc package from python_nix_template to pnt_core. Verify readDir-based discovery in modules/python.nix correctly discovers the renamed package directory.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:27.11666-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description 'Repository name (kebab-case)'. Change package-name-kebab-case placeholder from python-nix-template to pnt-core. Change package-name-snake-case placeholder from python_nix_template to pnt_core. Change package-name-camel-case placeholder from pythonNixTemplate to pntCore. Update template tests to include repo-name param. Verify that repo-name contexts in template files (GitHub URLs, container paths, worker domains, etc.) still contain the literal string python-nix-template which is now the repo-name placeholder.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:35.063916-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Template init commands (github:sciexp/python-nix-template) in justfile and docs/notes/archive/README.md contain both the git-org placeholder (sciexp) and the repo-name placeholder (python-nix-template), causing double substitution. Fix by: (a) adding docs/notes/archive/ to the nix-template path toggle in template.nix so it is excluded by default, and (b) restructuring the justfile init recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default value.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:42.754058-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Verify nix build, nix flake check, and pytest pass after all changes. Document verification commands for template instantiation in both convergent case (repo-name == package-name) and divergent case (repo-name != package-name, e.g. repo=data package=omicsio). Verify the fix-template-names utility in template-rename.nix still works or update if needed.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:49.792574-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-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"}]} From d25ef29064abeea2b37810421a7b52493a7ebeec Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 14:45:45 -0500 Subject: [PATCH 16/39] chore(beads): checkpoint pnt-2nw planning session --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 6a4fe4ca..7084f49e 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,5 +1,5 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:09.771537-05:00"} +{"id":"pnt-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18)\n\nWhat was done: Created epic and 5 child issues from analysis of sciexp/data post-instantiation fix commits. Determined that the primary package should be renamed from python-nix-template to pnt-core so that repo-name and package-name have naturally distinct omnix placeholder strings. Designed dependency graph: .1 (rename) unblocks .2 (Nix refs) and .3 (template.nix params) in parallel, .3 unblocks .4 (template refs), all unblock .5 (verification).\n\nWhat was learned: The omnix template mechanism performs global find-and-replace of placeholder strings. The fundamental tension was that python-nix-template serves as both the repo name and the package name in the template source. Renaming the package eliminates this ambiguity structurally rather than through synthetic placeholder strings. A dummy semantic-release tag (pnt-core-v0.2.1) is needed for version contiguity after the rename. User confirmed repo-name should be a required parameter, not optional with a default.\n\nWhat remains: All 5 issues are pending implementation. Branch pnt-2nw-disambiguate-names needs to be created from HEAD of pnt-kaf-generalized-discovery. PR #92 from pnt-kaf-generalized-discovery into main is still open; the new epic branch will stack on it.\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name (e.g., repo=data, package=omicsio) will work without post-instantiation fixes. sciexp/data can be re-instantiated cleanly.\n\u003c!-- /checkpoint-context --\u003e","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:45:34.810595-05:00"} {"id":"pnt-2nw.1","title":"Rename primary package from python-nix-template to pnt-core","description":"Move packages/python-nix-template/ to packages/pnt-core/. Rename src/python_nix_template/ to src/pnt_core/. Update pyproject.toml name, scripts entry point, build paths, test paths, coverage paths. Update package.json name and repository URL. Create dummy semantic-release tag pnt-core-v0.2.1 on HEAD for version contiguity with the last python-nix-template-v0.2.1 release.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:19.514833-05:00","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.2","title":"Update Nix module references for renamed package","description":"Rename hardcoded Nix attributes: pythonNixTemplate312 to pntCore312, pythonNixTemplate313 to pntCore313 in modules/packages.nix and modules/devshell.nix. Update string references like mkVirtualEnv name args. Update docs/_quarto.yml quartodoc package from python_nix_template to pnt_core. Verify readDir-based discovery in modules/python.nix correctly discovers the renamed package directory.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:27.11666-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description 'Repository name (kebab-case)'. Change package-name-kebab-case placeholder from python-nix-template to pnt-core. Change package-name-snake-case placeholder from python_nix_template to pnt_core. Change package-name-camel-case placeholder from pythonNixTemplate to pntCore. Update template tests to include repo-name param. Verify that repo-name contexts in template files (GitHub URLs, container paths, worker domains, etc.) still contain the literal string python-nix-template which is now the repo-name placeholder.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:35.063916-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} From d7d6e19e34d74386b9dcd3f51c48182a35bd437c Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:18:30 -0500 Subject: [PATCH 17/39] chore(beads): update pnt-2nw issues with definitive classification context Merge .1 and .2 scope so rename and Nix attribute updates happen atomically. Update all 5 issue descriptions with full rename/leave classification derived from sciexp/data fix commit analysis. --- .beads/issues.jsonl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 7084f49e..80f63f73 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,10 +1,10 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18)\n\nWhat was done: Created epic and 5 child issues from analysis of sciexp/data post-instantiation fix commits. Determined that the primary package should be renamed from python-nix-template to pnt-core so that repo-name and package-name have naturally distinct omnix placeholder strings. Designed dependency graph: .1 (rename) unblocks .2 (Nix refs) and .3 (template.nix params) in parallel, .3 unblocks .4 (template refs), all unblock .5 (verification).\n\nWhat was learned: The omnix template mechanism performs global find-and-replace of placeholder strings. The fundamental tension was that python-nix-template serves as both the repo name and the package name in the template source. Renaming the package eliminates this ambiguity structurally rather than through synthetic placeholder strings. A dummy semantic-release tag (pnt-core-v0.2.1) is needed for version contiguity after the rename. User confirmed repo-name should be a required parameter, not optional with a default.\n\nWhat remains: All 5 issues are pending implementation. Branch pnt-2nw-disambiguate-names needs to be created from HEAD of pnt-kaf-generalized-discovery. PR #92 from pnt-kaf-generalized-discovery into main is still open; the new epic branch will stack on it.\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name (e.g., repo=data, package=omicsio) will work without post-instantiation fixes. sciexp/data can be re-instantiated cleanly.\n\u003c!-- /checkpoint-context --\u003e","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:45:34.810595-05:00"} -{"id":"pnt-2nw.1","title":"Rename primary package from python-nix-template to pnt-core","description":"Move packages/python-nix-template/ to packages/pnt-core/. Rename src/python_nix_template/ to src/pnt_core/. Update pyproject.toml name, scripts entry point, build paths, test paths, coverage paths. Update package.json name and repository URL. Create dummy semantic-release tag pnt-core-v0.2.1 on HEAD for version contiguity with the last python-nix-template-v0.2.1 release.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:19.514833-05:00","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.2","title":"Update Nix module references for renamed package","description":"Rename hardcoded Nix attributes: pythonNixTemplate312 to pntCore312, pythonNixTemplate313 to pntCore313 in modules/packages.nix and modules/devshell.nix. Update string references like mkVirtualEnv name args. Update docs/_quarto.yml quartodoc package from python_nix_template to pnt_core. Verify readDir-based discovery in modules/python.nix correctly discovers the renamed package directory.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:27.11666-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description 'Repository name (kebab-case)'. Change package-name-kebab-case placeholder from python-nix-template to pnt-core. Change package-name-snake-case placeholder from python_nix_template to pnt_core. Change package-name-camel-case placeholder from pythonNixTemplate to pntCore. Update template tests to include repo-name param. Verify that repo-name contexts in template files (GitHub URLs, container paths, worker domains, etc.) still contain the literal string python-nix-template which is now the repo-name placeholder.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:35.063916-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Template init commands (github:sciexp/python-nix-template) in justfile and docs/notes/archive/README.md contain both the git-org placeholder (sciexp) and the repo-name placeholder (python-nix-template), causing double substitution. Fix by: (a) adding docs/notes/archive/ to the nix-template path toggle in template.nix so it is excluded by default, and (b) restructuring the justfile init recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default value.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:42.754058-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Verify nix build, nix flake check, and pytest pass after all changes. Document verification commands for template instantiation in both convergent case (repo-name == package-name) and divergent case (repo-name != package-name, e.g. repo=data package=omicsio). Verify the fix-template-names utility in template-rename.nix still works or update if needed.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T14:38:49.792574-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:42.700934-05:00"} +{"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:26.0567-05:00","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:41.590114-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:59.035277-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:12.270617-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:23.223935-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-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"}]} From 504ad46de152a381b94b6dd4ab59a682efa8330a Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:25:04 -0500 Subject: [PATCH 18/39] refactor: rename packages/python-nix-template to packages/pnt-core Rename the primary package directory and its source module from python_nix_template to pnt_core. --- packages/{python-nix-template => pnt-core}/.ci.json | 0 packages/{python-nix-template => pnt-core}/README.md | 0 packages/{python-nix-template => pnt-core}/conda/README.md | 0 .../conda/default_linux-64_conda_spec.txt | 0 .../conda/default_osx-arm64_conda_spec.txt | 0 .../conda/dev_linux-64_conda_spec.txt | 0 .../conda/dev_osx-arm64_conda_spec.txt | 0 .../conda/docs_linux-64_conda_spec.txt | 0 .../conda/docs_osx-arm64_conda_spec.txt | 0 .../conda/interactive_linux-64_conda_spec.txt | 0 .../conda/interactive_osx-arm64_conda_spec.txt | 0 .../conda/lint_linux-64_conda_spec.txt | 0 .../conda/lint_osx-arm64_conda_spec.txt | 0 .../conda/test_linux-64_conda_spec.txt | 0 .../conda/test_osx-arm64_conda_spec.txt | 0 .../conda/types_linux-64_conda_spec.txt | 0 .../conda/types_osx-arm64_conda_spec.txt | 0 packages/{python-nix-template => pnt-core}/package.json | 0 packages/{python-nix-template => pnt-core}/pixi.lock | 0 packages/{python-nix-template => pnt-core}/pyproject.toml | 0 packages/{python-nix-template => pnt-core}/src/.keep | 0 .../src/python_nix_template => pnt-core/src/pnt_core}/__init__.py | 0 .../src/python_nix_template => pnt-core/src/pnt_core}/tests/.keep | 0 .../src/pnt_core}/tests/__init__.py | 0 .../src/pnt_core}/tests/test_main.py | 0 packages/{python-nix-template => pnt-core}/uv.lock | 0 26 files changed, 0 insertions(+), 0 deletions(-) rename packages/{python-nix-template => pnt-core}/.ci.json (100%) rename packages/{python-nix-template => pnt-core}/README.md (100%) rename packages/{python-nix-template => pnt-core}/conda/README.md (100%) rename packages/{python-nix-template => pnt-core}/conda/default_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/default_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/dev_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/dev_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/docs_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/docs_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/interactive_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/interactive_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/lint_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/lint_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/test_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/test_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/types_linux-64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/conda/types_osx-arm64_conda_spec.txt (100%) rename packages/{python-nix-template => pnt-core}/package.json (100%) rename packages/{python-nix-template => pnt-core}/pixi.lock (100%) rename packages/{python-nix-template => pnt-core}/pyproject.toml (100%) rename packages/{python-nix-template => pnt-core}/src/.keep (100%) rename packages/{python-nix-template/src/python_nix_template => pnt-core/src/pnt_core}/__init__.py (100%) rename packages/{python-nix-template/src/python_nix_template => pnt-core/src/pnt_core}/tests/.keep (100%) rename packages/{python-nix-template/src/python_nix_template => pnt-core/src/pnt_core}/tests/__init__.py (100%) rename packages/{python-nix-template/src/python_nix_template => pnt-core/src/pnt_core}/tests/test_main.py (100%) rename packages/{python-nix-template => pnt-core}/uv.lock (100%) diff --git a/packages/python-nix-template/.ci.json b/packages/pnt-core/.ci.json similarity index 100% rename from packages/python-nix-template/.ci.json rename to packages/pnt-core/.ci.json diff --git a/packages/python-nix-template/README.md b/packages/pnt-core/README.md similarity index 100% rename from packages/python-nix-template/README.md rename to packages/pnt-core/README.md diff --git a/packages/python-nix-template/conda/README.md b/packages/pnt-core/conda/README.md similarity index 100% rename from packages/python-nix-template/conda/README.md rename to packages/pnt-core/conda/README.md diff --git a/packages/python-nix-template/conda/default_linux-64_conda_spec.txt b/packages/pnt-core/conda/default_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/default_linux-64_conda_spec.txt rename to packages/pnt-core/conda/default_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/default_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/default_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/default_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/default_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/dev_linux-64_conda_spec.txt b/packages/pnt-core/conda/dev_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/dev_linux-64_conda_spec.txt rename to packages/pnt-core/conda/dev_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/dev_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/dev_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/dev_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/dev_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/docs_linux-64_conda_spec.txt b/packages/pnt-core/conda/docs_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/docs_linux-64_conda_spec.txt rename to packages/pnt-core/conda/docs_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/docs_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/docs_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/docs_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/docs_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/interactive_linux-64_conda_spec.txt b/packages/pnt-core/conda/interactive_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/interactive_linux-64_conda_spec.txt rename to packages/pnt-core/conda/interactive_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/interactive_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/interactive_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/interactive_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/interactive_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/lint_linux-64_conda_spec.txt b/packages/pnt-core/conda/lint_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/lint_linux-64_conda_spec.txt rename to packages/pnt-core/conda/lint_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/lint_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/lint_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/lint_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/lint_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/test_linux-64_conda_spec.txt b/packages/pnt-core/conda/test_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/test_linux-64_conda_spec.txt rename to packages/pnt-core/conda/test_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/test_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/test_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/test_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/test_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/conda/types_linux-64_conda_spec.txt b/packages/pnt-core/conda/types_linux-64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/types_linux-64_conda_spec.txt rename to packages/pnt-core/conda/types_linux-64_conda_spec.txt diff --git a/packages/python-nix-template/conda/types_osx-arm64_conda_spec.txt b/packages/pnt-core/conda/types_osx-arm64_conda_spec.txt similarity index 100% rename from packages/python-nix-template/conda/types_osx-arm64_conda_spec.txt rename to packages/pnt-core/conda/types_osx-arm64_conda_spec.txt diff --git a/packages/python-nix-template/package.json b/packages/pnt-core/package.json similarity index 100% rename from packages/python-nix-template/package.json rename to packages/pnt-core/package.json diff --git a/packages/python-nix-template/pixi.lock b/packages/pnt-core/pixi.lock similarity index 100% rename from packages/python-nix-template/pixi.lock rename to packages/pnt-core/pixi.lock diff --git a/packages/python-nix-template/pyproject.toml b/packages/pnt-core/pyproject.toml similarity index 100% rename from packages/python-nix-template/pyproject.toml rename to packages/pnt-core/pyproject.toml diff --git a/packages/python-nix-template/src/.keep b/packages/pnt-core/src/.keep similarity index 100% rename from packages/python-nix-template/src/.keep rename to packages/pnt-core/src/.keep diff --git a/packages/python-nix-template/src/python_nix_template/__init__.py b/packages/pnt-core/src/pnt_core/__init__.py similarity index 100% rename from packages/python-nix-template/src/python_nix_template/__init__.py rename to packages/pnt-core/src/pnt_core/__init__.py diff --git a/packages/python-nix-template/src/python_nix_template/tests/.keep b/packages/pnt-core/src/pnt_core/tests/.keep similarity index 100% rename from packages/python-nix-template/src/python_nix_template/tests/.keep rename to packages/pnt-core/src/pnt_core/tests/.keep diff --git a/packages/python-nix-template/src/python_nix_template/tests/__init__.py b/packages/pnt-core/src/pnt_core/tests/__init__.py similarity index 100% rename from packages/python-nix-template/src/python_nix_template/tests/__init__.py rename to packages/pnt-core/src/pnt_core/tests/__init__.py diff --git a/packages/python-nix-template/src/python_nix_template/tests/test_main.py b/packages/pnt-core/src/pnt_core/tests/test_main.py similarity index 100% rename from packages/python-nix-template/src/python_nix_template/tests/test_main.py rename to packages/pnt-core/src/pnt_core/tests/test_main.py diff --git a/packages/python-nix-template/uv.lock b/packages/pnt-core/uv.lock similarity index 100% rename from packages/python-nix-template/uv.lock rename to packages/pnt-core/uv.lock From e52f32263cffff14f9c9294dbd1f0497b47fa294 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:26:14 -0500 Subject: [PATCH 19/39] refactor: update package-name references in pnt-core package files Rename python-nix-template to pnt-core in pyproject.toml, package.json, source code, tests, conda README, and CI config. --- packages/pnt-core/.ci.json | 2 +- packages/pnt-core/conda/README.md | 4 ++-- packages/pnt-core/package.json | 2 +- packages/pnt-core/pyproject.toml | 16 ++++++++-------- packages/pnt-core/src/pnt_core/__init__.py | 2 +- .../pnt-core/src/pnt_core/tests/test_main.py | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/pnt-core/.ci.json b/packages/pnt-core/.ci.json index e7dfdd5f..9ef21353 100644 --- a/packages/pnt-core/.ci.json +++ b/packages/pnt-core/.ci.json @@ -1,4 +1,4 @@ { "build-images": false, - "images": ["python-nix-template", "python-nix-template-dev"] + "images": ["pnt-core", "pnt-core-dev"] } diff --git a/packages/pnt-core/conda/README.md b/packages/pnt-core/conda/README.md index 283caa0e..35accf99 100644 --- a/packages/pnt-core/conda/README.md +++ b/packages/pnt-core/conda/README.md @@ -16,11 +16,11 @@ specific lockfile to construct a command of the form mamba create --name --file ``` -For example, for a conda environment named `python-nix-template` and the `dev` environment +For example, for a conda environment named `pnt-core` and the `dev` environment from the [pyproject.toml](../pyproject.toml) on x86_64-linux architecture run ```sh -mamba create --name python-nix-template --file dev_linux-64_conda_spec.txt +mamba create --name pnt-core --file dev_linux-64_conda_spec.txt ``` These environments will be missing packages that are sourced from pypi in the diff --git a/packages/pnt-core/package.json b/packages/pnt-core/package.json index c143f69e..80aa54e3 100644 --- a/packages/pnt-core/package.json +++ b/packages/pnt-core/package.json @@ -13,7 +13,7 @@ "node": ">=18" }, "license": "MIT", - "name": "python-nix-template", + "name": "pnt-core", "packageManager": "bun@1.3.4", "private": true, "release": { diff --git a/packages/pnt-core/pyproject.toml b/packages/pnt-core/pyproject.toml index 487a0b57..316f00bf 100644 --- a/packages/pnt-core/pyproject.toml +++ b/packages/pnt-core/pyproject.toml @@ -4,20 +4,20 @@ authors = [ ] dependencies = [] description = "Add your description here" -name = "python-nix-template" +name = "pnt-core" readme = "README.md" requires-python = ">=3.12,<3.14" version = "0.2.1" [project.scripts] -python-nix-template = "python_nix_template:main" +pnt-core = "pnt_core:main" [build-system] build-backend = "hatchling.build" requires = ["hatchling"] [tool.hatch.build.targets.wheel] -packages = ["src/python_nix_template"] +packages = ["src/pnt_core"] [dependency-groups] dev = [ @@ -60,7 +60,7 @@ preview = ["pixi-build"] python = ">=3.12,<3.14" [tool.pixi.pypi-dependencies] -python-nix-template = { path = ".", editable = true } +pnt-core = { path = ".", editable = true } [tool.pixi.environments] default = { solve-group = "default" } @@ -82,7 +82,7 @@ lint-check = "ruff check src/" types = "pyright src/" [tool.pixi.package] -name = "python-nix-template" +name = "pnt-core" version = "0.2.1" [tool.pixi.package.run-dependencies] @@ -103,17 +103,17 @@ addopts = """ -rA --xdoctest --disable-warnings ---cov=src/python_nix_template/ +--cov=src/pnt_core/ --cov-report=term-missing --cov-report=xml --durations=0 """ log_level = "INFO" testpaths = [ - "src/python_nix_template/tests", + "src/pnt_core/tests", ] [tool.coverage.run] omit = [ - "src/python_nix_template/tests/*", + "src/pnt_core/tests/*", ] diff --git a/packages/pnt-core/src/pnt_core/__init__.py b/packages/pnt-core/src/pnt_core/__init__.py index edac73e6..bd3c88fa 100644 --- a/packages/pnt-core/src/pnt_core/__init__.py +++ b/packages/pnt-core/src/pnt_core/__init__.py @@ -9,4 +9,4 @@ def main() -> None: - print("Hello from python-nix-template!") + print("Hello from pnt-core!") diff --git a/packages/pnt-core/src/pnt_core/tests/test_main.py b/packages/pnt-core/src/pnt_core/tests/test_main.py index c76b208e..2adda423 100644 --- a/packages/pnt-core/src/pnt_core/tests/test_main.py +++ b/packages/pnt-core/src/pnt_core/tests/test_main.py @@ -1,7 +1,7 @@ # TODO: restore absolute imports when # https://github.com/juspay/omnix/issues/425 # is resolved -# from python_nix_template import main +# from pnt_core import main from .. import main @@ -9,7 +9,7 @@ def test_main(capsys): """Test that the main function prints the expected greeting.""" main() captured = capsys.readouterr() - assert "Hello from python-nix-template!" in captured.out + assert "Hello from pnt-core!" in captured.out def test_main_returns_none(): From 33258bfd695d16a71fdf700b2a27553a8465754f Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:26:39 -0500 Subject: [PATCH 20/39] refactor: rename Nix package and devshell attrs to pntCore Update pythonNixTemplate* attr names to pntCore* and virtualenv name strings to pnt-core-3.1x in packages.nix and devshell.nix. --- modules/devshell.nix | 10 +++++----- modules/packages.nix | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/devshell.nix b/modules/devshell.nix index ff703952..b87a3af5 100644 --- a/modules/devshell.nix +++ b/modules/devshell.nix @@ -85,17 +85,17 @@ in { devShells = rec { - pythonNixTemplate312 = mkDevShell { - name = "python-nix-template-3.12"; + pntCore312 = mkDevShell { + name = "pnt-core-3.12"; pythonVersion = "py312"; }; - pythonNixTemplate313 = mkDevShell { - name = "python-nix-template-3.13"; + pntCore313 = mkDevShell { + name = "pnt-core-3.13"; pythonVersion = "py313"; }; - default = pythonNixTemplate313; + default = pntCore313; }; }; } diff --git a/modules/packages.nix b/modules/packages.nix index de9a05e6..2298144f 100644 --- a/modules/packages.nix +++ b/modules/packages.nix @@ -32,10 +32,10 @@ in { packages = rec { - pythonNixTemplate312 = pythonSets.py312.mkVirtualEnv "python-nix-template-3.12" defaultDeps; - pythonNixTemplate313 = pythonSets.py313.mkVirtualEnv "python-nix-template-3.13" defaultDeps; + pntCore312 = pythonSets.py312.mkVirtualEnv "pnt-core-3.12" defaultDeps; + pntCore313 = pythonSets.py313.mkVirtualEnv "pnt-core-3.13" defaultDeps; - default = pythonNixTemplate313; + default = pntCore313; }; }; } From a0ac0c9d80de1a0c87dd860308727d50501106eb Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:27:32 -0500 Subject: [PATCH 21/39] docs: update package-name references from python-nix-template to pnt-core Update quartodoc package name, API reference description, install commands, import examples, and architecture doc references. --- docs/_quarto.yml | 4 ++-- docs/guides/installation.qmd | 8 ++++---- docs/notes/architecture/crane-uv2nix-integration.md | 2 +- docs/notes/architecture/package-distribution-channels.md | 8 ++++---- docs/tutorials/getting-started.qmd | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/_quarto.yml b/docs/_quarto.yml index 94d2b4aa..a44bda86 100644 --- a/docs/_quarto.yml +++ b/docs/_quarto.yml @@ -115,7 +115,7 @@ website: quartodoc: dir: reference parser: google - package: python_nix_template + package: pnt_core title: Reference sidebar: reference/_sidbar.yml render_interlinks: true @@ -124,7 +124,7 @@ quartodoc: sections: - title: API Reference desc: | - API reference for python-nix-template. + API reference for pnt-core. contents: - name: main children: embedded diff --git a/docs/guides/installation.qmd b/docs/guides/installation.qmd index 9be4f6a1..c25ed636 100644 --- a/docs/guides/installation.qmd +++ b/docs/guides/installation.qmd @@ -12,7 +12,7 @@ This guide covers different ways to install python-nix-template. The fastest way to get started is with UV: ```bash -uv pip install python-nix-template +uv pip install pnt-core ``` ## Using Pip @@ -20,7 +20,7 @@ uv pip install python-nix-template You can also install with standard pip: ```bash -pip install python-nix-template +pip install pnt-core ``` ## Development Installation @@ -43,6 +43,6 @@ uv sync Verify your installation by running: ```python -import python-nix-template -print(python-nix-template.__version__) +import pnt_core +print(pnt_core.__version__) ``` \ No newline at end of file diff --git a/docs/notes/architecture/crane-uv2nix-integration.md b/docs/notes/architecture/crane-uv2nix-integration.md index 8ca5fba0..0a1c9bcc 100644 --- a/docs/notes/architecture/crane-uv2nix-integration.md +++ b/docs/notes/architecture/crane-uv2nix-integration.md @@ -410,7 +410,7 @@ This is a deliberate tradeoff: check caching provides fast CI feedback on the Ru Maturin packages are incompatible with uv2nix's `pyprojectFixupEditableHook`, which expects `EDITABLE_ROOT` to be set during the build process. Maturin's build backend does not set this variable. -The `mkEditablePythonSet` in `nix/modules/python.nix` composes editable overlays only for pure Python packages (`pnt-functional`, `python-nix-template`), excluding `pnt-cli`. +The `mkEditablePythonSet` in `nix/modules/python.nix` composes editable overlays only for pure Python packages (`pnt-functional`, `pnt-core`), excluding `pnt-cli`. The pnt-cli package is built as a regular wheel in the devshell. For iterative Rust development, the workflow is: enter the devshell via `nix develop`, then run `maturin develop --uv` in the package directory. diff --git a/docs/notes/architecture/package-distribution-channels.md b/docs/notes/architecture/package-distribution-channels.md index dc1cecbc..ccf406e9 100644 --- a/docs/notes/architecture/package-distribution-channels.md +++ b/docs/notes/architecture/package-distribution-channels.md @@ -23,12 +23,12 @@ uv and pixi serve as dependency resolution tools consumed by the nix layer, not Runtime dependencies (`beartype`, `expression`) are available on both PyPI and conda-forge. No channel-specific dependency graph differences for this package. -### python-nix-template +### pnt-core | Channel | Supported | Lock file | Runtime dependencies | |---------|-----------|-----------|---------------------| -| uv/PyPI | Yes | `packages/python-nix-template/uv.lock` | (none) | -| pixi/conda-forge | Yes | `packages/python-nix-template/pixi.lock` | python | +| uv/PyPI | Yes | `packages/pnt-core/uv.lock` | (none) | +| pixi/conda-forge | Yes | `packages/pnt-core/pixi.lock` | python | This package has no runtime dependencies beyond the Python interpreter. Dev dependencies (pytest, ruff, hypothesis, pyright, jupyter, quartodoc) are available on both channels. @@ -53,4 +53,4 @@ This allows packages to be built as conda packages in addition to PyPI wheels. | Build | `just uv-build ` | `just conda-build ` | | Lock | `just uv-lock ` | `just pixi-lock ` | -All recipes accept a package parameter defaulting to `python-nix-template`. +All recipes accept a package parameter defaulting to `pnt-core`. diff --git a/docs/tutorials/getting-started.qmd b/docs/tutorials/getting-started.qmd index e468dc20..5d89162e 100644 --- a/docs/tutorials/getting-started.qmd +++ b/docs/tutorials/getting-started.qmd @@ -23,7 +23,7 @@ See the [Installation Guide](../guides/installation.qmd) for detailed installati ```python # Example usage will be added here -print("Hello from python-nix-template!") +print("Hello from pnt-core!") ``` ## Next Steps From 3b6da044acc5c2b4c5ba022e26088e0a4e619062 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:28:03 -0500 Subject: [PATCH 22/39] refactor: update justfile package defaults from python-nix-template to pnt-core --- justfile | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/justfile b/justfile index 6508baab..9060d851 100644 --- a/justfile +++ b/justfile @@ -250,49 +250,49 @@ ci-check package: (ci-lint package) (ci-typecheck package) (ci-test package) # Package commands (conda) [group('conda')] -conda-build package="python-nix-template": +conda-build package="pnt-core": pixi build --manifest-path=packages/{{package}}/pyproject.toml # Create and sync conda environment with pixi [group('conda')] -conda-env package="python-nix-template": +conda-env package="pnt-core": pixi install --manifest-path=packages/{{package}}/pyproject.toml @echo "Conda environment is ready. Activate it with 'pixi shell'" # Update pixi lockfile [group('conda')] -pixi-lock package="python-nix-template": +pixi-lock package="pnt-core": pixi list --manifest-path=packages/{{package}}/pyproject.toml pixi tree --manifest-path=packages/{{package}}/pyproject.toml # Update conda environment [group('conda')] -conda-lock package="python-nix-template": +conda-lock package="pnt-core": pixi project export conda-explicit-spec packages/{{package}}/conda/ --manifest-path=packages/{{package}}/pyproject.toml --ignore-pypi-errors # Run tests in conda environment with pixi [group('conda')] -conda-test package="python-nix-template": +conda-test package="pnt-core": pixi run -e test --manifest-path=packages/{{package}}/pyproject.toml test # Run linting in conda environment with pixi [group('conda')] -conda-lint package="python-nix-template": +conda-lint package="pnt-core": pixi run -e lint --manifest-path=packages/{{package}}/pyproject.toml lint-check # Run linting and fix errors in conda environment with pixi [group('conda')] -conda-lint-fix package="python-nix-template": +conda-lint-fix package="pnt-core": pixi run -e lint --manifest-path=packages/{{package}}/pyproject.toml lint # Run type checking in conda environment with pixi [group('conda')] -conda-type package="python-nix-template": +conda-type package="pnt-core": pixi run -e types --manifest-path=packages/{{package}}/pyproject.toml types # Run all checks in conda environment (lint, type, test) [group('conda')] -conda-check package="python-nix-template": (conda-lint package) (conda-type package) (conda-test package) +conda-check package="pnt-core": (conda-lint package) (conda-type package) (conda-test package) @printf "\n\033[92mAll conda checks passed!\033[0m\n" ## Containers @@ -354,7 +354,7 @@ ci: # Run tests for a package [group('python')] -test package="python-nix-template": +test package="pnt-core": cd packages/{{package}} && pytest # Run tests for all packages @@ -370,22 +370,22 @@ test-all: # Build a package with uv [group('python')] -uv-build package="python-nix-template": +uv-build package="pnt-core": cd packages/{{package}} && uv build # Sync a package environment with uv [group('python')] -uv-sync package="python-nix-template": +uv-sync package="pnt-core": cd packages/{{package}} && uv sync # Update lockfile for a package [group('python')] -uv-lock package="python-nix-template": +uv-lock package="pnt-core": cd packages/{{package}} && uv lock # Run linting for a package [group('python')] -lint package="python-nix-template": +lint package="pnt-core": cd packages/{{package}} && ruff check src/ # Run linting for all packages @@ -395,17 +395,17 @@ lint-all: # Run linting and fix errors for a package [group('python')] -lint-fix package="python-nix-template": +lint-fix package="pnt-core": cd packages/{{package}} && ruff check --fix src/ # Run type checking for a package [group('python')] -type package="python-nix-template": +type package="pnt-core": cd packages/{{package}} && pyright src/ # Run all checks for a package (lint, type, test) [group('python')] -check package="python-nix-template": (lint package) (type package) (test package) +check package="pnt-core": (lint package) (type package) (test package) @printf "\nAll Python checks passed for {{package}}.\n" ## Rust @@ -728,7 +728,7 @@ test-release-direct: # Test package release [group('release')] -test-package-release package-name="python-nix-template" branch="main": +test-package-release package-name="pnt-core" branch="main": cd packages/{{package-name}} && bun run test-release -- -b {{branch}} # Preview release version for a package (dry-run semantic-release with merge simulation) From 831fa9619ba0f232dbca0723048167a8f5921d92 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:28:31 -0500 Subject: [PATCH 23/39] docs: update README recipe examples with pnt-core package defaults --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 78c10b02..38c30bca 100644 --- a/README.md +++ b/README.md @@ -262,15 +262,15 @@ Available recipes: test-docs-deploy branch=`git branch --show-current` # Test full deploy-docs workflow locally with act [conda] - conda-build package="python-nix-template" # Package commands (conda) - conda-check package="python-nix-template" # Run all checks in conda environment (lint, type, test) - conda-env package="python-nix-template" # Create and sync conda environment with pixi - conda-lint package="python-nix-template" # Run linting in conda environment with pixi - conda-lint-fix package="python-nix-template" # Run linting and fix errors in conda environment with pixi - conda-lock package="python-nix-template" # Update conda environment - conda-test package="python-nix-template" # Run tests in conda environment with pixi - conda-type package="python-nix-template" # Run type checking in conda environment with pixi - pixi-lock package="python-nix-template" # Update pixi lockfile + conda-build package="pnt-core" # Package commands (conda) + conda-check package="pnt-core" # Run all checks in conda environment (lint, type, test) + conda-env package="pnt-core" # Create and sync conda environment with pixi + conda-lint package="pnt-core" # Run linting in conda environment with pixi + conda-lint-fix package="pnt-core" # Run linting and fix errors in conda environment with pixi + conda-lock package="pnt-core" # Update conda environment + conda-test package="pnt-core" # Run tests in conda environment with pixi + conda-type package="pnt-core" # Run type checking in conda environment with pixi + pixi-lock package="pnt-core" # Update pixi lockfile [containers] container-build-production CONTAINER="pnt-cli" # Build production container image @@ -300,21 +300,21 @@ Available recipes: flake-update # Update all flake inputs to their latest versions [python] - check package="python-nix-template" # Run all checks for a package (lint, type, test) - lint package="python-nix-template" # Run linting for a package + check package="pnt-core" # Run all checks for a package (lint, type, test) + lint package="pnt-core" # Run linting for a package lint-all # Run linting for all packages - lint-fix package="python-nix-template" # Run linting and fix errors for a package - test package="python-nix-template" # Run tests for a package + lint-fix package="pnt-core" # Run linting and fix errors for a package + test package="pnt-core" # Run tests for a package test-all # Run tests for all packages - type package="python-nix-template" # Run type checking for a package - uv-build package="python-nix-template" # Build a package with uv - uv-lock package="python-nix-template" # Update lockfile for a package - uv-sync package="python-nix-template" # Sync a package environment with uv + type package="pnt-core" # Run type checking for a package + uv-build package="pnt-core" # Build a package with uv + uv-lock package="pnt-core" # Update lockfile for a package + uv-sync package="pnt-core" # Sync a package environment with uv [release] preview-version base-branch package-path # Preview release version for a package (dry-run semantic-release with merge simulation) release-package package-name dry-run="false" # Run semantic-release for a package - test-package-release package-name="python-nix-template" branch="main" # Test package release + test-package-release package-name="pnt-core" branch="main" # Test package release test-release # Release testing with bun test-release-as-main # Test release as if on main branch test-release-direct # Test release directly on release branch From 5608945a5071bc32eb0c5e6d0dab14d96c0654cc Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:30:58 -0500 Subject: [PATCH 24/39] refactor: update debug config module name to pnt-core --- .vscode/launch.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f7e0f0dc..03b84ef0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,10 +2,10 @@ "version": "0.1.0", "configurations": [ { - "name": "python-nix-template: Debug CLI", + "name": "pnt-core: Debug CLI", "type": "debugpy", "request": "launch", - "module": "python_nix_template", + "module": "pnt_core", "args": [ ], "console": "integratedTerminal", From 73078ef71bcfa6035ddcdeb4e31771d1ed79a0fe Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:31:03 -0500 Subject: [PATCH 25/39] docs: update pnt-functional conda env name to pnt-core --- packages/pnt-functional/conda/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pnt-functional/conda/README.md b/packages/pnt-functional/conda/README.md index 283caa0e..35accf99 100644 --- a/packages/pnt-functional/conda/README.md +++ b/packages/pnt-functional/conda/README.md @@ -16,11 +16,11 @@ specific lockfile to construct a command of the form mamba create --name --file ``` -For example, for a conda environment named `python-nix-template` and the `dev` environment +For example, for a conda environment named `pnt-core` and the `dev` environment from the [pyproject.toml](../pyproject.toml) on x86_64-linux architecture run ```sh -mamba create --name python-nix-template --file dev_linux-64_conda_spec.txt +mamba create --name pnt-core --file dev_linux-64_conda_spec.txt ``` These environments will be missing packages that are sourced from pypi in the From 8931e61f5e58da16af741cf6214710fde35651c3 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:34:36 -0500 Subject: [PATCH 26/39] chore(beads): close pnt-2nw.1 after rename implementation --- .beads/issues.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 80f63f73..31d6c164 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,6 +1,6 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"open","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:42.700934-05:00"} -{"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:26.0567-05:00","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:24:41.390914-05:00"} +{"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:34:36.630152-05:00","closed_at":"2026-02-18T15:34:36.630152-05:00","close_reason":"Implemented in 504ad46..73078ef. Renamed packages/python-nix-template to packages/pnt-core, updated Nix attrs to pntCore, all verification passed (nix build, nix flake check, pytest 2/2).","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:41.590114-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:59.035277-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:12.270617-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} From 964d4eeaf32978907552389789a4373da77158b7 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:41:26 -0500 Subject: [PATCH 27/39] chore(beads): close pnt-2nw.2 after discovery verification --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 31d6c164..0589f201 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,7 +1,7 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:24:41.390914-05:00"} {"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:34:36.630152-05:00","closed_at":"2026-02-18T15:34:36.630152-05:00","close_reason":"Implemented in 504ad46..73078ef. Renamed packages/python-nix-template to packages/pnt-core, updated Nix attrs to pntCore, all verification passed (nix build, nix flake check, pytest 2/2).","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:41.590114-05:00","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:41:26.572349-05:00","closed_at":"2026-02-18T15:41:26.572349-05:00","close_reason":"All 6 verification checks pass: readDir discovery finds pnt-core, Nix attrs are pntCore*, nix flake check passes, no stale package-name refs in modules. Remaining python-nix-template occurrences are repo-name contexts (containers.nix repoName, template.nix placeholders, CI/workflow GitHub URLs).","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:59.035277-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:12.270617-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:23.223935-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-05:00","created_by":"Cameron Smith"}]} From 93dae1ee6125f7ba047fc21c84040710a1425571 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:39:58 -0500 Subject: [PATCH 28/39] fix(template): update package-name placeholder values to match renamed package The package-name placeholders must reflect the actual strings present in template files after the pnt-core rename, so omnix substitution targets the correct literals. --- modules/template.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/template.nix b/modules/template.nix index 088df7a4..caa6f151 100644 --- a/modules/template.nix +++ b/modules/template.nix @@ -85,17 +85,17 @@ { name = "package-name-kebab-case"; description = "Name of the Python package (kebab-case)"; - placeholder = "python-nix-template"; + placeholder = "pnt-core"; } { name = "package-name-snake-case"; description = "Name of the Python package (snake_case)"; - placeholder = "python_nix_template"; + placeholder = "pnt_core"; } { name = "package-name-camel-case"; description = "Name of the Python package (camelCase)"; - placeholder = "pythonNixTemplate"; + placeholder = "pntCore"; } { name = "monorepo-package"; From 9c7a975ce5b83da169deeffcb1218e1c56bc7c43 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:40:15 -0500 Subject: [PATCH 29/39] feat(template): add repo-name parameter for repository name substitution Separates the repository name from the package name in template instantiation. The placeholder targets the literal "python-nix-template" strings remaining in repo-name contexts (README, flake description, GitHub URLs, docs prose). --- modules/template.nix | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/template.nix b/modules/template.nix index caa6f151..d7d01b1d 100644 --- a/modules/template.nix +++ b/modules/template.nix @@ -97,6 +97,11 @@ description = "Name of the Python package (camelCase)"; placeholder = "pntCore"; } + { + name = "repo-name"; + description = "Repository name (kebab-case)"; + placeholder = "python-nix-template"; + } { name = "monorepo-package"; description = "Include the functional programming monorepo package in the project"; From 3ef74953d9967af4c4511378b15ab9bd4d9416ab Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 15:40:34 -0500 Subject: [PATCH 30/39] test(template): add repo-name to template test params --- modules/template.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/template.nix b/modules/template.nix index d7d01b1d..01144c02 100644 --- a/modules/template.nix +++ b/modules/template.nix @@ -175,6 +175,7 @@ default = { params = { package-name = "awesome-package"; + repo-name = "test-repo"; author = "John Doe"; author-email = "john@example.com"; }; From 75ae5b64cf2f4316bef5c0855d02bfc5d8f6c3b1 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:16:47 -0500 Subject: [PATCH 31/39] chore(beads): close pnt-2nw.3 after template.nix repo-name parameter --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 0589f201..3794f7c5 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -2,7 +2,7 @@ {"id":"pnt-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:24:41.390914-05:00"} {"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:34:36.630152-05:00","closed_at":"2026-02-18T15:34:36.630152-05:00","close_reason":"Implemented in 504ad46..73078ef. Renamed packages/python-nix-template to packages/pnt-core, updated Nix attrs to pntCore, all verification passed (nix build, nix flake check, pytest 2/2).","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:41:26.572349-05:00","closed_at":"2026-02-18T15:41:26.572349-05:00","close_reason":"All 6 verification checks pass: readDir discovery finds pnt-core, Nix attrs are pntCore*, nix flake check passes, no stale package-name refs in modules. Remaining python-nix-template occurrences are repo-name contexts (containers.nix repoName, template.nix placeholders, CI/workflow GitHub URLs).","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:16:59.035277-05:00","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:16:47.171656-05:00","closed_at":"2026-02-18T16:16:47.171656-05:00","close_reason":"Implemented in fc71df7..3ef7495. Updated package-name placeholder values to pnt-core/pnt_core/pntCore, added repo-name parameter (default python-nix-template), updated template test params. nix flake check passes, repo-name confirmed in om.templates params.","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:12.270617-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:23.223935-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-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"}]} From 0eca74141daf6570080f900a5534b6d5ce92cef4 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:19:59 -0500 Subject: [PATCH 32/39] refactor(template): make template-ref a required parameter in template-init recipe The previous default value embedded github:sciexp/python-nix-template, which undergoes double placeholder substitution during omnix instantiation. Making template-ref a required parameter avoids this issue while also executing the init command directly rather than echoing usage instructions. --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 9060d851..b2db4e7a 100644 --- a/justfile +++ b/justfile @@ -610,8 +610,8 @@ sops-rotate role='dev' method='ssh': # Initialize new project from template [group('template')] -template-init: - echo "Use: nix --accept-flake-config run github:juspay/omnix/v1.3.2 -- init github:sciexp/python-nix-template -o new-python-project" +template-init template-ref: + nix --accept-flake-config run github:juspay/omnix/v1.3.2 -- init {{ template-ref }} -o new-python-project # Verify template functionality by creating and checking a test project [group('template')] From 1022d93a174e147318aabe27e511c8dc3f571e5d Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:20:12 -0500 Subject: [PATCH 33/39] docs: update README recipe listing with template-init parameter --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38c30bca..3efa0484 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ Available recipes: validate-secrets # Validate all sops encrypted files can be decrypted [template] - template-init # Initialize new project from template + template-init template-ref # Initialize new project from template template-verify # Verify template functionality by creating and checking a test project ``` From 2096d1a87146ceae6075a33163788d87dfb7c50b Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:22:02 -0500 Subject: [PATCH 34/39] chore(beads): close pnt-2nw.4 after template reference context fixes --- .beads/issues.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 3794f7c5..f7f50fc0 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -3,7 +3,7 @@ {"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:34:36.630152-05:00","closed_at":"2026-02-18T15:34:36.630152-05:00","close_reason":"Implemented in 504ad46..73078ef. Renamed packages/python-nix-template to packages/pnt-core, updated Nix attrs to pntCore, all verification passed (nix build, nix flake check, pytest 2/2).","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:41:26.572349-05:00","closed_at":"2026-02-18T15:41:26.572349-05:00","close_reason":"All 6 verification checks pass: readDir discovery finds pnt-core, Nix attrs are pntCore*, nix flake check passes, no stale package-name refs in modules. Remaining python-nix-template occurrences are repo-name contexts (containers.nix repoName, template.nix placeholders, CI/workflow GitHub URLs).","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:16:47.171656-05:00","closed_at":"2026-02-18T16:16:47.171656-05:00","close_reason":"Implemented in fc71df7..3ef7495. Updated package-name placeholder values to pnt-core/pnt_core/pntCore, added repo-name parameter (default python-nix-template), updated template test params. nix flake check passes, repo-name confirmed in om.templates params.","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"open","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:12.270617-05:00","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:22:02.22518-05:00","closed_at":"2026-02-18T16:22:02.22518-05:00","close_reason":"Implemented in 0eca741..1022d93. Made template-ref a required param in template-init recipe, updated README. Case 1 (docs/notes/archive/) was moot: directory never existed in git history. nix flake check passes.","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:23.223935-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-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"}]} From 321ed4754b643338dad8c6aefde181ad34cd9825 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:42:07 -0500 Subject: [PATCH 35/39] docs(readme): add repo-name and package-name-camel-case to instantiation examples Both convergent examples now include the new template parameters introduced by the disambiguation epic. Uses portable perl-based camelCase derivation instead of GNU sed. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 3efa0484..6cab14da 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,13 @@ tl;dr ```sh PROJECT_DIRECTORY=pnt-mono && \ PROJECT_SNAKE_CASE=$(echo "$PROJECT_DIRECTORY" | tr '-' '_') && \ +PROJECT_CAMEL_CASE=$(echo "$PROJECT_DIRECTORY" | perl -pe 's/-(.)/uc($1)/ge') && \ PARAMS=$(cat < Date: Wed, 18 Feb 2026 16:43:39 -0500 Subject: [PATCH 36/39] chore(beads): close pnt-2nw.5 and pnt-2nw epic after integration verification --- .beads/issues.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index f7f50fc0..1153cdd9 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,10 +1,10 @@ {"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-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"in_progress","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:24:41.390914-05:00"} +{"id":"pnt-2nw","title":"Disambiguate repo-name from package-name in template instantiation","description":"Rename primary package from python-nix-template to pnt-core so repo-name and package-name have distinct placeholder strings. Add repo-name omnix parameter. Eliminates 14+ post-instantiation fix commits observed when instantiating with divergent repo and package names (evidence: sciexp/data init branch).","notes":"\u003c!-- checkpoint-context --\u003e\n## State estimate (2026-02-18, session 2)\n\nWhat was done: Completed definitive classification of all ~109 occurrences of python-nix-template (and variant forms) across the repo. Used sciexp/data fix commits as authoritative evidence: items NOT fixed = package-name contexts (rename to pnt-core), items FIXED = repo-name contexts (leave as python-nix-template for repo-name placeholder). Merged .1 and .2 scope so Nix attribute updates happen alongside the rename to avoid broken intermediate state. Updated all 5 issue descriptions with comprehensive context.\n\nKey classification decisions:\n- Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) classified as REPO-NAME because one docs site per repo. These stay as python-nix-template and become the repo-name placeholder.\n- .ci.json container image names classified as PACKAGE-NAME (not fixed in sciexp/data). Renamed to pnt-core/pnt-core-dev. These are intentionally disabled pending nixpod/nix2container migration.\n- Root package.json name field classified as REPO-NAME (fixed in sciexp/data to @sciexp/data).\n- flake.nix description prefix, docs site titles, README header, bootstrap banner all classified as REPO-NAME (fixed in sciexp/data).\n- template.nix placeholder value updates are in .3's scope, not .1. template.nix om.templates key name stays as python-nix-template.\n- Dummy tag pnt-core-v0.2.1 placed on same commit as python-nix-template-v0.2.1, not HEAD.\n\nWhat was learned: The classification methodology (sciexp/data fix commits as ground truth) is robust. Total: ~51 package-name occurrences to rename, ~32 repo-name occurrences to leave, ~25 platform-identity occurrences classified as repo-name after user decision on docs site identity. snake_case and camelCase variants are used exclusively in package-name contexts. All repo-name and platform-identity occurrences use only kebab-case.\n\nWhat remains: All 5 issues pending implementation. Branch pnt-2nw-disambiguate-names needs creation from pnt-kaf-generalized-discovery. Implementation sequence: .1 (rename + Nix attrs) -\u003e .2 (verification) and .3 (template params) in parallel -\u003e .4 (template refs) -\u003e .5 (integration).\n\nDownstream impact: Once complete, template instantiations with divergent repo-name and package-name will work without post-instantiation fixes.\n\u003c!-- /checkpoint-context --\u003e","status":"closed","priority":1,"issue_type":"epic","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:09.771537-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:43:39.00065-05:00","closed_at":"2026-02-18T16:43:39.00065-05:00","close_reason":"All 5 children closed. Template now disambiguates repo-name from package-name via separate omnix params. Verified with convergent and divergent instantiation tests against pushed branch."} {"id":"pnt-2nw.1","title":"Rename primary package to pnt-core and update Nix attributes","description":"Rename primary package from python-nix-template to pnt-core, updating all package-name contexts. Scope expanded to include Nix attribute updates (originally pnt-2nw.2) because leaving Nix attrs pointing at the old directory breaks nix build between issues.\n\nCRITICAL: Selective rename, NOT blanket find-and-replace. Only package-name contexts change. Repo-name contexts must remain as python-nix-template — they become the repo-name placeholder in pnt-2nw.3. Docs prose (\"the python-nix-template project/package/library\" in ~15 .qmd files) is classified as repo-name because there is one docs site per repo.\n\n--- STEP 1: DIRECTORY RENAMES (git mv) ---\n\ngit mv packages/python-nix-template packages/pnt-core\ngit mv packages/pnt-core/src/python_nix_template packages/pnt-core/src/pnt_core\n\n--- STEP 2: FILE CONTENT — RENAME TO pnt-core/pnt_core/pntCore ---\n\nINSIDE packages/pnt-core/:\n- pyproject.toml line 7: name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 13: entry point python-nix-template = \"python_nix_template:main\" -\u003e pnt-core = \"pnt_core:main\"\n- pyproject.toml line 20: packages [\"src/python_nix_template\"] -\u003e [\"src/pnt_core\"]\n- pyproject.toml line 63: editable source python-nix-template -\u003e pnt-core\n- pyproject.toml line 85: pixi name \"python-nix-template\" -\u003e \"pnt-core\"\n- pyproject.toml line 106: --cov=src/python_nix_template/ -\u003e --cov=src/pnt_core/\n- pyproject.toml line 113: test path \"src/python_nix_template/tests\" -\u003e \"src/pnt_core/tests\"\n- pyproject.toml line 118: coverage omit \"src/python_nix_template/tests/*\" -\u003e \"src/pnt_core/tests/*\"\n- package.json line 16: \"name\": \"python-nix-template\" -\u003e \"pnt-core\"\n- src/pnt_core/__init__.py line 12: print string python-nix-template -\u003e pnt-core\n- src/pnt_core/tests/test_main.py line 4: comment python_nix_template -\u003e pnt_core\n- src/pnt_core/tests/test_main.py line 12: assertion \"Hello from python-nix-template!\" -\u003e \"Hello from pnt-core!\"\n- conda/README.md lines 19, 23: conda env name python-nix-template -\u003e pnt-core\n- .ci.json line 3: image names [\"python-nix-template\", \"python-nix-template-dev\"] -\u003e [\"pnt-core\", \"pnt-core-dev\"]\n\nNIX MODULES (absorbed from pnt-2nw.2):\n- modules/packages.nix: pythonNixTemplate312 -\u003e pntCore312, pythonNixTemplate313 -\u003e pntCore313, mkVirtualEnv names \"python-nix-template-3.1x\" -\u003e \"pnt-core-3.1x\", default alias\n- modules/devshell.nix: same pattern — attr names, devshell name strings, default alias\n\nDOCUMENTATION:\n- docs/_quarto.yml line 118: package: python_nix_template -\u003e pnt_core (quartodoc)\n- docs/_quarto.yml line 127: \"API reference for python-nix-template.\" -\u003e \"API reference for pnt-core.\"\n- docs/tutorials/getting-started.qmd line 26: print example -\u003e pnt-core\n- docs/guides/installation.qmd lines 15, 23: pip install python-nix-template -\u003e pnt-core\n- docs/guides/installation.qmd lines 46-47: import python-nix-template -\u003e import pnt_core (fix pre-existing bug: use snake_case for Python import), python-nix-template.__version__ -\u003e pnt_core.__version__\n- docs/notes/architecture/package-distribution-channels.md: line 26 heading, lines 30-31 paths, line 56 default name — all python-nix-template -\u003e pnt-core\n- docs/notes/architecture/crane-uv2nix-integration.md line 413: python-nix-template -\u003e pnt-core in pure Python package list\n\nJUSTFILE:\n- 19 recipe package= defaults (lines 253-408): package=\"python-nix-template\" -\u003e package=\"pnt-core\"\n Recipes: conda-build, conda-env, pixi-lock, conda-lock, conda-test, conda-lint, conda-lint-fix, conda-type, conda-check, test, uv-build, uv-sync, uv-lock, lint, lint-fix, type, check\n- Line 731: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nREADME.md:\n- Recipe examples with package= (lines 265-273, 303-312): python-nix-template -\u003e pnt-core\n- Line 317: test-package-release package-name=\"python-nix-template\" -\u003e package-name=\"pnt-core\"\n\nOTHER:\n- .vscode/launch.json line 5: debug name \"python-nix-template: Debug CLI\" -\u003e \"pnt-core: Debug CLI\"\n- .vscode/launch.json line 8: module \"python_nix_template\" -\u003e \"pnt_core\"\n- packages/pnt-functional/conda/README.md lines 19, 23: env name python-nix-template -\u003e pnt-core\n\n--- STEP 3: WHAT TO LEAVE AS python-nix-template ---\n\nThese repo-name contexts become the repo-name placeholder in pnt-2nw.3:\n- Root package.json: name and repository URL\n- packages/pnt-core/package.json line 85: repository URL\n- packages/pnt-cli/package.json line 85: repository URL\n- packages/pnt-functional/package.json line 85: repository URL\n- modules/containers.nix line 8: repoName\n- modules/template.nix: welcomeText (line 9), om.templates key (line 82), placeholder values (lines 88/93/98 — updated by pnt-2nw.3, not here)\n- wrangler.jsonc: worker name and domain (lines 3, 18)\n- .github/ISSUE_TEMPLATE/config.yml: GitHub discussion URLs\n- .github/workflows/deploy-docs.yaml line 70: worker URLs\n- .github/workflows/template.yaml lines 141, 182: REPO_REF\n- .dvc/config line 5: GCS path\n- scripts/bootstrap.sh: comment (line 2), raw.githubusercontent URL (line 4), banner (line 11)\n- scripts/sops-bootstrap.sh: SSH key comment (line 38), echo (line 175)\n- justfile: repo= defaults (lines 41, 56), SOPS example (line 517), template init ref (line 614), deployment URLs (lines 884, 907, 947)\n- README.md: header (line 1), flake refs (lines 14/43/82/98-101), develop context (line 208), repo= examples (lines 254-255)\n- flake.nix line 2: description prefix\n- docs/_quarto.yml: title (line 42), site-url (line 44), GitHub links (lines 53, 62)\n- docs/index.qmd: title (line 2), heading (line 9), GitHub link (line 26)\n- docs/guides/installation.qmd: clone URL (line 31), cd (line 32), description/prose (lines 3, 8)\n- docs/tutorials/getting-started.qmd: description and prose (lines 3, 6, 8)\n- docs/guides/development.qmd: description and prose (lines 3, 8)\n- All docs prose in ~15 .qmd files: \"the python-nix-template project/package/library\" references\n- docs/about/index.qmd, docs/concepts/index.qmd, docs/development/**/*.qmd: all prose references\n\n--- STEP 4: DUMMY TAG ---\n\ngit tag pnt-core-v0.2.1 $(git rev-parse python-nix-template-v0.2.1)\nPlace on SAME commit as existing tag, NOT on HEAD. For version contiguity.\n\n--- STEP 5: VERIFICATION ---\n\nnix build\nnix flake check\ncd packages/pnt-core \u0026\u0026 pytest\n\nAll must pass before marking complete.\n\n--- BRANCH SETUP ---\n\nWork in .worktrees/pnt-2nw-1-rename-package\ngit worktree add .worktrees/pnt-2nw-1-rename-package -b pnt-2nw-1-rename-package pnt-2nw-disambiguate-names","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:19.514833-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:34:36.630152-05:00","closed_at":"2026-02-18T15:34:36.630152-05:00","close_reason":"Implemented in 504ad46..73078ef. Renamed packages/python-nix-template to packages/pnt-core, updated Nix attrs to pntCore, all verification passed (nix build, nix flake check, pytest 2/2).","dependencies":[{"issue_id":"pnt-2nw.1","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:19.515572-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.2","title":"Verify readDir-based discovery works with renamed pnt-core package","description":"Verification-only pass after pnt-2nw.1. All rename and Nix attribute work is done in .1. This issue confirms that the readDir-based discovery mechanisms work correctly with the renamed package.\n\nVerify:\n1. modules/python.nix readDir discovers packages/pnt-core/ correctly\n2. nix eval .#packages.x86_64-linux shows pntCore312 and pntCore313 attributes\n3. nix eval .#devShells.x86_64-linux shows pntCore312 and pntCore313 devshells\n4. No Nix module references the old python-nix-template package directory name\n5. The discover-packages CI script (if it exists) correctly detects pnt-core\n\nSearch for any remaining hardcoded references to the old name:\n rg 'python.nix.template' modules/ --type nix\n rg 'python_nix_template' modules/ --type nix\n rg 'pythonNixTemplate' modules/ --type nix\n\nThese should return zero results in Nix modules (the string \"python-nix-template\" will still appear in non-package contexts like repoName, om.templates key, etc. — those are correct).","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:27.11666-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:41:26.572349-05:00","closed_at":"2026-02-18T15:41:26.572349-05:00","close_reason":"All 6 verification checks pass: readDir discovery finds pnt-core, Nix attrs are pntCore*, nix flake check passes, no stale package-name refs in modules. Remaining python-nix-template occurrences are repo-name contexts (containers.nix repoName, template.nix placeholders, CI/workflow GitHub URLs).","dependencies":[{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:27.117365-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.2","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.803552-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.3","title":"Add repo-name parameter and update template.nix placeholders","description":"In modules/template.nix: add new string param repo-name with placeholder python-nix-template and description \"Repository name (kebab-case)\". This is a REQUIRED parameter (not optional with default).\n\nChange placeholder values to match the renamed package:\n- package-name-kebab-case placeholder: python-nix-template -\u003e pnt-core\n- package-name-snake-case placeholder: python_nix_template -\u003e pnt_core\n- package-name-camel-case placeholder: pythonNixTemplate -\u003e pntCore\n\nUpdate template tests to include repo-name param in the test params.\n\nAfter this change, omnix template instantiation performs two sets of substitutions:\n1. All occurrences of \"pnt-core\" (and pnt_core, pntCore) -\u003e user's package name\n2. All occurrences of \"python-nix-template\" -\u003e user's repo name\n\nVerify that all repo-name contexts in template files still contain the literal string \"python-nix-template\", confirming they will be substituted with the user's repo name. Key repo-name contexts:\n- Root package.json name and repository URL\n- packages/*/package.json repository URLs\n- modules/containers.nix repoName\n- wrangler.jsonc worker name and domain\n- .github/ issue template URLs, deploy-docs worker URLs, template.yaml REPO_REF\n- .dvc/config GCS path\n- scripts/bootstrap.sh raw.githubusercontent URL and banner\n- scripts/sops-bootstrap.sh SSH key comment\n- justfile repo= defaults, SOPS example, template init ref, deployment URLs\n- README.md header, flake refs, repo= examples, develop context\n- flake.nix description prefix\n- docs/_quarto.yml title, site-url, GitHub links\n- docs/index.qmd title, heading, GitHub link\n- docs/guides/installation.qmd clone URL and cd command\n- All docs prose in ~15 .qmd files (\"the python-nix-template project/package/library\") — classified as repo-name because one docs site per repo\n- docs/tutorials, docs/guides, docs/about, docs/concepts, docs/development prose references","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:35.063916-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:16:47.171656-05:00","closed_at":"2026-02-18T16:16:47.171656-05:00","close_reason":"Implemented in fc71df7..3ef7495. Updated package-name placeholder values to pnt-core/pnt_core/pntCore, added repo-name parameter (default python-nix-template), updated template test params. nix flake check passes, repo-name confirmed in om.templates params.","dependencies":[{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:35.064575-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.3","depends_on_id":"pnt-2nw.1","type":"blocks","created_at":"2026-02-18T14:38:55.948661-05:00","created_by":"Cameron Smith"}]} {"id":"pnt-2nw.4","title":"Handle template reference contexts in justfile and docs","description":"Handle template reference contexts where both git-org (sciexp) and repo-name (python-nix-template) placeholders appear in the same string, causing potential double-substitution issues.\n\nTwo specific cases:\n1. docs/notes/archive/README.md contains multiple \"github:sciexp/python-nix-template\" flake references. Fix by adding docs/notes/archive/ to the nix-template path toggle in template.nix so this directory is excluded from template output by default (it contains template-specific documentation that should not appear in instantiated projects).\n\n2. justfile line 614 init recipe contains \"github:sciexp/python-nix-template\" as an embedded default value. Fix by restructuring the recipe to take template-ref as a required parameter rather than embedding the placeholder-containing string as a default.\n\nNote: After pnt-2nw.3, \"sciexp\" is the git-org placeholder and \"python-nix-template\" is the repo-name placeholder. Strings like \"github:sciexp/python-nix-template\" undergo double substitution (both placeholders replaced), which is correct for these contexts. The issue is specifically about strings where the template should reference ITSELF (the upstream template repo) rather than being substituted.","status":"closed","priority":2,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:42.754058-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:22:02.22518-05:00","closed_at":"2026-02-18T16:22:02.22518-05:00","close_reason":"Implemented in 0eca741..1022d93. Made template-ref a required param in template-init recipe, updated README. Case 1 (docs/notes/archive/) was moot: directory never existed in git history. nix flake check passes.","dependencies":[{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:42.754765-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.4","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.110897-05:00","created_by":"Cameron Smith"}]} -{"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"open","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T15:17:23.223935-05:00","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-05:00","created_by":"Cameron Smith"}]} +{"id":"pnt-2nw.5","title":"Integration verification and instantiation test documentation","description":"Integration verification after all rename and template parameter changes. Verify:\n\n1. nix build, nix flake check, and pytest pass after all changes\n2. Template instantiation works for convergent case (repo-name == package-name):\n Test with omnix init using identical repo-name and package-name values\n3. Template instantiation works for divergent case (repo-name != package-name):\n Test with e.g. repo-name=data, package-name=omicsio — this is the case that motivated the entire epic\n4. In both cases, verify no \"python-nix-template\" or \"pnt-core\" literal strings remain in the instantiated output (all should be substituted)\n5. Verify fix-template-names utility in template-rename.nix still works, or update if needed\n6. Document the verification commands and results\n\nCross-reference with sciexp/data fix commits (git -C ~/projects/sciexp/data log --oneline --reverse init --not main) to confirm the same contexts that required manual fixing would now be handled automatically by the two-placeholder system.","status":"closed","priority":1,"issue_type":"task","owner":"cameron.ray.smith@gmail.com","created_at":"2026-02-18T14:38:49.792574-05:00","created_by":"Cameron Smith","updated_at":"2026-02-18T16:43:38.893385-05:00","closed_at":"2026-02-18T16:43:38.893385-05:00","close_reason":"All verification passes. Convergent (repo==pkg) and divergent (repo!=pkg) instantiation both work correctly via omnix. 12/15 sciexp/data manual fixes now automatic. README examples updated with repo-name and package-name-camel-case params. fix-template-names utility still functional.","dependencies":[{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw","type":"parent-child","created_at":"2026-02-18T14:38:49.793345-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.2","type":"blocks","created_at":"2026-02-18T14:38:56.289628-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.3","type":"blocks","created_at":"2026-02-18T14:38:56.464683-05:00","created_by":"Cameron Smith"},{"issue_id":"pnt-2nw.5","depends_on_id":"pnt-2nw.4","type":"blocks","created_at":"2026-02-18T14:38:56.621874-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"}]} From ee519d3f227bd720fa6dbb5b6436a0f12e420bc3 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:49:38 -0500 Subject: [PATCH 37/39] fix(lock): regenerate uv.lock after package rename to pnt-core --- packages/pnt-core/uv.lock | 138 +++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/packages/pnt-core/uv.lock b/packages/pnt-core/uv.lock index d5b9c5e1..c1b53a0c 100644 --- a/packages/pnt-core/uv.lock +++ b/packages/pnt-core/uv.lock @@ -1196,6 +1196,75 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/88/71fa06eb487ed9d4fab0ad173300b7a58706385f98fb66b1ccdc3ec3d4dd/plum_dispatch-2.6.1-py3-none-any.whl", hash = "sha256:49cd83027498e35eac32c7a93ecd6a99970d72d90f4141cc93be760c7ba831c4", size = 41456, upload-time = "2025-12-18T11:56:53.599Z" }, ] +[[package]] +name = "pnt-core" +version = "0.2.1" +source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "hypothesis" }, + { name = "ipython" }, + { name = "jupyter" }, + { name = "jupyter-cache" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "quartodoc" }, + { name = "ruff" }, + { name = "xdoctest" }, +] +docs = [ + { name = "jupyter" }, + { name = "jupyter-cache" }, + { name = "quartodoc" }, +] +interactive = [ + { name = "ipython" }, +] +lint = [ + { name = "ruff" }, +] +test = [ + { name = "hypothesis" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "xdoctest" }, +] +types = [ + { name = "pyright" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "hypothesis", specifier = ">=6.125.1" }, + { name = "ipython", specifier = ">=8.32.0" }, + { name = "jupyter", specifier = ">=1.1.1" }, + { name = "jupyter-cache", specifier = ">=1.0.1" }, + { name = "pyright", specifier = ">=1.1.395" }, + { name = "pytest", specifier = ">=8.3.4" }, + { name = "pytest-cov", specifier = ">=6.0.0" }, + { name = "quartodoc", specifier = ">=0.9.1" }, + { name = "ruff", specifier = ">=0.9.4" }, + { name = "xdoctest", specifier = ">=1.2.0" }, +] +docs = [ + { name = "jupyter", specifier = ">=1.1.1" }, + { name = "jupyter-cache", specifier = ">=1.0.1" }, + { name = "quartodoc", specifier = ">=0.9.1" }, +] +interactive = [{ name = "ipython", specifier = ">=8.32.0" }] +lint = [{ name = "ruff", specifier = ">=0.9.4" }] +test = [ + { name = "hypothesis", specifier = ">=6.125.1" }, + { name = "pytest", specifier = ">=8.3.4" }, + { name = "pytest-cov", specifier = ">=6.0.0" }, + { name = "xdoctest", specifier = ">=1.2.0" }, +] +types = [{ name = "pyright", specifier = ">=1.1.395" }] + [[package]] name = "prometheus-client" version = "0.24.1" @@ -1397,75 +1466,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl", hash = "sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2", size = 15548, upload-time = "2025-10-06T04:15:17.553Z" }, ] -[[package]] -name = "python-nix-template" -version = "0.2.1" -source = { editable = "." } - -[package.dev-dependencies] -dev = [ - { name = "hypothesis" }, - { name = "ipython" }, - { name = "jupyter" }, - { name = "jupyter-cache" }, - { name = "pyright" }, - { name = "pytest" }, - { name = "pytest-cov" }, - { name = "quartodoc" }, - { name = "ruff" }, - { name = "xdoctest" }, -] -docs = [ - { name = "jupyter" }, - { name = "jupyter-cache" }, - { name = "quartodoc" }, -] -interactive = [ - { name = "ipython" }, -] -lint = [ - { name = "ruff" }, -] -test = [ - { name = "hypothesis" }, - { name = "pytest" }, - { name = "pytest-cov" }, - { name = "xdoctest" }, -] -types = [ - { name = "pyright" }, -] - -[package.metadata] - -[package.metadata.requires-dev] -dev = [ - { name = "hypothesis", specifier = ">=6.125.1" }, - { name = "ipython", specifier = ">=8.32.0" }, - { name = "jupyter", specifier = ">=1.1.1" }, - { name = "jupyter-cache", specifier = ">=1.0.1" }, - { name = "pyright", specifier = ">=1.1.395" }, - { name = "pytest", specifier = ">=8.3.4" }, - { name = "pytest-cov", specifier = ">=6.0.0" }, - { name = "quartodoc", specifier = ">=0.9.1" }, - { name = "ruff", specifier = ">=0.9.4" }, - { name = "xdoctest", specifier = ">=1.2.0" }, -] -docs = [ - { name = "jupyter", specifier = ">=1.1.1" }, - { name = "jupyter-cache", specifier = ">=1.0.1" }, - { name = "quartodoc", specifier = ">=0.9.1" }, -] -interactive = [{ name = "ipython", specifier = ">=8.32.0" }] -lint = [{ name = "ruff", specifier = ">=0.9.4" }] -test = [ - { name = "hypothesis", specifier = ">=6.125.1" }, - { name = "pytest", specifier = ">=8.3.4" }, - { name = "pytest-cov", specifier = ">=6.0.0" }, - { name = "xdoctest", specifier = ">=1.2.0" }, -] -types = [{ name = "pyright", specifier = ">=1.1.395" }] - [[package]] name = "pytokens" version = "0.4.1" From 1f07281ae354793b21fa2070fc546a82ad44f756 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 17:11:15 -0500 Subject: [PATCH 38/39] fix(ci): add repo-name parameter to template workflow instantiation tests --- .github/workflows/template.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/template.yaml b/.github/workflows/template.yaml index 3ccf7da7..93be3a09 100644 --- a/.github/workflows/template.yaml +++ b/.github/workflows/template.yaml @@ -148,6 +148,7 @@ jobs: "package-name-kebab-case": "pnt-mono", "package-name-snake-case": "pnt_mono", "package-name-camel-case": "pntMono", + "repo-name": "pnt-mono", "monorepo-package": true, "git-org": "pnt-mono", "author": "Pnt Mono", @@ -189,6 +190,7 @@ jobs: "package-name-kebab-case": "pnt-new", "package-name-snake-case": "pnt_new", "package-name-camel-case": "pntNew", + "repo-name": "pnt-new", "monorepo-package": false, "git-org": "pnt-new", "author": "Pnt New", From 4056a249834cdec51c43e10179fb6f480a2c4137 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Wed, 18 Feb 2026 16:55:34 -0500 Subject: [PATCH 39/39] chore(pnt-core): 0.2.1 -> 0.2.2 Signed-off-by: Cameron Smith --- packages/pnt-core/pyproject.toml | 4 ++-- packages/pnt-core/uv.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pnt-core/pyproject.toml b/packages/pnt-core/pyproject.toml index 316f00bf..78452124 100644 --- a/packages/pnt-core/pyproject.toml +++ b/packages/pnt-core/pyproject.toml @@ -7,7 +7,7 @@ description = "Add your description here" name = "pnt-core" readme = "README.md" requires-python = ">=3.12,<3.14" -version = "0.2.1" +version = "0.2.2" [project.scripts] pnt-core = "pnt_core:main" @@ -83,7 +83,7 @@ types = "pyright src/" [tool.pixi.package] name = "pnt-core" -version = "0.2.1" +version = "0.2.2" [tool.pixi.package.run-dependencies] diff --git a/packages/pnt-core/uv.lock b/packages/pnt-core/uv.lock index c1b53a0c..e4a3a8d2 100644 --- a/packages/pnt-core/uv.lock +++ b/packages/pnt-core/uv.lock @@ -1198,7 +1198,7 @@ wheels = [ [[package]] name = "pnt-core" -version = "0.2.1" +version = "0.2.2" source = { editable = "." } [package.dev-dependencies]