Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
583ca751da | ||
|
|
665703fbe6 | ||
|
|
ad6dac634e | ||
|
|
9b7a9fa9b9 | ||
|
|
33278d9ed2 | ||
|
|
40aef99289 | ||
|
|
b191d8883c | ||
|
|
1df7bec2d7 |
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- name: Install Nix
|
||||
if: steps.detect.outputs.run == 'true'
|
||||
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31
|
||||
uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
|
||||
@@ -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 — the common trap
|
||||
|
||||
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.
|
||||
|
||||
Beware a false green: the CI `detect` step skips the heavy checks on a pull
|
||||
request that touches **no** `.nix`, `flake.lock`, or the workflow file — so a
|
||||
docs-only PR reports success without ever running prettier. The failure then
|
||||
surfaces on the push-to-`main` run (which always runs the full check) or on the
|
||||
next unrelated PR that does touch Nix. Run `nix flake check` locally before
|
||||
merging a docs change, regardless of what the PR check shows.
|
||||
|
||||
## 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.
|
||||
@@ -1,11 +1,13 @@
|
||||
- [User name](user_name.md) — address the user as Lyra
|
||||
- [Soviet engineer persona](persona_soviet_engineer.md) — terse, dry, pragmatic; no emojis; technical accuracy over voice
|
||||
- [Git conventions](git_conventions.md) — never commit to main, always a branch; Conventional Commits branches and messages; inspect repo style first; commit at logical checkpoints
|
||||
- [Git network ops](git_network_ops.md) — GitHub pushable in-sandbox (agent key; just sandbox off); Gitea code.emmathe.dev needs hand-off
|
||||
- [Git network ops](git_network_ops.md) — GitHub and Gitea (code.emmathe.dev) both pushable in-sandbox (sandbox off, agent key); raise Gitea PRs via tea CLI
|
||||
- [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
|
||||
- [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
|
||||
- [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
|
||||
- [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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: git-network-ops
|
||||
description: Push/pull is remote-specific — GitHub is agent-pushable in-sandbox; Gitea (code.emmathe.dev) needs hand-off to Lyra.
|
||||
description: Push/pull is remote-specific — both GitHub and Gitea (code.emmathe.dev) are agent-pushable in-sandbox (sandbox off); raise Gitea PRs with the tea CLI.
|
||||
metadata:
|
||||
node_type: memory
|
||||
type: feedback
|
||||
@@ -11,8 +11,8 @@ Whether a network op can run depends on which key the remote needs:
|
||||
|
||||
**GitHub remotes (e.g. csg-citrix-storefront/\*): pushable in-sandbox by the agent.** ssh-agent holds the decrypted `~/.ssh/id_ed25519` (`emma.thorpe@cloud.com`), which is authorized on GitHub. Only requirement now is `dangerouslyDisableSandbox: true` (network); plain `git push`/`ls-remote` works. Probe non-mutatively with `git ls-remote` first. (Historically also needed `ssh -F /dev/null` to dodge a broken NixOS-WSL system ssh_config include — that's fixed in nixfiles via `programs.ssh.systemd-ssh-proxy.enable = false`, merged and rebuilt 2026-06, so the workaround is no longer needed.)
|
||||
|
||||
**Gitea (`code.emmathe.dev`, e.g. nixfiles): hand off to Lyra.** Needs `~/.ssh/code.emmathe.dev`, which is passphrase-protected and NOT in the agent, so `git push`/`pull`/`fetch` there will fail/hang. Pause, give Lyra the exact command (she runs `ssh-add ~/.ssh/code.emmathe.dev` once, then pushes).
|
||||
**Gitea (`code.emmathe.dev`, e.g. nixfiles): pushable in-sandbox by the agent (as of 2026-07-14).** The ssh-agent now holds the `code.emmathe.dev` key (`git@code.emmathe.dev`), so `git push` works with `dangerouslyDisableSandbox: true` — it needs the agent socket plus `~/.ssh/known_hosts`, both reachable with sandbox off. Probe with `git ls-remote` first. Raise PRs with the `tea` CLI, which is installed and logged in to `code.emmathe.dev` (user `lyrathorpe`): `tea pr create --login code.emmathe.dev --repo lyrathorpe/nixfiles --base main --head <branch> --title "..." --description "..."`. Only fall back to hand-off if `ssh-add -l` (sandbox off) does NOT list the `code.emmathe.dev` key — then it dropped from the agent and Lyra must re-add it (`ssh-add ~/.ssh/code.emmathe.dev`, passphrase-protected).
|
||||
|
||||
**Fine to run locally:** `git branch`, `git rebase`, `git reset`, `git status`, `git log`, `git diff`. `git commit` works in-sandbox via ssh-agent signing — see [[git-commit-signing]].
|
||||
|
||||
**How to apply:** Check the remote host before a network op. GitHub → just do it (sandbox off). Gitea → hand off. Related: [[git-conventions]].
|
||||
**How to apply:** Both remotes → do it with sandbox off; probe with `git ls-remote` first, and raise Gitea PRs via `tea`. Hand off only if the Gitea key is missing from the agent. Related: [[git-conventions]].
|
||||
|
||||
@@ -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,24 @@
|
||||
---
|
||||
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