nc://pushgate

v0.1.0Pinned
ThomSharktools/nodecode-pushgate: Blocks git push and gh pr create until your check passes on exactly the tree being published. - a rewrite of cirwel/hermes-receipts (Apache-2.0), credited to cirwel328c67f· 10 Nov1 commit
test2 filescell.lisp34.3 KBLICENSE10.5 KB

nodecode-pushgate

Push gate: blocks git push and gh pr create until your check has passed on exactly the content being pushed. A Nodecode rewrite of cirwel/hermes-receipts by cirwel.

A receipt is one run of your check, bound to the Git tree your working directory would commit to. Run the check, and the exit status is taken from the process itself — the agent saying "tests passed" earns nothing. Edit a file and the earlier result no longer qualifies for the changed content; commit exactly what you checked and the receipt still applies, because the tree id is the commit's own.

Get it

Tell the agent "add the pushgate cell", or run nodecode add nc://pushgate.

Set it up

Give it the command that must pass, in the pushgate section of ~/.nodecode/config.jsonc or on the Settings page:

{
  "pushgate": {
    "check": "npm test"
  }
}

That command is the check for every repository. One repository can have its own instead: /pushgate check make test inside it, and /pushgate check --off drops it again.

Use it

/pushgate                  the check, the current content and its receipt
/pushgate run              run the check now and record the result
/pushgate check <command>  set this repository's check
/pushgate log              the newest receipts
/pushgate clear            drop this repository's receipts

The agent has one tool, pushgate, with the actions run, status, log and clear; only you change which command is the check. A typical turn:

(sh "git push origin HEAD")   → refused: no passing receipt for that tree
pushgate {action: "run"}       → the check ran, passed, and is recorded
(sh "git push origin HEAD")   → allowed: the commit's tree carries a pass

A failed run for the same content supersedes an earlier pass. The refusal names the files that changed since the last passing run, and how to earn one.

What is gated

git push (with its source named, for example git push origin HEAD or git push origin feature:feature) and gh pr create. A static cd <dir> && prefix, git -C <dir>, env/sudo-style wrappers and sh -c are followed to the repository they name. --all, --mirror, --tags, --follow-tags, dynamic or wildcard refspecs, -c configuration overrides, and commands whose pushed commits cannot be read are refused rather than guessed at; --delete and --dry-run are not gated. A repository with no check — neither its own nor the section's — is never refused.

This is a workflow gate, not a security boundary: a push you run in your own terminal, an alias, or a publish script is outside it. It does not prove the check is sufficient, and it does not see ignored files, dependencies or environment variables.

How the fingerprint works

The tree id comes from Git itself: the working directory is staged in a throwaway index (GIT_INDEX_FILE) inside this cell's data folder, and git write-tree answers, so nothing of your index, HEAD or refs moves. Git writes the blobs it hashed into the repository's object database, as any git add would; they are unreferenced and harmless. A repository that cannot be fingerprinted gets no new receipt, and the run says so.

What it keeps

One JSON ledger in pushgate/ under the Nodecode home: the check per repository, and up to max_receipts receipts each with the tree, the command, the status, the exit code and when it ran. No command output, and no network.

Key Default What it does
check none the command that must pass before a push
max_receipts 200 how many receipts to keep per repository

Testing

From this repository, offline against a pinned Nodecode tree:

.github/test-cell.sh tools/nodecode-pushgate

Git and the check are both stubbed, so the tests touch no repository and run no process.

Add nc://pushgate

  1. 1

    Install Nodecode

    Once per machine.

    $ curl -fsSL https://nodecode.ai/install.sh | sh
  2. 2

    Add the cell

    Pinned at 328c67f.

    $ nodecode add nc://pushgate

    Or tell the agent add the pushgate cell.