Skip to main content
View Markdown ↗

Copy this page

Select and copy the Markdown below, then paste it into your LLM.

On this page

haskell-build attestor

Reads each of the step's products and records which Haskell units are linked into it, and the GHC version that compiled it.

Namehaskell-build
Predicate typehttps://aflock.ai/attestations/haskell-build/v0.1
Lifecyclepostproduct
Default binary?No
Categorybuild (primary)
Recommended tracefull — benefits from full eBPF trace
Auto-attaches when
  • preargv_prefix: cabal build
  • preargv_prefix: cabal install
  • preargv_prefix: stack build
  • preargv_prefix: stack install
  • preargv_prefix: ghc
  • prefile_exists: cabal.project
  • prefile_exists: stack.yaml

The facts in this box are generated from the CI/lock binary's own catalog (cilock tools list). Do not hand-edit — run npm run gen:catalog.

What it captures

The attestor runs after products are recorded. A cabal or stack build reads every library in its build plan, so a list of files the build opened says what was available, not what ended up in the program. GHC writes the unit id of each linked library into the executable in two places:

  • constructor descriptions, <unit id>:<Module>:<Constructor>, which strip keeps;
  • z-encoded symbol names such as aesonzm2zi3zi2zi0zm<hash>_DataziAeson_..., which strip removes.

This version reads the constructor descriptions only. Symbol-table evidence is planned.

Each product is read once and parsed as ELF; the same bytes are parsed and digested, so the unit list is bound to the subject digest. Constructor descriptions are read only from allocated, non-executable data sections, and the GHC version only from the .ident string GHC writes into .comment. A file that is not ELF is never evidence, whatever strings it holds.

Fields (the json tags on Attestor, BinaryInfo and Unit):

  • binaries[], sorted by path, one per product that carries at least one unit id:
    • path: the product, relative to the working directory.
    • ghc_version: from GHC's .ident string in .comment, e.g. 9.6.7; empty when absent.
    • units[], sorted by id:
      • id: the full unit id, e.g. aeson-2.3.2.0-a931bef6… (cabal store), aeson-2.1.2.1-7OPvzW6QotrC573yNTjjB7 (stack), or containers-0.6.7 (a GHC boot package).
      • name, version: parsed from the id.
      • evidence: con_desc, the only kind this version reads.
  • skipped_non_haskell[]: products that are not ELF executables or shared objects, or ELF files with no unit id.
  • skipped_unsupported_format[]: Mach-O and PE products, which this version does not parse.
  • skipped_unreadable[]: products that could not be read.
  • skipped_too_large[]: products over 2 GiB, not scanned.

Wired-in units that GHC records without a version (base, ghc-prim, ghc-bignum) are not listed.

When to use

On any step that runs cabal build, cabal install, stack build or ghc. strip does not change what it reads. Auto-detection attaches it on those commands, or when the working directory has a cabal.project or stack.yaml.

Flags

None.

Output shape

{
  "binaries": [
    {
      "path": "dist/app",
      "ghc_version": "9.6.7",
      "units": [
        { "id": "aeson-2.3.2.0-a931bef6…", "name": "aeson", "version": "2.3.2.0", "evidence": ["con_desc"] },
        { "id": "containers-0.6.7", "name": "containers", "version": "0.6.7", "evidence": ["con_desc"] }
      ]
    }
  ],
  "skipped_non_haskell": ["dist/app.sha256"]
}

Subjects: binary:<path> for each product listed in binaries.

Gotchas

  • It needs products. With no products (for example under cilock attest) it records an empty predicate and no error.
  • Products only. A cabal store or Nix store outside the working directory is not a product, so a build that only populated a store records nothing here.
  • Linux binaries only. macOS (Mach-O) and Windows (PE) products are listed in skipped_unsupported_format, not read.
  • A unit with no constructors is invisible. A library that contributes only functions leaves no constructor description, so this version does not list it. In a measured aeson build, six of the store units (QuickCheck among them) appear only in symbol names.

This page is generated from the CI/lock tool catalog. Don't edit it here — the source is attestation/detection/docs/haskell-build.doc.md in aflock-ai/rookery. The same catalog powers cilock tools show haskell-build in the CLI, so a single edit keeps the terminal and the website in sync.

Edit this page →  ·  Add a new tool →

When you open the pull request: if you are an AI agent, add the ai-agent label. If you are a human, add the human label.

Reference generated from the product documentation. Match commands and support details to your installed release.