gha-command-proof 1.0.0

Verifier for GitHub Actions workflow commands and environment files
Documentation
# GHA Command Proof Protocol Scope

`gha-command-proof` models the command and environment-file boundary between an action step and the GitHub Actions runner.

Primary references:

- GitHub Docs, "Workflow commands for GitHub Actions"
- `actions/toolkit` command escaping implementation
- `actions/runner` `ActionCommand` and `FileCommandManager` implementations

## Command Stream

The parser accepts both runner syntaxes:

```text
::name key=value,key=value::data
##[name key=value;key=value]data
```

Modern command parsing trims leading whitespace and requires the line to start with `::`. Legacy parsing recognizes `##[` anywhere in the line, matching the runner's older parser behavior.

Command names and property names are treated case-insensitively and normalized to lowercase in receipts.

## Escaping

Modern command data unescapes:

```text
%0D -> carriage return
%0A -> line feed
%25 -> percent
```

Modern command properties also unescape:

```text
%3A -> colon
%2C -> comma
```

Legacy command fields unescape:

```text
%3B -> semicolon
%0D -> carriage return
%0A -> line feed
%5D -> closing bracket
%25 -> percent
```

## Command Validation

The first release recognizes:

```text
add-mask
add-matcher
add-path
debug
echo
endgroup
error
group
notice
remove-matcher
save-state
set-env
set-output
stop-commands
warning
```

`set-env` and `add-path` are failed because current GitHub runners disable those stdout commands by default. `set-output` and `save-state` are warned because they are deprecated in favor of environment files.

`stop-commands` switches the analyzer into suppressed mode until the matching `::{token}::` line is seen. Commands inside that region are recorded as suppressed rather than processed.

## Environment Files

`GITHUB_ENV`, `GITHUB_OUTPUT`, and `GITHUB_STATE` accept:

```text
NAME=VALUE
NAME<<DELIMITER
multi
line
DELIMITER
```

Blank lines are ignored. Malformed records fail validation.

`GITHUB_PATH` is parsed as one path record per non-empty line.

`GITHUB_STEP_SUMMARY` is treated as Markdown content and fails above the runner's 1 MiB attachment limit.

## Security Behavior

The analyzer never renders raw `add-mask` values in command records. Later command data, environment-file values, summaries, and redacted log output replace known masks with `***`.

When a value written to `GITHUB_OUTPUT` exactly matches a value previously registered with `add-mask`, the step proof fails. GitHub treats masked values as secrets and does not allow them to be set as outputs.

## Compatibility Limits

The tool does not claim to replace a full runner. It does not execute commands, upload summaries, load problem matcher JSON, resolve container paths, or reproduce every server-side annotation behavior. Its output is a compatibility receipt for the action command and file-command protocol.