Implement researched Guix package outcome for #385: [Guix packaging] GruntHack #691

Closed
opened 2026-09-06 07:11:37 +00:00 by htayj · 4 comments
htayj commented 2026-09-06 07:11:37 +00:00 (Migrated from github.com)

Context

This delivery ticket was created from research issue #385 ([Guix packaging] GruntHack).

The host-validated research finding follows:

Canonical source: https://github.com/NHTangles/GruntHack (the GruntHack project page identifies this as the updated repository; the issue's https://github.com/GruntHack/GruntHack URL is not publicly resolvable). Use the stable GruntHack 0.2.4 source at commit 51d75eebbcf8ab0ce31ddab9581d266db0a691c5 (include/patchlevel.h; commit date 2018-09-17), pinned GitHub archive SHA-256 00c8b0178f4fb2aefd08c51d08263b9f6c57340b601afb6d9f9528fdd9bd7187. The project is a NetHack 3.4.3 derivative, distinct from this channel's acehack and dnethack packages; no same-upstream GruntHack package or delivery history was found in the local channel. The single repository has no Git submodules and no language registry. Its authoritative Unix build metadata is sys/unix/setup.sh plus the generated Makefiles: run the setup, build the terminal port from src, generate the game data with the top-level targets, and link WINTTYLIB=-lncurses. The package module should be tay/packages/grunthack.scm, package name grunthack, with a manual/gnu build using gcc-toolchain, gnumake, and ncurses; use the repository's shipped lex/yacc output or declare flex/bison when regenerating the level utilities, and avoid the historical install target because it assumes /usr, a games account, setgid/setuid, and a writable compiled-in /usr/gh. Patch the build/install phases to place the executable and read-only data in the store, install dat/license and the relevant text documentation, and make the launcher set HACKDIR/NETHACKDIR to store data while directing saves, scores, and other mutable state to an XDG data directory under the user's HOME. Upstream has no updater, telemetry, runtime download, or network feature. License evidence is dat/license at the pinned commit: it is the NetHack General Public License and README explicitly directs distributors to it; code, maps, game data, and documentation shipped from this one origin are covered by that notice. Do not install sys/share/sounds, optional font/tile assets, or other files whose provenance is not needed: sys/share/sounds/README only says the Roland samples should have no copyright, which is not a clear redistribution grant. The tty-only package therefore has no installed sound/font/tile origin requiring separate clearance. Research did not claim a build proof because the phase boundary forbids Guix-daemon/toolchain execution; the upstream build metadata is sufficient to define the later offline Guix build and no-network closure. Required delivery acceptance: guix lint and no-grafts build offline; run upstream-compatible tests where available; run --check; verify installed license/notice coverage and no writable store paths. The wrapper must add the exact safe runtime contract below: grunthack --guix-smoke creates an isolated fresh HOME/XDG data directory, runs the real terminal game through a bounded PTY with fixed TERM and deterministic character-selection/gameplay input, enters the first level, performs a movement, saves, exits, restores that save, performs another normal command, asserts the save and all mutable files remain below the isolated XDG directory and the store is unchanged, emits the single-line marker, and exits zero. Capture .goocastle/evidence/issue-385.png showing the real local game and the successful save/restore 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": 691,
      "packageName": "grunthack",
      "packageModulePath": "tay/packages/grunthack.scm",
      "artifactPath": ".goocastle/evidence/issue-691.png",
      "runtime": {
        "executable": "grunthack",
        "invocation": {
          "file": "grunthack",
          "args": [
            "--guix-smoke"
          ]
        },
        "successMarker": "grunthack guix smoke passed"
      }
    }
  ]
}

Imported from GitHub issue/PR. Originally posted by htayj on 2026-09-06T07:11:37Z.

