Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcd6fa6be3 | ||
|
|
f4a9e638a5 | ||
|
|
4fd26b1662 | ||
|
|
665703fbe6 | ||
|
|
ad6dac634e | ||
|
|
9b7a9fa9b9 | ||
|
|
33278d9ed2 | ||
|
|
40aef99289 | ||
|
|
b191d8883c | ||
|
|
1df7bec2d7 |
+27
-15
@@ -1,15 +1,21 @@
|
|||||||
# Flake CI: full `nix flake check` (formatting + deadnix + statix + pre-commit)
|
# Flake CI. Formatting (treefmt) runs on *every* PR; the heavier Nix work
|
||||||
# plus an explicit per-host evaluation pass for granular output.
|
# (deadnix/statix/pre-commit lints + per-host evaluation) runs only when the
|
||||||
|
# change can affect it.
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
# Deliberately no `paths:` filter. This job is a required status check on main,
|
# Deliberately no `paths:` filter. This job is a required status check on main,
|
||||||
# and a path-filtered workflow is *skipped* (never runs) for PRs that touch no
|
# and a path-filtered workflow is *skipped* (never runs) for PRs that touch no
|
||||||
# matching file -- which leaves the required check pending forever and blocks the
|
# matching file -- which leaves the required check pending forever and blocks the
|
||||||
# merge (e.g. a .renovaterc.json-only change). So the workflow always runs and
|
# merge (e.g. a .renovaterc.json-only change). So the workflow always runs and
|
||||||
# always reports. To avoid burning a full Nix evaluation on changes that can't
|
# always reports.
|
||||||
# affect it, the "detect" step below diffs the PR and the heavy steps run only
|
#
|
||||||
# when a .nix file, flake.lock, or this workflow changed; otherwise they skip and
|
# Two tiers of checks:
|
||||||
# the job still passes. The required check is therefore always green-reportable.
|
# * Formatting always runs. treefmt covers Markdown, YAML, and JSON as well as
|
||||||
|
# Nix and shell, so a docs- or config-only PR must be format-checked too. It
|
||||||
|
# is cheap (no host evaluation).
|
||||||
|
# * The heavy steps (full `nix flake check` + host evals) run only when a .nix
|
||||||
|
# file, flake.lock, or this workflow changed; otherwise they skip and the job
|
||||||
|
# still passes, keeping the required check green-reportable.
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
@@ -25,11 +31,10 @@ jobs:
|
|||||||
# Full history so the detect step can diff the PR against its base.
|
# Full history so the detect step can diff the PR against its base.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# Decide whether the Nix steps need to run. On a pull_request, diff the PR
|
# Decide whether the *heavy* Nix steps need to run. On a pull_request, diff
|
||||||
# against its base and look for files that can affect the flake: any .nix,
|
# against the base for files that can affect them: any .nix, the lockfile,
|
||||||
# the lockfile, or this workflow. On any other event (push to main) always
|
# or this workflow. On any other event (push to main) always run. The
|
||||||
# run. The job itself always succeeds, so the required status check is
|
# formatting step below is unaffected -- it always runs.
|
||||||
# reported even when the heavy steps are skipped.
|
|
||||||
- name: Detect Nix-relevant changes
|
- name: Detect Nix-relevant changes
|
||||||
id: detect
|
id: detect
|
||||||
run: |
|
run: |
|
||||||
@@ -45,16 +50,16 @@ jobs:
|
|||||||
echo "Changed files:"
|
echo "Changed files:"
|
||||||
echo "$changed"
|
echo "$changed"
|
||||||
if echo "$changed" | grep -Eq '(\.nix$|^flake\.lock$|^\.gitea/workflows/ci\.yaml$)'; then
|
if echo "$changed" | grep -Eq '(\.nix$|^flake\.lock$|^\.gitea/workflows/ci\.yaml$)'; then
|
||||||
echo "Nix-relevant changes found: running checks."
|
echo "Nix-relevant changes found: running heavy checks."
|
||||||
echo "run=true" >> "$GITHUB_OUTPUT"
|
echo "run=true" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "No Nix-relevant changes: skipping checks (job still passes)."
|
echo "No Nix-relevant changes: heavy checks skip (formatting still runs)."
|
||||||
echo "run=false" >> "$GITHUB_OUTPUT"
|
echo "run=false" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Nix drives the formatting check, so install it unconditionally.
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
if: steps.detect.outputs.run == 'true'
|
uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31
|
||||||
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31
|
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
@@ -62,6 +67,13 @@ jobs:
|
|||||||
substituters = https://cache.nixos.org https://nix-community.cachix.org
|
substituters = https://cache.nixos.org https://nix-community.cachix.org
|
||||||
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
|
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
|
||||||
|
|
||||||
|
# Always run: treefmt formats Markdown/YAML/JSON (docs + config) as well as
|
||||||
|
# Nix and shell, so documentation-only PRs are format-checked too. This is
|
||||||
|
# the cheap gate (no host evaluation) and pre-builds the `formatting`
|
||||||
|
# derivation that the flake check below reuses from cache.
|
||||||
|
- name: Formatting check
|
||||||
|
run: nix build --print-build-logs '.#checks.x86_64-linux.formatting'
|
||||||
|
|
||||||
# Runs every flake check: treefmt formatting, deadnix, statix, and the
|
# Runs every flake check: treefmt formatting, deadnix, statix, and the
|
||||||
# pre-commit hooks (so a --no-verify commit can't ship unlinted).
|
# pre-commit hooks (so a --no-verify commit can't ship unlinted).
|
||||||
- name: Flake check
|
- name: Flake check
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Working on this flake
|
||||||
|
|
||||||
|
Project notes for changes to this repository. Persona and memory rules live in
|
||||||
|
the user-global config; this file is about the flake's checks and conventions.
|
||||||
|
|
||||||
|
## Before you commit: run the formatter
|
||||||
|
|
||||||
|
Formatting and linting are driven by the flake. CI (`.gitea/workflows/ci.yaml`)
|
||||||
|
runs `nix flake check`, which fails the build if any file is unformatted or trips
|
||||||
|
a lint. From the repo root:
|
||||||
|
|
||||||
|
- `nix fmt` — format the whole tree (writes changes).
|
||||||
|
- `nix flake check` — run every check read-only (what CI runs).
|
||||||
|
- `nix develop` — dev shell; its `shellHook` installs the git pre-commit hooks so
|
||||||
|
the same gates run on `git commit`.
|
||||||
|
|
||||||
|
Never commit with `--no-verify`. A bypassed commit ships unformatted content and
|
||||||
|
turns CI red on the next push to `main` (see "Docs are checked too").
|
||||||
|
|
||||||
|
## What gets checked
|
||||||
|
|
||||||
|
Defined in `flake.nix` (the `treefmt`, `pre-commit`, and `checks` blocks) and
|
||||||
|
`statix.toml`:
|
||||||
|
|
||||||
|
| Check | Tool | Covers |
|
||||||
|
| ------------ | --------------------------------- | ------------------------------------------------------- |
|
||||||
|
| `formatting` | treefmt → `nixfmt` | all `*.nix` |
|
||||||
|
| `formatting` | treefmt → `shfmt` | shell scripts |
|
||||||
|
| `formatting` | treefmt → `prettier` | **Markdown, YAML, JSON** (incl. `README.md`, this file) |
|
||||||
|
| `deadnix` | deadnix | dead Nix bindings (`--no-lambda-pattern-names`) |
|
||||||
|
| `statix` | statix | Nix antipatterns (config in `statix.toml`) |
|
||||||
|
| pre-commit | nixfmt-rfc-style, deadnix, statix | the same gates, run on commit |
|
||||||
|
|
||||||
|
Excluded from formatting: `*/hardware-configuration.nix` (generated by
|
||||||
|
`nixos-generate-config`) and `flake.lock`. Editor defaults (indent, EOL, final
|
||||||
|
newline) are in `.editorconfig`; note Markdown keeps trailing whitespace, which
|
||||||
|
encodes hard line breaks.
|
||||||
|
|
||||||
|
## Docs are checked too
|
||||||
|
|
||||||
|
prettier formats `*.md`, so **documentation edits must be run through `nix fmt`**
|
||||||
|
exactly like code. prettier re-aligns Markdown tables in particular; hand-editing
|
||||||
|
a table almost always leaves it non-conformant and fails the `formatting` check.
|
||||||
|
|
||||||
|
The CI `formatting` step runs on **every** PR — including docs- and config-only
|
||||||
|
changes — so a Markdown/YAML/JSON edit is format-checked before merge, not just
|
||||||
|
after it lands on `main`. (The heavier `deadnix`/`statix`/`pre-commit` lints and
|
||||||
|
the per-host evaluation still run only when a `.nix` file, `flake.lock`, or the
|
||||||
|
workflow changed; see `.gitea/workflows/ci.yaml`.) Run `nix fmt` before you
|
||||||
|
commit and the formatting check stays green.
|
||||||
|
|
||||||
|
## Host evaluation
|
||||||
|
|
||||||
|
CI also evaluates every `nixosConfigurations` / `darwinConfigurations` host's
|
||||||
|
toplevel (eval only, no build) on an x86_64 runner, so eval errors fail cheaply.
|
||||||
|
Reproduce locally:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix eval --raw ".#nixosConfigurations.<host>.config.system.build.toplevel.drvPath"
|
||||||
|
```
|
||||||
|
|
||||||
|
Host lists are discovered from the flake, so adding or removing a host needs no
|
||||||
|
change to the workflow.
|
||||||
Generated
+33
-55
@@ -25,11 +25,11 @@
|
|||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "pkgs/firefox-addons",
|
"dir": "pkgs/firefox-addons",
|
||||||
"lastModified": 1782014564,
|
"lastModified": 1783656166,
|
||||||
"narHash": "sha256-F/royQHyJAyKWKrV8AaG4Yf1yjzxa+PFk5xvTdvBrzk=",
|
"narHash": "sha256-6WP/DOGL2X6DdZl+vhxt/R7Ahn31z0cwo3JJ0cYFC2M=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "nur-expressions",
|
"repo": "nur-expressions",
|
||||||
"rev": "d6668e34bbce788459883a1097bf0ee170f49c61",
|
"rev": "dd7e87fef8e4b30bfbf59418c48ddd3ab4ddb42e",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -93,11 +93,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1778716662,
|
"lastModified": 1782949081,
|
||||||
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
|
"narHash": "sha256-vp6Y/Grm98ESt6ceOkWiHWyZRDV3J1RID4w+6NWK9yA=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
|
"rev": "17c9d6cdfc60c64f4ee8d306f9bc0b4ccb51481e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -130,17 +130,16 @@
|
|||||||
"git-hooks": {
|
"git-hooks": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"gitignore": "gitignore",
|
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781733627,
|
"lastModified": 1783008725,
|
||||||
"narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=",
|
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39",
|
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -149,27 +148,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gitignore": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"git-hooks",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709087332,
|
|
||||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -177,11 +155,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781981105,
|
"lastModified": 1783221248,
|
||||||
"narHash": "sha256-/1nNBbA7PrSQpTc9Qazkhl4kIPg+TNl0CjxS3UQJKlw=",
|
"narHash": "sha256-ESQnuNHEDChsB4IxoLRhscVahqkDWkTb+qdIz8euYt4=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "7bfff44b465909f69a442701293bc0badcf476dc",
|
"rev": "af2beae5f0fae0a4310cc0e6aef2572f56090353",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -253,11 +231,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1782030356,
|
"lastModified": 1783414108,
|
||||||
"narHash": "sha256-h4WpMr455AfRub0FXBaon6Vcpe0waUyJ4GivIW6oyd4=",
|
"narHash": "sha256-RY8e+gR2/DhXsYDxGDL6Hhe9+POD9u4+llwxMBqMQDs=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "3017088b49efd404f78e3b104f553b97e4af786b",
|
"rev": "96d6de10eb281b98f5cfcd1841394c03da5df77c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -274,11 +252,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781520503,
|
"lastModified": 1783669315,
|
||||||
"narHash": "sha256-XuqQQG1qRyc3o8ld937sDLQNx+QrGV852KJ0dNglJDg=",
|
"narHash": "sha256-DjIkyK48jWUxYCCoTDS9L5PgGg6/RFRSRXW2dSFpJg8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixos-apple-silicon",
|
"repo": "nixos-apple-silicon",
|
||||||
"rev": "43043ad207529650f9fa68e1705f7cf9c08bfdeb",
|
"rev": "9e46a0edd8a6d96538d146a4bb4477e7fae8b1a0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -294,11 +272,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781622756,
|
"lastModified": 1783673680,
|
||||||
"narHash": "sha256-JrPh4M6S7aPsEE9tOENuZrxC6o2szSLlK+t4+nLke9s=",
|
"narHash": "sha256-ardRVG+ipnyyxVdIsbLMy5foO6gDqN/yIi8v10HTJqs=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "08018c72174a4df5657f8d94178ac69fb9c243e5",
|
"rev": "0b655af52b5b89bcceb88737efdc3a7498e751ee",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -315,11 +293,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781182279,
|
"lastModified": 1783336371,
|
||||||
"narHash": "sha256-V5EQQbDnmdiXGQXrEF1PEL7QYsFqfH8N1E89Z5ONwFk=",
|
"narHash": "sha256-ZisTtweyb7JUwPP54HAXE9TypT8m89dIxDI36Ak0hAs=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NixOS-WSL",
|
"repo": "NixOS-WSL",
|
||||||
"rev": "5675822ba756e6e56f8f6a5a76e90e0da2ece94d",
|
"rev": "a9620cfa43f0c1c30a46c31ae3c6e58cdb124a14",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -330,11 +308,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781216227,
|
"lastModified": 1783389287,
|
||||||
"narHash": "sha256-9mUW6gNwoN2SWc/l0fW4svPNOulXLl8ijqKyeSOGgJE=",
|
"narHash": "sha256-0xIy4dVLqq47rA+mRy0hXDfjhQd4E5PoIns/RmB7nR4=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a0374025a863d007d98e3297f6aa46cc3141c2f0",
|
"rev": "0ad6f47ea4fe188f4bc8f0380f93ae8523337c6c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -346,11 +324,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781577229,
|
"lastModified": 1783522502,
|
||||||
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
|
"narHash": "sha256-iffAls3iaNTyJC2faYcUXSI+Gp02cDjYl+MygxKl2GI=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
"rev": "0bb7ec54c8483066ec9d7720e780a5caa71f8612",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -369,11 +347,11 @@
|
|||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781971008,
|
"lastModified": 1782919967,
|
||||||
"narHash": "sha256-T2u2RQZWKvD1J+TgcxjiJr8IymBr/PrUNeAGhMZFZU4=",
|
"narHash": "sha256-pRwjfB5HQJ3m8J8bOR43pPHtHI7VUJSqwLA3P06cOY0=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "7afca458f064f166d3a9c98db3b41a984fe46492",
|
"rev": "667c8471f4a0fb24d702d1a61af8609f1a5f1ba6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
- [Git commit signing](git_commit_signing.md) — signs in-sandbox via ssh-agent (allowAllUnixSockets + inlined pubkey)
|
- [Git commit signing](git_commit_signing.md) — signs in-sandbox via ssh-agent (allowAllUnixSockets + inlined pubkey)
|
||||||
- [Git check state first](git_check_state.md) — always check branch/status/divergence before git work; Lyra edits repos between sessions
|
- [Git check state first](git_check_state.md) — always check branch/status/divergence before git work; Lyra edits repos between sessions
|
||||||
- [Keep docs updated](docs_keep_updated.md) — update docs in the same pass as code/config changes; stale docs are a defect
|
- [Keep docs updated](docs_keep_updated.md) — update docs in the same pass as code/config changes; stale docs are a defect
|
||||||
|
- [SIBO Workabout MX project](sibo_workabout_mx_scanner.md) — RE + barcode-inventory project state; scanner is an OO DYL object (oscanner), blocked on on-device ordinal capture; resume via code/inventory/CONTINUATION.md
|
||||||
- [Jira tooling](jira_tooling.md) — comments are Markdown not wiki; transitions may need assignee; link direction; WSP transition IDs
|
- [Jira tooling](jira_tooling.md) — comments are Markdown not wiki; transitions may need assignee; link direction; WSP transition IDs
|
||||||
- [Review and comments workflow](workflow_review_and_comments.md) — show PR body and non-trivial Jira comments before posting; terse IaC code comments; PR body content rules
|
- [Review and comments workflow](workflow_review_and_comments.md) — show PR body and non-trivial Jira comments before posting; terse IaC code comments; PR body content rules
|
||||||
- [Sandbox prompts](feedback_sandbox_prompts.md) — don't prompt for sandbox-disable or routine read-only shell ops; broaden permissions instead
|
- [Sandbox prompts](feedback_sandbox_prompts.md) — don't prompt for sandbox-disable or routine read-only shell ops; broaden permissions instead
|
||||||
- [Dev clusters disposable](dev_clusters_disposable.md) — Lyra's dev clusters are recreatable; mutate/break freely, no confirmation needed
|
- [Dev clusters disposable](dev_clusters_disposable.md) — Lyra's dev clusters are recreatable; mutate/break freely, no confirmation needed
|
||||||
|
- [Nix shell tooling](nix_shell_tooling.md) — any nixpkgs tool runs ad hoc via `nix run`/`nix shell nixpkgs#<pkg>`; a missing command is never a dead end
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: nix-shell-tooling
|
||||||
|
description: "Any nixpkgs tool can be run ad hoc via nix run / nix shell — a missing command is never a dead end during development"
|
||||||
|
metadata:
|
||||||
|
node_type: memory
|
||||||
|
type: feedback
|
||||||
|
originSessionId: dfb56b58-518b-4daf-b531-7119bb4a9534
|
||||||
|
---
|
||||||
|
|
||||||
|
Any tool in nixpkgs can be run without installing it into the environment. If a
|
||||||
|
command is missing during development, pull it from nixpkgs on the fly instead
|
||||||
|
of working around its absence or reporting the tool as unavailable.
|
||||||
|
|
||||||
|
**Why:** Lyra runs NixOS; the ambient PATH is deliberately minimal, but the full
|
||||||
|
nixpkgs set is always one command away. "command not found" is not a blocker.
|
||||||
|
|
||||||
|
**How to apply:**
|
||||||
|
|
||||||
|
- One-off run: `nix run nixpkgs#<pkg> -- <args>` (e.g. `nix run nixpkgs#jq -- .`).
|
||||||
|
- Tools on PATH for a session: `nix shell nixpkgs#<pkg> [nixpkgs#<pkg2> ...]`,
|
||||||
|
then run commands normally.
|
||||||
|
- Legacy form also works: `nix-shell -p <pkg> --run '<cmd>'`.
|
||||||
|
- Prefer this over hand-rolling a substitute for a tool that exists in nixpkgs.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: sibo-workabout-mx-scanner
|
||||||
|
description: State of the Psion Workabout MX reverse-engineering / barcode-inventory project and how to resume it
|
||||||
|
metadata:
|
||||||
|
node_type: memory
|
||||||
|
type: project
|
||||||
|
originSessionId: 74de014e-9cf4-47f6-92f4-c34197ac1858
|
||||||
|
---
|
||||||
|
|
||||||
|
Long-running project (July 2026) reverse-engineering the **Psion Workabout MX** (SIBO OS, NEC V30MX, TopSpeed C) to build a barcode **inventory demo** (scan UPC → DBF database file; add stock, consume by a quantity unit) and, alongside, **complete device programming documentation**. Repo: Gitea **lyrathorpe/sibo-playground**, working branch **`feat/inventory-phase1-scan`** (unmerged). Gitea needs hand-off / the contents API for pushes — see [[git-network-ops]]; [[git-conventions]] for branch/PR rules.
|
||||||
|
|
||||||
|
**Committed on the branch (durable, survive reboot):**
|
||||||
|
|
||||||
|
- `docs/reference/00-08` + index — the SIBO/MX programming reference (building apps, system/OS, I/O devices, PLIB core, file system & DBF, UI, hardware, and RE'd boot/OS-call internals).
|
||||||
|
- `code/inventory/` — app scaffold: `upc.c/.h` (UPC-A check-digit validation, correct), `bcode.c/.h`, `scan.c` (Phase-1 diagnostics), `README.md`, **`SCANNER-API.md`** (all scanner findings), **`CONTINUATION.md`** (the on-device debugging procedure to finish).
|
||||||
|
- `docs/mx-re/toolchain-and-plan.md` — the RE toolchain.
|
||||||
|
- The **ROM `w2mx_v7.20f_eng.bin`** and the full **SDK + HDK** (manuals as `docs/*.txt`; headers/libs/`bar*.ldd` under `code/SIBOSDK/`; HDK under `code/HDK/`) are on the branch. `/tmp/claude/sibo/` working files (ROM slices, MAME rom dir, Ghidra/decomp output) are transient and reproducible from the toolchain doc.
|
||||||
|
|
||||||
|
**Scanner — key result:** the integral laser is driven as an **OO library object** in `SCANNER.DYL` (category token **`oscanner`**) via `p_getlibh` → `p_newsend`/`f_newsend` → `p_send`, over **LIBMANAGER (INT 0x84)** / **MESSMANAGER (INT 0x83)** — NOT raw device I/O. Confirmed on the physical device: `p_open("WL2:D")` + control ops **6** then **7** (`p_iow(chan,6); p_iow(chan,7)`) fire the laser to a good decode (green LED). Default Symbol2 11-byte param block: `04 3f 01 15 06 04 1e 80 0d 0a 06` (decoded output is CR/LF-terminated). Dead ends (do not retry): raw `TTY:D` reads, and the wand `BAR:` / `bar*.ldd` decoders (probe expansion slots → `-41`).
|
||||||
|
|
||||||
|
**Blocked on / next step:** the OO **message ordinals + parameter structs** for init / set-params / trigger / read. OLIB assigns ordinals dynamically across the class hierarchy (base classes in `olib`/`hwim`), so they resolve only at runtime — capture them with the **SIBO Debugger on the physical device** (remote debug over serial; it supports breakpoints inside DYLs). MAME cannot inject a barcode, so the last mile must be on hardware. Full step-by-step is in `code/inventory/CONTINUATION.md`.
|
||||||
|
|
||||||
|
**RE toolchain (reproducible):** the ROM is MAME machine **`psionwamx`**; run its debugger headless via `xvfb-run -a mame psionwamx -rompath roms -debug -debugscript CMDS -sound none -seconds_to_run N` (MAME lua input injection into the keyboard matrix does NOT work headless — a known limitation). Static: **radare2** (16-bit x86). Decompile: **Ghidra headless** (processor `x86:LE:16:Real Mode`, a Java GhidraScript — Ghidra 12 has no bundled Python). Get MAME/radare2/Ghidra via `nix-shell -p ...`. Details in `docs/mx-re/toolchain-and-plan.md`.
|
||||||
|
|
||||||
|
**Fallback to deliver value now:** Phase 2 (the DBF inventory: add stock, consume by quantity) can be built with keyboard UPC entry against `docs/reference/05-filesystem-dbf.md`, dropping the scanner in behind the same interface once retrieval is finished. [[docs-keep-updated]]
|
||||||
Reference in New Issue
Block a user