Skip to content

receipt-keys gate red on main since 2026-09-28: header comments read as keyless instantiations #877

Open

Description

@gHashTag

What is wrong

TRI-NET portability and receipt keys (.github/workflows/trinet-portability.yml, job receipt-keys) has failed on every scheduled run on main from 2026-09-28 through 2026-10-04: 7 of 7. The last green scheduled run was 2026-09-27 on 9947512ff.

receipt-key check: 2 module default(s), 5 testbench instantiation(s) of 2 keyed module(s)
  RULE 2  formal/tern_tc_layer_rtl_tb.v:7: instantiates trinet_node_core without passing RECEIPT_KEY. ...
  RULE 2  formal/tern_tc_layer_rtl_tb.v:18: instantiates trinet_node_core without passing RECEIPT_KEY. ...
FAIL: 2 problem(s)

Lines 7 and 18 are comments in the testbench header. Both name the file fpga/portable/trinet_node_core.v. The only real instantiation is line 42, and it passes the key: trinet_node_core #(.BAUD_DIV_P(BAUD_DIV), .RECEIPT_KEY(128'h0)) dut (. So the bench obeys rule 2, and the red is a false positive in conformance/key_default_check.py, which matches module names in raw source, comments included.

The same defect also produces a false negative. The check accepts an instantiation if the text RECEIPT_KEY appears anywhere in its parameter list, so #(.BAUD_DIV_P(BAUD_DIV), /* .RECEIPT_KEY(128'h0) */) counts as passing a key. On today's tree that mutant reports only the two comment lines, nothing at line 42.

How it got onto main unseen

The testbench reached main in d7e9718 (merge of #355, 2026-09-27). The checker reads every formal/**/*_tb.v and every fpga/**/*.v, but the workflow's paths: list names one testbench and three RTL locations. #355 changed 13 files the checker reads and none on the list, so the gate did not run on the PR or on the push, only on the next day's schedule. Measured on main first-parent history since 2026-09-04: 3 commits touched files the checker reads (d7e9718, 0f4512b, 57de4a1), and all 3 were outside the paths list.

This is the same defect class as #875: one list of paths in the workflow and a second one inside the script, maintained by hand.

Plan

  1. This issue: blank comments and string literals before matching, keeping newlines so line numbers stay right. Add a CI guard step: a key written only in a comment must be rejected, at the line of the real instantiation.
  2. Follow-up, after ci: run nine workflows once per PR commit, on every path their push run watched #876 merges (it rewrites the same on: block): make the workflow's paths cover what the checker reads. Widening the whole workflow to fpga/**/*.v would also run the portability job on every RTL change. That job takes about 2 minutes: 2m00s to 2m02s on four runs on 2026-10-04. (I first wrote "25-minute" here, which is its timeout-minutes, not its duration.) Moving receipt-keys into its own workflow would avoid those 2 minutes per run, but it is no longer clearly the better shape. That is the owner's call.

Done when

  • python3 conformance/key_default_check.py exits 0 on main's tree and reports 3 testbench instantiations (not 5).
  • Mutants that must fail still fail, each with exactly one RULE line in the right place: the two the workflow already applies, plus the bench dropping its key and the key moved into a comment.
  • Mutants that must pass do pass: a commented-out non-null default, and the module name inside a $display string.

Part of #851 (W15: gates that fail or pass for a reason other than their claim).

🤖 Generated with Claude Code

Activity

  1. added 2 commits that reference this issue on Oct 10, 2026
    0a3c197
    b40cbbf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions