Skip to content

feat(exit-certificate): execution traceability — startup banner and build version#1688

Merged
joanestebanr merged 5 commits into
feature/exit-certificate-toolfrom
feat/exit-certificate-tool-version
Jun 30, 2026
Merged

feat(exit-certificate): execution traceability — startup banner and build version#1688
joanestebanr merged 5 commits into
feature/exit-certificate-toolfrom
feat/exit-certificate-tool-version

Conversation

@joanestebanr

@joanestebanr joanestebanr commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

🔄 Changes Summary

Goal: make every exit_certificate run traceable — at a glance you can tell which build, which config and which exact command produced a given output/log.

To achieve that:

  • run.go: logs an execution traceability banner line-by-line (same format as the rest of the logs) at the start of Run, reporting:
    • build version, git revision, git branch and build date,
    • Go version and OS/Arch,
    • the sha256 of the config file (so the exact parameters used can be verified),
    • the command-line arguments the tool was invoked with.
  • Makefile: the exit_certificate build target now passes -ldflags "all=$(LDFLAGS)", so Version, GitRev, GitBranch and BuildDate are injected into the binary (previously left at their defaults — without this the banner/--version would report placeholders).
  • cmd/main.go: --version prints the full build info (version, git revision, branch, build date, Go version, OS/Arch) via a custom cli.VersionPrinter calling aggkit.PrintVersion.

Output example:

