Implement researched Guix package outcome for #387: [Guix packaging] Hack'EM #693

Closed
opened 2026-09-06 13:00:42 +00:00 by htayj · 2 comments
htayj commented 2026-09-06 13:00:42 +00:00 (Migrated from github.com)

Context

This delivery ticket was created from research issue #387 ([Guix packaging] Hack'EM).

The host-validated research finding follows:

Delivery is technically and legally viable as the distinct Hack'EM variant (not the official Guix nethack package or this channel's related grunthack package). Canonical maintained source: https://github.com/elunna/hackem; fixed stable release v1.2.2, commit 6e99cffbeecd2cbf71b3d27b9285be345aca298b; commit archive SHA-256 53cee6b27997eceab653401b20face1f64f6e7360ec6ad448f5b2256c76dddb. The local channel has no hackem definition/history; official GNU Guix games.scm has nethack, but its upstream is NetHack/NetHack and it is not an equivalent Hack'EM package. Upstream README describes Hack'EM as an independently playable EvilHack-based successor/variant incorporating Slash'EM, SpliceHack, UnNetHack, SlashTHEM, xNetHack, FIQHack, SporkHack, slashem-up and SLASHEM9. The pinned source is one complete archive with no .gitmodules, language registry, updater or runtime-download dependency; the Windows CI's separate PDCurses clone is not part of the Linux package. LICENSE is the NETHACK GENERAL PUBLIC LICENSE: copying/modification/redistribution is granted with intact notices, source availability and identical terms for derivatives. Core source, maps and docs carry the corresponding NetHack freely-redistributable notices; preserve them and install LICENSE plus selected README/Guidebook/man documentation. The sound README only says Roland S-750 samples “should be no copyright” and is not a clear redistribution grant, so do not install any sys/share/sounds files. Build only the Linux tty/curses port, which the linux hints select with in-tree tty/curses sources, ncurses/tinfo, generated makedefs/dungeon/level data, and no X11/Qt/bitmap/font assets; optional unlinked GIF reader/random.c material is not in the runtime closure. Use gnu-build-system, disable parallel make, run sys/unix/setup.sh with a fixed Linux hints file, then make all offline. Expected native inputs are gcc-toolchain, gnu-make, flex, bison and the documentation formatter (groff-minimal, with col if required); runtime/build inputs are ncurses/tinfo and wrapper utilities bash-minimal, coreutils/findutils/util-linux. Expect GNU89/fcommon compatibility flags and a fixed SOURCE_DATE_EPOCH for generated files. Do not run upstream make install: its Makefile deletes HACKDIR and creates writable files there. Install the real binary as libexec/hackem-real and the generated data archive/license/docs under share/hackem; patch the compiled VAR_PLAYGROUND path to a launcher-provided environment value, keep HACKDIR/NETHACKDIR read-only store data, and wrap normal play so saves, scores, bones, locks, logs and config live below XDG_STATE_HOME/XDG_DATA_HOME (with fresh HOME fallback), with no network/server/updater behavior. The wrapper must provide exactly one safe contract, --guix-smoke: create an isolated fresh HOME/XDG/TMP tree, launch the real tty game through a PTY with deterministic locale/seed/config, select a character, make a real move, save and restore (or cleanly quit after the meaningful save/load), capture terminal output, assert all mutable files remain in the isolated tree and the store is untouched, then print the single stdout line hackem guix smoke passed. Delivery must run upstream build checks where available, guix lint/build --no-grafts --check, and this bounded smoke; research could not run Guix because the host provides no daemon and therefore claims no package proof.

Acceptance criteria

  • Implement the viable package change identified in the host-validated research finding.
  • Preserve Guix source provenance, licensing, and deterministic build requirements recorded in the finding.
  • Add and pass a package-specific safe smoke proof using isolated HOME/XDG state before closure.

Runtime evidence contract

Implementation workflow: guix-package-quality-gates
Reviewed contract file: .goocastle/runtime-evidence-contracts.json
Required proof phase: safe-package-proof; screenshot phase: runtime-screenshot
Evidence adapter: github-issue-comment
Copy this reviewed contract into the named file before running the package proof workflow.

{
  "version": 1,
  "contracts": [
    {
      "issueNumber": 693,
      "packageName": "hackem",
      "packageModulePath": "tay/packages/hackem.scm",
      "artifactPath": ".goocastle/evidence/issue-693.png",
      "runtime": {
        "executable": "hackem",
        "invocation": {
          "file": "hackem",
          "args": [
            "--guix-smoke"
          ]
        },
        "successMarker": "hackem guix smoke passed"
      }
    }
  ]
}

Imported from GitHub issue/PR. Originally posted by htayj on 2026-09-06T13:00:42Z.

<!-- goocastle-implementation-ticket:sequential-reviewer:387:1:implementation-ready --> ## Context This delivery ticket was created from research issue #387 ([Guix packaging] Hack'EM). The host-validated research finding follows: Delivery is technically and legally viable as the distinct Hack'EM variant (not the official Guix nethack package or this channel's related grunthack package). Canonical maintained source: https://github.com/elunna/hackem; fixed stable release v1.2.2, commit 6e99cffbeecd2cbf71b3d27b9285be345aca298b; commit archive SHA-256 53cee6b27997eceab653401b20face1f64f6e7360ec6ad448f5b2256c76dddb. The local channel has no hackem definition/history; official GNU Guix games.scm has nethack, but its upstream is NetHack/NetHack and it is not an equivalent Hack'EM package. Upstream README describes Hack'EM as an independently playable EvilHack-based successor/variant incorporating Slash'EM, SpliceHack, UnNetHack, SlashTHEM, xNetHack, FIQHack, SporkHack, slashem-up and SLASHEM9. The pinned source is one complete archive with no .gitmodules, language registry, updater or runtime-download dependency; the Windows CI's separate PDCurses clone is not part of the Linux package. LICENSE is the NETHACK GENERAL PUBLIC LICENSE: copying/modification/redistribution is granted with intact notices, source availability and identical terms for derivatives. Core source, maps and docs carry the corresponding NetHack freely-redistributable notices; preserve them and install LICENSE plus selected README/Guidebook/man documentation. The sound README only says Roland S-750 samples “should be no copyright” and is not a clear redistribution grant, so do not install any sys/share/sounds files. Build only the Linux tty/curses port, which the linux hints select with in-tree tty/curses sources, ncurses/tinfo, generated makedefs/dungeon/level data, and no X11/Qt/bitmap/font assets; optional unlinked GIF reader/random.c material is not in the runtime closure. Use gnu-build-system, disable parallel make, run sys/unix/setup.sh with a fixed Linux hints file, then make all offline. Expected native inputs are gcc-toolchain, gnu-make, flex, bison and the documentation formatter (groff-minimal, with col if required); runtime/build inputs are ncurses/tinfo and wrapper utilities bash-minimal, coreutils/findutils/util-linux. Expect GNU89/fcommon compatibility flags and a fixed SOURCE_DATE_EPOCH for generated files. Do not run upstream make install: its Makefile deletes HACKDIR and creates writable files there. Install the real binary as libexec/hackem-real and the generated data archive/license/docs under share/hackem; patch the compiled VAR_PLAYGROUND path to a launcher-provided environment value, keep HACKDIR/NETHACKDIR read-only store data, and wrap normal play so saves, scores, bones, locks, logs and config live below XDG_STATE_HOME/XDG_DATA_HOME (with fresh HOME fallback), with no network/server/updater behavior. The wrapper must provide exactly one safe contract, --guix-smoke: create an isolated fresh HOME/XDG/TMP tree, launch the real tty game through a PTY with deterministic locale/seed/config, select a character, make a real move, save and restore (or cleanly quit after the meaningful save/load), capture terminal output, assert all mutable files remain in the isolated tree and the store is untouched, then print the single stdout line hackem guix smoke passed. Delivery must run upstream build checks where available, guix lint/build --no-grafts --check, and this bounded smoke; research could not run Guix because the host provides no daemon and therefore claims no package proof. ## Acceptance criteria - Implement the viable package change identified in the host-validated research finding. - Preserve Guix source provenance, licensing, and deterministic build requirements recorded in the finding. - Add and pass a package-specific safe smoke proof using isolated HOME/XDG state before closure. <!-- goocastle-runtime-evidence-contract --> ## Runtime evidence contract Implementation workflow: `guix-package-quality-gates` Reviewed contract file: `.goocastle/runtime-evidence-contracts.json` Required proof phase: `safe-package-proof`; screenshot phase: `runtime-screenshot` Evidence adapter: `github-issue-comment` Copy this reviewed contract into the named file before running the package proof workflow. ```json { "version": 1, "contracts": [ { "issueNumber": 693, "packageName": "hackem", "packageModulePath": "tay/packages/hackem.scm", "artifactPath": ".goocastle/evidence/issue-693.png", "runtime": { "executable": "hackem", "invocation": { "file": "hackem", "args": [ "--guix-smoke" ] }, "successMarker": "hackem guix smoke passed" } } ] } ``` <!-- goocastle-runtime-evidence-contract-end --> --- Imported from [GitHub issue/PR](https://github.com/htayj/guix-channel/issues/693). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T13:00:42Z.
htayj commented 2026-09-08 04:36:36 +00:00 (Migrated from github.com)

Goocastle verified runtime evidence.

Runtime screenshot

Runtime receipt
  • Package: hackem
  • Safe package proof phase: safe-package-proof
  • Safe package proof argv: ["node","/opt/goocastle/bin/guix-package-proof.mjs","--package-name","hackem","--module-path","tay/packages/hackem.scm","--runtime-json","{&quot;executable&quot;:&quot;hackem&quot;,&quot;invocation&quot;:{&quot;file&quot;:&quot;hackem&quot;,&quot;args&quot;:[&quot;--guix-smoke&quot;]},&quot;successMarker&quot;:&quot;hackem guix smoke passed&quot;}"]
  • Screenshot phase: runtime-screenshot
  • Screenshot argv: ["sh",".goocastle/capture-guix-package-screenshot.sh"]
  • Runtime executable (Guix store/profile): /gnu/store/wj1x36rsyrccdkkwv8bwrk2jz0jg8fib-hackem-1.2.2/bin/hackem
  • Runtime invocation: ["/gnu/store/wj1x36rsyrccdkkwv8bwrk2jz0jg8fib-hackem-1.2.2/bin/hackem","--guix-smoke"]
  • Expected runtime invocation: ["hackem","--guix-smoke"]
  • Expected runtime marker: hackem guix smoke passed
  • Per-issue runtime contract: .goocastle/runtime-evidence-contracts.json (issue #693, SHA-256 74d69dc1184499a69633e190476c6b2b5616eaf98254546168eb646246d61188)
  • Artifact path: .goocastle/evidence/issue-693.png
  • Artifact SHA-256: b8c6c75822bdc1bffdb8a75f19777c8091ad267c0232279a3b750aa4194b759e
  • Artifact commit: a5878e4abb954ad91e1dd38455cf6dfffca6dd40
  • Artifact size/format: 27389 bytes / png

Imported from GitHub comment. Originally posted by htayj on 2026-09-08T04:36:36Z.

<!-- goocastle-runtime-evidence:sequential-reviewer:693:1:b8c6c75822bdc1bffdb8a75f19777c8091ad267c0232279a3b750aa4194b759e --> Goocastle verified runtime evidence. ![Runtime screenshot](https://github.com/htayj/guix-channel/blob/a5878e4abb954ad91e1dd38455cf6dfffca6dd40/.goocastle/evidence/issue-693.png?raw=1) <details><summary>Runtime receipt</summary> - Package: <code>hackem</code> - Safe package proof phase: <code>safe-package-proof</code> - Safe package proof argv: <code>[&quot;node&quot;,&quot;/opt/goocastle/bin/guix-package-proof.mjs&quot;,&quot;--package-name&quot;,&quot;hackem&quot;,&quot;--module-path&quot;,&quot;tay/packages/hackem.scm&quot;,&quot;--runtime-json&quot;,&quot;{\&quot;executable\&quot;:\&quot;hackem\&quot;,\&quot;invocation\&quot;:{\&quot;file\&quot;:\&quot;hackem\&quot;,\&quot;args\&quot;:[\&quot;--guix-smoke\&quot;]},\&quot;successMarker\&quot;:\&quot;hackem guix smoke passed\&quot;}&quot;]</code> - Screenshot phase: <code>runtime-screenshot</code> - Screenshot argv: <code>[&quot;sh&quot;,&quot;.goocastle/capture-guix-package-screenshot.sh&quot;]</code> - Runtime executable (Guix store/profile): <code>/gnu/store/wj1x36rsyrccdkkwv8bwrk2jz0jg8fib-hackem-1.2.2/bin/hackem</code> - Runtime invocation: <code>[&quot;/gnu/store/wj1x36rsyrccdkkwv8bwrk2jz0jg8fib-hackem-1.2.2/bin/hackem&quot;,&quot;--guix-smoke&quot;]</code> - Expected runtime invocation: <code>[&quot;hackem&quot;,&quot;--guix-smoke&quot;]</code> - Expected runtime marker: <code>hackem guix smoke passed</code> - Per-issue runtime contract: <code>.goocastle/runtime-evidence-contracts.json (issue #693, SHA-256 74d69dc1184499a69633e190476c6b2b5616eaf98254546168eb646246d61188)</code> - Artifact path: <code>.goocastle/evidence/issue-693.png</code> - Artifact SHA-256: <code>b8c6c75822bdc1bffdb8a75f19777c8091ad267c0232279a3b750aa4194b759e</code> - Artifact commit: <code>a5878e4abb954ad91e1dd38455cf6dfffca6dd40</code> - Artifact size/format: <code>27389 bytes / png</code> </details> --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/693#issuecomment-5579306229). Originally posted by [htayj](https://github.com/htayj) on 2026-09-08T04:36:36Z.
htayj commented 2026-09-08 04:36:40 +00:00 (Migrated from github.com)

Completed by Goocastle


Imported from GitHub comment. Originally posted by htayj on 2026-09-08T04:36:40Z.

Completed by Goocastle --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/693#issuecomment-5579306826). Originally posted by [htayj](https://github.com/htayj) on 2026-09-08T04:36:40Z.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
tay/guix-channel#693
No description provided.