<!-- goocastle-implementation-ticket:sequential-reviewer:385:1:implementation-ready --> ## Context This delivery ticket was created from research issue #385 ([Guix packaging] GruntHack). The host-validated research finding follows: Canonical source: https://github.com/NHTangles/GruntHack (the GruntHack project page identifies this as the updated repository; the issue's https://github.com/GruntHack/GruntHack URL is not publicly resolvable). Use the stable GruntHack 0.2.4 source at commit 51d75eebbcf8ab0ce31ddab9581d266db0a691c5 (include/patchlevel.h; commit date 2018-09-17), pinned GitHub archive SHA-256 00c8b0178f4fb2aefd08c51d08263b9f6c57340b601afb6d9f9528fdd9bd7187. The project is a NetHack 3.4.3 derivative, distinct from this channel's acehack and dnethack packages; no same-upstream GruntHack package or delivery history was found in the local channel. The single repository has no Git submodules and no language registry. Its authoritative Unix build metadata is sys/unix/setup.sh plus the generated Makefiles: run the setup, build the terminal port from src, generate the game data with the top-level targets, and link WINTTYLIB=-lncurses. The package module should be tay/packages/grunthack.scm, package name grunthack, with a manual/gnu build using gcc-toolchain, gnumake, and ncurses; use the repository's shipped lex/yacc output or declare flex/bison when regenerating the level utilities, and avoid the historical install target because it assumes /usr, a games account, setgid/setuid, and a writable compiled-in /usr/gh. Patch the build/install phases to place the executable and read-only data in the store, install dat/license and the relevant text documentation, and make the launcher set HACKDIR/NETHACKDIR to store data while directing saves, scores, and other mutable state to an XDG data directory under the user's HOME. Upstream has no updater, telemetry, runtime download, or network feature. License evidence is dat/license at the pinned commit: it is the NetHack General Public License and README explicitly directs distributors to it; code, maps, game data, and documentation shipped from this one origin are covered by that notice. Do not install sys/share/sounds, optional font/tile assets, or other files whose provenance is not needed: sys/share/sounds/README only says the Roland samples should have no copyright, which is not a clear redistribution grant. The tty-only package therefore has no installed sound/font/tile origin requiring separate clearance. Research did not claim a build proof because the phase boundary forbids Guix-daemon/toolchain execution; the upstream build metadata is sufficient to define the later offline Guix build and no-network closure. Required delivery acceptance: guix lint and no-grafts build offline; run upstream-compatible tests where available; run --check; verify installed license/notice coverage and no writable store paths. The wrapper must add the exact safe runtime contract below: grunthack --guix-smoke creates an isolated fresh HOME/XDG data directory, runs the real terminal game through a bounded PTY with fixed TERM and deterministic character-selection/gameplay input, enters the first level, performs a movement, saves, exits, restores that save, performs another normal command, asserts the save and all mutable files remain below the isolated XDG directory and the store is unchanged, emits the single-line marker, and exits zero. Capture .goocastle/evidence/issue-385.png showing the real local game and the successful save/restore 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": 691, "packageName": "grunthack", "packageModulePath": "tay/packages/grunthack.scm", "artifactPath": ".goocastle/evidence/issue-691.png", "runtime": { "executable": "grunthack", "invocation": { "file": "grunthack", "args": [ "--guix-smoke" ] }, "successMarker": "grunthack guix smoke passed" } } ] } ``` <!-- goocastle-runtime-evidence-contract-end --> --- Imported from [GitHub issue/PR](https://github.com/htayj/guix-channel/issues/691). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T07:11:37Z.
htayj commented 2026-09-06 09:24:26 +00:00 (Migrated from github.com)

Goocastle blocked this ticket after the bounded repair budget was exhausted for the required command gate.
The failure receipt and task branch provenance remain preserved; inspect the branch and repair the failing gate before retrying.

Bounded failure evidence:
Failed command: node /opt/goocastle/bin/guix-package-proof.mjs '--package-name' grunthack '--module-path' tay/packages/grunthack.scm '--runtime-json' '{"executable":"grunthack","invocation":{"file":"grunthack","args":["--guix-smoke"]},"successMarker":"grunthack guix smoke passed"}'
Exit status: 1
Final failure lines:
[stderr] Cannot start runtime evidence phase "safe-package-proof": task worktree contains uncommitted changes after agent phase "edge-case-audit"; scheduling bounded implementation/audit repair before retrying


Imported from GitHub comment. Originally posted by htayj on 2026-09-06T09:24:26Z.

<!-- goocastle-repair-blocked:691:safe-package-proof --> Goocastle blocked this ticket after the bounded repair budget was exhausted for the required command gate. The failure receipt and task branch provenance remain preserved; inspect the branch and repair the failing gate before retrying. Bounded failure evidence: Failed command: node /opt/goocastle/bin/guix-package-proof.mjs '--package-name' grunthack '--module-path' tay/packages/grunthack.scm '--runtime-json' '{"executable":"grunthack","invocation":{"file":"grunthack","args":["--guix-smoke"]},"successMarker":"grunthack guix smoke passed"}' Exit status: 1 Final failure lines: [stderr] Cannot start runtime evidence phase "safe-package-proof": task worktree contains uncommitted changes after agent phase "edge-case-audit"; scheduling bounded implementation/audit repair before retrying --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/691#issuecomment-5558311755). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T09:24:26Z.
htayj commented 2026-09-06 11:05:15 +00:00 (Migrated from github.com)

Goocastle blocked this ticket after the bounded repair budget was exhausted for the required command gate.
The failure receipt and task branch provenance remain preserved; inspect the branch and repair the failing gate before retrying.

Bounded failure evidence:
Failed command: node /opt/goocastle/bin/guix-package-proof.mjs '--package-name' grunthack '--module-path' tay/packages/grunthack.scm '--runtime-json' '{"executable":"grunthack","invocation":{"file":"grunthack","args":["--guix-smoke"]},"successMarker":"grunthack guix smoke passed"}'
Exit status: 1
Final failure lines:
[stderr] Session terminated, killing shell...grunthack smoke: first game failed
[stdout] tay/packages/grunthack.scm:248:0: grunthack@0.2.4-0.5[REDACTED]d75ee: parentheses feel lonely, move to the previous or next line
[stderr] node exited with code [REDACTED]
[earlier or oversized output omitted]


Imported from GitHub comment. Originally posted by htayj on 2026-09-06T11:05:15Z.

<!-- goocastle-repair-blocked:691:safe-package-proof --> Goocastle blocked this ticket after the bounded repair budget was exhausted for the required command gate. The failure receipt and task branch provenance remain preserved; inspect the branch and repair the failing gate before retrying. Bounded failure evidence: Failed command: node /opt/goocastle/bin/guix-package-proof.mjs '--package-name' grunthack '--module-path' tay/packages/grunthack.scm '--runtime-json' '{"executable":"grunthack","invocation":{"file":"grunthack","args":["--guix-smoke"]},"successMarker":"grunthack guix smoke passed"}' Exit status: 1 Final failure lines: [stderr] Session terminated, killing shell...grunthack smoke: first game failed [stdout] tay/packages/grunthack.scm:248:0: grunthack@0.2.4-0.5[REDACTED]d75ee: parentheses feel lonely, move to the previous or next line [stderr] node exited with code [REDACTED] [earlier or oversized output omitted] --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/691#issuecomment-5558795122). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T11:05:15Z.
htayj commented 2026-09-06 12:08:32 +00:00 (Migrated from github.com)

Goocastle verified runtime evidence.

Runtime screenshot

Runtime receipt
  • Package: grunthack
  • Safe package proof phase: safe-package-proof
  • Safe package proof argv: ["node","/opt/goocastle/bin/guix-package-proof.mjs","--package-name","grunthack","--module-path","tay/packages/grunthack.scm","--runtime-json","{&quot;executable&quot;:&quot;grunthack&quot;,&quot;invocation&quot;:{&quot;file&quot;:&quot;grunthack&quot;,&quot;args&quot;:[&quot;--guix-smoke&quot;]},&quot;successMarker&quot;:&quot;grunthack guix smoke passed&quot;}"]
  • Screenshot phase: runtime-screenshot
  • Screenshot argv: ["sh",".goocastle/capture-guix-package-screenshot.sh"]
  • Runtime executable (Guix store/profile): /gnu/store/196szhapbiicf5dlysnvxcdshi652cpl-grunthack-0.2.4-0.51d75ee/bin/grunthack
  • Runtime invocation: ["/gnu/store/196szhapbiicf5dlysnvxcdshi652cpl-grunthack-0.2.4-0.51d75ee/bin/grunthack","--guix-smoke"]
  • Expected runtime invocation: ["grunthack","--guix-smoke"]
  • Expected runtime marker: grunthack guix smoke passed
  • Per-issue runtime contract: .goocastle/runtime-evidence-contracts.json (issue #691, SHA-256 76884c56ba3494d13586ec8a0b013f2d5738fe3567ef0d245e81cc7431e41ecf)
  • Artifact path: .goocastle/evidence/issue-691.png
  • Artifact SHA-256: 40e00472da601a3f941b576ae2374762128621147f608626b0f5176f85190473
  • Artifact commit: a6483af9e8e7d4eea3cfcb9f9fb9e4ac900b5bf8
  • Artifact size/format: 29107 bytes / png

Imported from GitHub comment. Originally posted by htayj on 2026-09-06T12:08:32Z.

<!-- goocastle-runtime-evidence:sequential-reviewer:691:1:40e00472da601a3f941b576ae2374762128621147f608626b0f5176f85190473 --> Goocastle verified runtime evidence. ![Runtime screenshot](https://github.com/htayj/guix-channel/blob/a6483af9e8e7d4eea3cfcb9f9fb9e4ac900b5bf8/.goocastle/evidence/issue-691.png?raw=1) <details><summary>Runtime receipt</summary> - Package: <code>grunthack</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;grunthack&quot;,&quot;--module-path&quot;,&quot;tay/packages/grunthack.scm&quot;,&quot;--runtime-json&quot;,&quot;{\&quot;executable\&quot;:\&quot;grunthack\&quot;,\&quot;invocation\&quot;:{\&quot;file\&quot;:\&quot;grunthack\&quot;,\&quot;args\&quot;:[\&quot;--guix-smoke\&quot;]},\&quot;successMarker\&quot;:\&quot;grunthack 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/196szhapbiicf5dlysnvxcdshi652cpl-grunthack-0.2.4-0.51d75ee/bin/grunthack</code> - Runtime invocation: <code>[&quot;/gnu/store/196szhapbiicf5dlysnvxcdshi652cpl-grunthack-0.2.4-0.51d75ee/bin/grunthack&quot;,&quot;--guix-smoke&quot;]</code> - Expected runtime invocation: <code>[&quot;grunthack&quot;,&quot;--guix-smoke&quot;]</code> - Expected runtime marker: <code>grunthack guix smoke passed</code> - Per-issue runtime contract: <code>.goocastle/runtime-evidence-contracts.json (issue #691, SHA-256 76884c56ba3494d13586ec8a0b013f2d5738fe3567ef0d245e81cc7431e41ecf)</code> - Artifact path: <code>.goocastle/evidence/issue-691.png</code> - Artifact SHA-256: <code>40e00472da601a3f941b576ae2374762128621147f608626b0f5176f85190473</code> - Artifact commit: <code>a6483af9e8e7d4eea3cfcb9f9fb9e4ac900b5bf8</code> - Artifact size/format: <code>29107 bytes / png</code> </details> --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/691#issuecomment-5559108046). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T12:08:32Z.
htayj commented 2026-09-06 12:08:37 +00:00 (Migrated from github.com)

Completed by Goocastle


Imported from GitHub comment. Originally posted by htayj on 2026-09-06T12:08:37Z.

Completed by Goocastle --- Imported from [GitHub comment](https://github.com/htayj/guix-channel/issues/691#issuecomment-5559108392). Originally posted by [htayj](https://github.com/htayj) on 2026-09-06T12:08:37Z.
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#691
No description provided.