2026-06-30T15:23:42.172+0200    INFO    exit_certificate/run.go:31      ╔═══════════════════════════════════════════╗   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:32      ║   Exit Certificate Tool — Traceability    ║   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:33      ╚═══════════════════════════════════════════╝   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:34      Version:      v0.10.0-rc1-72-gfc332f25  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:35      Git revision: fc332f25  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:36      Git branch:   feat/exit-certificate-tool-version        {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:37      Built:        Tue, 30 Jun 2026 15:16:17 +0200   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:38      Go version:   go1.25.7  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:39      OS/Arch:      linux/amd64       {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:40      Config file:  tmp/exit_certificate-kurtosis.json (sha256: e2f0a892dcb070f888037f0f88bf47232e7667f61e6449419fca9c92ba77ce01)     {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:41      Command line: ./target/exit_certificate -c tmp/exit_certificate-kurtosis.json   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}

⚠️ Breaking Changes

  • None.

📋 Config Updates

  • None.

✅ Testing

  • 🤖 Automatic: make build-exit_certificate builds with injected ldflags.
  • 🖱️ Manual: ./target/exit_certificate --version prints full build info; running any step logs the traceability banner (verified config sha256 + command line render correctly).

📝 Notes

  • log/log.go is shared infrastructure and is intentionally left untouched; the per-trace version field stays as-is for all binaries.

🤖 Generated with Claude Code

- Makefile: build exit_certificate with -ldflags "all=$(LDFLAGS)" so
  Version/GitRev/GitBranch/BuildDate are populated in the binary.
- cmd/main.go: --version prints full build info via aggkit.PrintVersion.
- run.go: log a per-line startup banner (version, branch, build date,
  config-file sha256 and command line) at the start of Run.
- log/log.go: drop the per-trace "version" field now that the banner
  reports it once at startup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown

Claude finished @joanestebanr's task in 1m 48s —— View job


PR Review Complete ✅

Reviewing PR #1688: feat(exit-certificate): inject build version and log startup banner


🚀 What's New

This PR adds build version injection via ldflags and implements a startup banner for the exit_certificate tool that displays build information, config file SHA256, and command-line arguments. The per-log-line version field has been removed from all aggkit binaries in favor of startup-time version reporting.

🐛 Bug Fixes

None.

📋 Config Updates

None.

⚠️ Breaking Changes

🔌 Log Format Change (All Binaries): The version field has been removed from log/log.go InitialFields, affecting all aggkit binaries. Log lines will no longer include a version field (though pid is retained). Version information is now reported once at startup instead of on every log line.


Review Feedback

✅ Overall Assessment

This is a clean, well-implemented PR that improves observability by adding build version tracking and startup banners. The changes are straightforward and follow existing patterns in the codebase.

Code Quality

🟢 Makefile Changes (Makefile:106)

The ldflags injection is correctly implemented and consistent with other binaries (aggkit at line 77, remove_ger at line 102).

$(GOENVVARS) go build -ldflags "all=$(LDFLAGS)" -o $(GOBIN)/exit_certificate ./tools/exit_certificate/cmd

Good: Follows the established pattern used by other binaries in the repo.

🟢 Custom Version Printer (tools/exit_certificate/cmd/main.go:13-15)

The implementation correctly uses cli.VersionPrinter to provide custom version output via aggkit.PrintVersion.

Good: Integrates cleanly with the urfave/cli framework and reuses the shared aggkit.PrintVersion function.

🟢 Startup Banner (tools/exit_certificate/run.go:28-47)

The banner implementation is well-structured and informative:

  • Displays full build metadata (version, git rev, branch, date, Go version, OS/arch)
  • Includes config file SHA256 for reproducibility/debugging
  • Logs command-line arguments for audit trails

Good practices observed:

  • Uses aggkit.GetVersion() for consistency
  • Gracefully handles config read errors with "n/a" fallback
  • Clear visual formatting with box-drawing characters
  • Called early in the Run function after logger initialization

🟡 Minor Enhancement Opportunity (tools/exit_certificate/run.go:32-34)

The config SHA256 calculation silently fails if the file can't be read. While the "n/a" fallback is fine for startup logging, consider whether this deserves a debug-level log:

configSHA := "n/a"
if data, err := os.ReadFile(configPath); err == nil {
    configSHA = fmt.Sprintf("%x", sha256.Sum256(data))
} else {
    log.Debugf("Unable to compute config SHA256: %v", err)  // Optional enhancement
}

Rationale: This would help operators understand why SHA256 shows "n/a" in scenarios where the config path is wrong or permissions are insufficient. Not required, but could improve debuggability.

🟢 Log Field Removal (log/log.go:87-89)

Removing the per-log version field is a good trade-off:

  • Pro: Reduces log verbosity and redundancy (version doesn't change during runtime)
  • Pro: Startup banner provides version info once at the beginning
  • Con: Log aggregation systems lose per-line version context

Assessment: This is acceptable since:

  1. The main aggkit binary already has conditional version logging (cmd/run.go:82-88)
  2. Version is typically static for a running process
  3. Operators can correlate logs with version via startup banner

However, this is a breaking change for any log parsing/aggregation systems that rely on the version field.

Security Considerations

✅ No Security Issues

  • Config file SHA256 is logged for verification but doesn't expose sensitive data
  • Command-line arguments are logged, which is standard practice (operators should avoid passing secrets via CLI)
  • No new attack vectors introduced

Performance Considerations

✅ Negligible Performance Impact

  • SHA256 computation happens once at startup
  • os.Args join is trivial
  • Startup banner adds ~8 log lines (insignificant)

Testing Observations

The PR mentions manual testing (./target/exit_certificate --version and startup banner verification). The existing test suite covers the tool's functionality, and this PR doesn't require new tests since:

  1. It's build infrastructure (ldflags injection)
  2. Startup logging is straightforward and hard to break
  3. Version printer reuses tested aggkit.PrintVersion

Recommendation: CI tests will validate the build succeeds with ldflags injection.


📝 Summary

Strengths:

  • ✅ Consistent with existing repo patterns (ldflags, version printing)
  • ✅ Improves observability with config SHA256 and command-line logging
  • ✅ Clean, readable implementation
  • ✅ No security concerns

Considerations:

  • 🟡 Breaking change: version field removed from all binary logs (documented in PR description)
  • 🟡 Optional: Could add debug log when config SHA256 calculation fails

Recommendation: ✅ Approve — This PR is ready to merge. The breaking change to log format is well-documented and acceptable. The implementation is solid and follows best practices.


…ity"

The banner now reports config sha256 and command line in addition to the
build version, so "Traceability" describes the block better than "Version".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 050ba8c612

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread log/log.go
@joanestebanr joanestebanr changed the title feat(exit-certificate): inject build version and log startup banner feat(exit-certificate): execution traceability — startup banner and build version Jun 30, 2026
@joanestebanr joanestebanr self-assigned this Jun 30, 2026
@joanestebanr joanestebanr added the exit_certificate_tool Tool to create a final exit certificate label Jun 30, 2026
log/log.go is shared infrastructure and should not be modified by this
tool. Keep the version field on every trace; the startup banner still
reports the full build version info separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@joanestebanr

Copy link
Copy Markdown
Collaborator Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves execution traceability for the exit_certificate tool by emitting startup build/config provenance in logs and ensuring build metadata is injected/printed consistently.

Changes:

  • Add a startup “traceability banner” to exit_certificate runs (build info, Go/OS, config sha256, argv).
  • Customize --version output to print full build information via aggkit.PrintVersion.
  • Ensure the exit_certificate Makefile target injects build metadata through -ldflags.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tools/exit_certificate/run.go Adds startup traceability banner logging build/runtime info, config hash, and command invocation.
tools/exit_certificate/cmd/main.go Overrides cli.VersionPrinter so --version prints full build details.
Makefile Updates exit_certificate build target to pass -ldflags "all=$(LDFLAGS)" for build metadata injection.

Comment thread tools/exit_certificate/run.go Outdated
Comment thread tools/exit_certificate/run.go Outdated
Comment thread tools/exit_certificate/run.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9ba61ff14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/exit_certificate/run.go Outdated
joanestebanr and others added 2 commits June 30, 2026 13:06
…argv

Addresses PR review feedback on the traceability banner:

- Config sha256 is now computed from the same on-disk bytes LoadConfig
  parses (returned by readRawConfig) and stored on Config.ConfigSHA256,
  instead of a second independent os.ReadFile in the banner. The banner
  is logged after a successful load, so the hash always matches the
  config actually used (no TOCTOU, no TOML→JSON mismatch).
- Command line is now shell-escaped (shellQuoteArgs): args containing
  spaces or special chars are single-quoted, so the logged command is
  faithfully replayable (e.g. --step 'sign, submit').
- Fixed the printStartupBanner doc comment that wrongly claimed it
  replaced the per-trace "version" field (that logger change was
  reverted; log/log.go is left untouched).

Adds TestShellQuote and TestLoadConfigSetsSHA256.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
golangci-lint (staticcheck QF1001) flagged the negated boolean in
shellQuote. Move the positive check into an isShellSafeRune helper and
negate at the call site.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@joanestebanr joanestebanr merged commit b546dad into feature/exit-certificate-tool Jun 30, 2026
24 of 26 checks passed
@joanestebanr joanestebanr deleted the feat/exit-certificate-tool-version branch June 30, 2026 13:24
joanestebanr added a commit that referenced this pull request Jun 30, 2026
…uild version (#1688)

## 🔄 Changes Summary

**Goal:** make every `exit_certificate` run **traceable** — at a glance
you can tell which build, which config and which exact command produced
a given output/log.

To achieve that:
- **run.go**: logs an *execution traceability* banner line-by-line (same
format as the rest of the logs) at the start of `Run`, reporting:
  - build version, git revision, git branch and build date,
  - Go version and OS/Arch,
- the **sha256 of the config file** (so the exact parameters used can be
verified),
  - the **command-line arguments** the tool was invoked with.
- **Makefile**: the `exit_certificate` build target now passes `-ldflags
"all=$(LDFLAGS)"`, so `Version`, `GitRev`, `GitBranch` and `BuildDate`
are injected into the binary (previously left at their defaults —
without this the banner/`--version` would report placeholders).
- **cmd/main.go**: `--version` prints the full build info (version, git
revision, branch, build date, Go version, OS/Arch) via a custom
`cli.VersionPrinter` calling `aggkit.PrintVersion`.

### Output example:
```
2026-06-30T15:23:42.172+0200    INFO    exit_certificate/run.go:31      ╔═══════════════════════════════════════════╗   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:32      ║   Exit Certificate Tool — Traceability    ║   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:33      ╚═══════════════════════════════════════════╝   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:34      Version:      v0.10.0-rc1-72-gfc332f25  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:35      Git revision: fc332f2  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:36      Git branch:   feat/exit-certificate-tool-version        {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:37      Built:        Tue, 30 Jun 2026 15:16:17 +0200   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:38      Go version:   go1.25.7  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:39      OS/Arch:      linux/amd64       {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:40      Config file:  tmp/exit_certificate-kurtosis.json (sha256: e2f0a892dcb070f888037f0f88bf47232e7667f61e6449419fca9c92ba77ce01)     {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:41      Command line: ./target/exit_certificate -c tmp/exit_certificate-kurtosis.json   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
```

## ⚠️ Breaking Changes
- None.

## 📋 Config Updates
- None.

## ✅ Testing
- 🤖 **Automatic**: `make build-exit_certificate` builds with injected
ldflags.
- 🖱️ **Manual**: `./target/exit_certificate --version` prints full build
info; running any step logs the traceability banner (verified config
sha256 + command line render correctly).

## 📝 Notes
- `log/log.go` is shared infrastructure and is intentionally left
untouched; the per-trace `version` field stays as-is for all binaries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
joanestebanr added a commit that referenced this pull request Jul 10, 2026
…uild version (#1688)

## 🔄 Changes Summary

**Goal:** make every `exit_certificate` run **traceable** — at a glance
you can tell which build, which config and which exact command produced
a given output/log.

To achieve that:
- **run.go**: logs an *execution traceability* banner line-by-line (same
format as the rest of the logs) at the start of `Run`, reporting:
  - build version, git revision, git branch and build date,
  - Go version and OS/Arch,
- the **sha256 of the config file** (so the exact parameters used can be
verified),
  - the **command-line arguments** the tool was invoked with.
- **Makefile**: the `exit_certificate` build target now passes `-ldflags
"all=$(LDFLAGS)"`, so `Version`, `GitRev`, `GitBranch` and `BuildDate`
are injected into the binary (previously left at their defaults —
without this the banner/`--version` would report placeholders).
- **cmd/main.go**: `--version` prints the full build info (version, git
revision, branch, build date, Go version, OS/Arch) via a custom
`cli.VersionPrinter` calling `aggkit.PrintVersion`.

### Output example:
```
2026-06-30T15:23:42.172+0200    INFO    exit_certificate/run.go:31      ╔═══════════════════════════════════════════╗   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:32      ║   Exit Certificate Tool — Traceability    ║   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:33      ╚═══════════════════════════════════════════╝   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:34      Version:      v0.10.0-rc1-72-gfc332f25  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:35      Git revision: fc332f2  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:36      Git branch:   feat/exit-certificate-tool-version        {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:37      Built:        Tue, 30 Jun 2026 15:16:17 +0200   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:38      Go version:   go1.25.7  {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:39      OS/Arch:      linux/amd64       {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:40      Config file:  tmp/exit_certificate-kurtosis.json (sha256: e2f0a892dcb070f888037f0f88bf47232e7667f61e6449419fca9c92ba77ce01)     {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
2026-06-30T15:23:42.173+0200    INFO    exit_certificate/run.go:41      Command line: ./target/exit_certificate -c tmp/exit_certificate-kurtosis.json   {"pid": 560596, "version": "v0.10.0-rc1-72-gfc332f25"}
```

## ⚠️ Breaking Changes
- None.

## 📋 Config Updates
- None.

## ✅ Testing
- 🤖 **Automatic**: `make build-exit_certificate` builds with injected
ldflags.
- 🖱️ **Manual**: `./target/exit_certificate --version` prints full build
info; running any step logs the traceability banner (verified config
sha256 + command line render correctly).

## 📝 Notes
- `log/log.go` is shared infrastructure and is intentionally left
untouched; the per-trace `version` field stays as-is for all binaries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

exit_certificate_tool Tool to create a final exit certificate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants