Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*.cmd text eol=crlf
*.bat text eol=crlf

# Unix shell scripts must retain LF so their shebang works on Linux.
*.sh text eol=lf

# Treat known binary assets as binary.
*.ico binary
*.png binary
Expand Down
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Bug report
description: Report a Foreman Agent Safety defect or crash.
description: Report a TraceBrake defect or crash.
title: "[Bug]: "
labels: ["bug"]
body:
Expand All @@ -14,9 +14,9 @@ body:
id: steps
attributes:
label: Steps to reproduce
description: Include the exact Foreman Agent Safety version/commit and what you were doing.
description: Include the exact TraceBrake version/commit and what you were doing.
placeholder: |
1. Launch Foreman Agent Safety...
1. Launch TraceBrake...
2. Connect Codex...
3. Open...
validations:
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/detection_tuning.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ body:
- type: textarea
id: why
attributes:
label: Why should Foreman Agent Safety treat this differently?
label: Why should TraceBrake treat this differently?
validations:
required: true
- type: input
Expand Down
102 changes: 95 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
version:
description: 'Version to build (without leading v), e.g. 0.1.0'
required: true
publish_release:
description: 'Publish from the selected annotated mainline v* tag; leave off for a private candidate'
required: true
type: boolean
default: false

permissions:
contents: write
Expand All @@ -24,9 +29,29 @@ jobs:
# repository *Variable* (Settings -> Secrets and variables -> Actions -> Variables). Until then the
# release builds and ships UNSIGNED with SHA-256 checksums, exactly as before — nothing breaks.
# One-time setup (free OSS signing via SignPath Foundation): see docs/release-checklist.md.
SIGN: ${{ vars.SIGNPATH_ORGANIZATION_ID != '' }}
SIGN: ${{ vars.SIGNPATH_ORGANIZATION_ID != '' && (github.event_name == 'push' || inputs.publish_release) }}
# Deliberately fail closed if the runner image changes its compiler. Update this only after reviewing
# Inno Setup's release and the Chocolatey package checksums.
INNO_SETUP_VERSION: '6.7.1'
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
fetch-depth: 0

- name: Test release-source guard bypasses
shell: pwsh
run: pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleaseSourceBypasses.ps1

- name: Verify publish source is an annotated mainline tag
if: ${{ github.event_name == 'push' || inputs.publish_release }}
shell: pwsh
env:
RELEASE_SHA: ${{ github.sha }}
RELEASE_REF: ${{ github.ref }}
run: |
git fetch origin main:refs/remotes/origin/main --no-tags
pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Assert-ReleaseSource.ps1 `
-CommitSha $env:RELEASE_SHA -MainRef origin/main -TagRef $env:RELEASE_REF -RequireAnnotatedTag

- name: Set up .NET 10
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
Expand All @@ -40,13 +65,19 @@ jobs:
EVENT_NAME: ${{ github.event_name }}
INPUT_VERSION: ${{ github.event.inputs.version }}
REF_NAME: ${{ github.ref_name }}
RELEASE_REF: ${{ github.ref }}
PUBLISH_RELEASE: ${{ github.event_name == 'push' || inputs.publish_release }}
run: |
$raw = if ($env:EVENT_NAME -eq 'workflow_dispatch') { $env:INPUT_VERSION } else { $env:REF_NAME }
$v = $raw.Trim()
if ($v.StartsWith('v', [StringComparison]::OrdinalIgnoreCase)) { $v = $v.Substring(1) }
if ($v -notmatch '^\d+\.\d+\.\d+(?:-[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?(?:\+[0-9A-Za-z]+(?:[.-][0-9A-Za-z]+)*)?$') {
throw "Release version '$v' is not valid SemVer."
}
if ($env:PUBLISH_RELEASE -eq 'true' -and
-not $env:RELEASE_REF.Equals("refs/tags/v$v", [StringComparison]::OrdinalIgnoreCase)) {
throw "Published version '$v' must exactly match selected tag '$($env:RELEASE_REF)'."
}
"version=$v" >> $env:GITHUB_OUTPUT
"is_prerelease=$(if ($v -match '^\d+\.\d+\.\d+-') { 'true' } else { 'false' })" >> $env:GITHUB_OUTPUT

Expand Down Expand Up @@ -103,7 +134,7 @@ jobs:
# target only stages it for *builds* (bin\), and the single-file app can't share its bundled runtime — so
# publish it separately, self-contained, into the guardian\ subfolder the app launches from
# (<app>\guardian\Foreman.Guardian.exe). Without this step the "Enable hardened guardian" action is
# unreachable in released builds (the install path returns "Reinstall Foreman Agent Safety").
# unreachable in released builds (the install path returns "Reinstall TraceBrake").
# The SignPath app-payload configuration must include every executable published here; the signed-payload
# verification below enforces that external configuration before the installer is built.
- name: Publish hardened guardian (self-contained)
Expand Down Expand Up @@ -153,12 +184,22 @@ jobs:
Remove-Item publish/Foreman.CuSidecar.* -ErrorAction SilentlyContinue
Remove-Item publish/Foreman.CuPilot.* -ErrorAction SilentlyContinue

- name: Package browser extensions
shell: pwsh
run: pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Copy-ReleaseExtensions.ps1 -PayloadPath publish

- name: Verify release payload layout and version
shell: pwsh
env:
RELEASE_VERSION: ${{ steps.ver.outputs.version }}
run: pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleasePayload.ps1 -PayloadPath publish -ExpectedVersion $env:RELEASE_VERSION

- name: Exercise release-payload sibling bypasses
shell: pwsh
env:
RELEASE_VERSION: ${{ steps.ver.outputs.version }}
run: pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleasePayloadBypasses.ps1 -PayloadPath publish -ExpectedVersion $env:RELEASE_VERSION

# --- Sign every executable in the app payload BEFORE building the installer, so the installer embeds
# already-signed binaries. SignPath signs only the files named in the "app" artifact configuration
# and passes everything else through untouched. The verification step below fails closed if that
Expand Down Expand Up @@ -196,23 +237,34 @@ jobs:
shell: pwsh
env:
RELEASE_VERSION: ${{ steps.ver.outputs.version }}
run: pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleasePayload.ps1 -PayloadPath publish -ExpectedVersion $env:RELEASE_VERSION -RequireValidSignatures
run: |
pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleasePayload.ps1 -PayloadPath publish -ExpectedVersion $env:RELEASE_VERSION -RequireValidSignatures -SkipManifestHashValidation
pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Update-ReleasePayloadManifest.ps1 -PayloadPath publish
pwsh -NoProfile -ExecutionPolicy Bypass -File ./scripts/Test-ReleasePayload.ps1 -PayloadPath publish -ExpectedVersion $env:RELEASE_VERSION -RequireValidSignatures

- name: Build installer (Inno Setup)
shell: pwsh
env:
RELEASE_VERSION: ${{ steps.ver.outputs.version }}
run: |
choco install innosetup --no-progress -y
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "/DMyAppVersion=$env:RELEASE_VERSION" installer/foreman.iss
choco install innosetup --version="$env:INNO_SETUP_VERSION" --require-checksums --no-progress -y
$iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
$compilerOutput = @(& $iscc "/DMyAppVersion=$env:RELEASE_VERSION" installer/tracebrake.iss 2>&1)
$compilerExit = $LASTEXITCODE
$compilerOutput | Write-Host
if ($compilerExit -ne 0) { throw "Inno Setup failed with exit code $compilerExit." }
$expectedBanner = "Compiler engine version: Inno Setup $env:INNO_SETUP_VERSION"
if (($compilerOutput -join "`n") -notmatch [Regex]::Escape($expectedBanner)) {
throw "The installer was not compiled by the pinned engine '$expectedBanner'."
}

# --- Sign the installer itself LAST, after it is built from the already-signed payload. ---
- name: Upload unsigned installer
id: upload-installer
if: ${{ env.SIGN == 'true' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: foreman-installer-unsigned
name: tracebrake-installer-unsigned
path: installer/Output/*.exe
retention-days: 1

Expand Down Expand Up @@ -251,28 +303,64 @@ jobs:
ForEach-Object { "$($_.Hash.ToLowerInvariant()) $(Split-Path $_.Path -Leaf)" } |
Set-Content -Encoding ASCII installer/Output/checksums-sha256.txt

- name: Upload unpublished release candidate
if: ${{ github.event_name == 'workflow_dispatch' && !inputs.publish_release }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: tracebrake-installer-candidate-${{ steps.ver.outputs.version }}
path: |
installer/Output/*.exe
installer/Output/checksums-sha256.txt
retention-days: 7
if-no-files-found: error

- name: Prepare release disclosure
id: release-disclosure
shell: pwsh
run: |
$signing = if ('${{ env.SIGN }}' -eq 'true') {
'**Signing:** Authenticode signed through SignPath Foundation.'
} else {
'**Signing:** UNSIGNED alpha build. Verify the attached SHA-256 checksum and GitHub provenance before running it. The optional LocalSystem Guardian fails closed in unsigned Release builds.'
}
@(
'body<<TRACEBRAKE_RELEASE_BODY'
'> **OpenAI Build Week record:** the immutable submission snapshot is [`v0.1.0-alpha3`](https://github.com/aXL333/Foreman/releases/tag/v0.1.0-alpha3). Later releases are maintenance/development builds and are not claimed as submission-period work.'
''
$signing
''
'**Browser extensions:** both unpacked MV3 extensions are included under the installed `extensions` folder. See the README for Chrome loading and pairing steps.'
''
'Verify provenance with `gh attestation verify <installer.exe> --repo aXL333/Foreman`.'
'TRACEBRAKE_RELEASE_BODY'
) >> $env:GITHUB_OUTPUT

# Supply-chain provenance: a keyless Sigstore attestation binding each shipped artifact to THIS repo,
# commit, and workflow run. Independent of code signing (runs whether SignPath is configured or not), and
# runs AFTER signing so the attested digests are the final, signed bytes. GitHub stores the attestation, so
# nothing extra is attached to the Release; anyone can verify a download with:
# gh attestation verify <file> --repo ${{ github.repository }}
- name: Attest build provenance
if: ${{ github.event_name == 'push' || inputs.publish_release }}
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4
with:
subject-path: |
installer/Output/*.exe
publish/Foreman.exe
publish/TraceBrake.exe
publish/sidecar/Foreman.EtwSidecar.exe
publish/guardian/Foreman.Guardian.exe
publish/cu-sidecar/Foreman.CuSidecar.exe
publish/cu-pilot/Foreman.CuPilot.exe
publish/release-payload.manifest.json

- name: Attach installer to GitHub Release
if: ${{ github.event_name == 'push' || inputs.publish_release }}
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
tag_name: v${{ steps.ver.outputs.version }}
target_commitish: ${{ github.sha }}
prerelease: ${{ steps.ver.outputs.is_prerelease == 'true' }}
body: ${{ steps.release-disclosure.outputs.body }}
files: |
installer/Output/*.exe
installer/Output/checksums-sha256.txt
Expand Down
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Code of Conduct

Foreman Agent Safety is a safety tool. Project discussion should be practical, respectful, and focused on making agent work more visible and accountable.
TraceBrake is a safety tool. Project discussion should be practical, respectful, and focused on making agent work more visible and accountable.

## Expected Behavior

Expand Down
14 changes: 7 additions & 7 deletions CODE_SIGNING.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Code Signing

This document describes how Foreman Agent Safety release binaries are (or will be) code-signed, and how
This document describes how TraceBrake release binaries are (or will be) code-signed, and how
you can verify a download. It exists both for transparency to users and as a reference for the
[SignPath Foundation](https://signpath.org/) open-source signing program.

## Current status

Foreman Agent Safety is in **alpha**. Until code signing is approved and live, release artifacts are
TraceBrake is in **alpha**. Until code signing is approved and live, release artifacts are
shipped **unsigned**, accompanied by **SHA-256 checksums** (`checksums-sha256.txt`) so you can verify
integrity. Release notes state clearly whether a given build is signed.

Expand All @@ -27,18 +27,18 @@ for qualifying open-source projects. Key properties of this model:

Signing is nested so the installer ships already-signed binaries:

1. Every executable in the app payload is signed first: **`Foreman.exe`**,
1. Every executable in the app payload is signed first: **`TraceBrake.exe`**,
**`sidecar/Foreman.EtwSidecar.exe`**, **`guardian/Foreman.Guardian.exe`**,
**`cu-sidecar/Foreman.CuSidecar.exe`**, and **`cu-pilot/Foreman.CuPilot.exe`**.
2. The **Inno Setup installer** (`Foreman-Agent-Safety-Setup-*.exe`) is built from those signed binaries and
2. The **Inno Setup installer** (`TraceBrake-Setup-*.exe`) is built from those signed binaries and
then signed last.
3. SHA-256 checksums are generated over the final, signed installer.

All signatures are **timestamped**, so they remain valid after the (short-lived) certificate expires.

The optional Guardian uses the same verified Authenticode identity as its long-lived client policy. A signed
installation pins the publisher, so later releases signed by that publisher continue to work without a binary hash
re-pin. Unsigned development installations instead pin the exact Foreman.exe path and SHA-256 and are explicitly
re-pin. Unsigned development installations instead pin the exact TraceBrake.exe path and SHA-256 and are explicitly
reported as development-only protection; re-enabling the Guardian after signing upgrades that policy.

## Attribution
Expand All @@ -55,15 +55,15 @@ This attribution appears in the release notes and the application's About inform
**Checksum (always available):**

```powershell
Get-FileHash .\Foreman-Agent-Safety-Setup-<version>.exe -Algorithm SHA256
Get-FileHash .\TraceBrake-Setup-<version>.exe -Algorithm SHA256
# compare against checksums-sha256.txt attached to the release
```

**Authenticode signature (once signed):** right-click the installer → *Properties* → *Digital Signatures*,
or:

```powershell
Get-AuthenticodeSignature .\Foreman-Agent-Safety-Setup-<version>.exe | Format-List
Get-AuthenticodeSignature .\TraceBrake-Setup-<version>.exe | Format-List
# Expect: Status = Valid, signed by "SignPath Foundation"
```

Expand Down
14 changes: 7 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Contributing to Foreman Agent Safety
# Contributing to TraceBrake

Foreman Agent Safety is alpha software for local AI-agent safety oversight. Bug reports, false-positive tuning, docs polish, and small focused pull requests are welcome.
TraceBrake is alpha software for local AI-agent safety oversight. Bug reports, false-positive tuning, docs polish, and small focused pull requests are welcome.

## Prerequisites

- .NET 10 SDK preview. CI uses the preview channel.
- Windows 10/11 x64 for the full tray app and monitor.
- A working `dotnet` on `PATH`.

Foreman Agent Safety runs at normal user integrity by default. No admin/UAC prompt is required except for the optional elevated network sidecar.
TraceBrake runs at normal user integrity by default. No admin/UAC prompt is required except for the optional elevated network sidecar.

## Build And Test

Expand Down Expand Up @@ -55,14 +55,14 @@ Avoid putting working offensive one-liners in issue prose, PR titles, or docs. T

## Product And Design Standards

Foreman Agent Safety is a safety tool, not a novelty tray utility. Public-facing changes should keep that tone:
TraceBrake is a safety tool, not a novelty tray utility. Public-facing changes should keep that tone:

- Prefer "safety monitor", "oversight", "audit", "review", and "accountability" over vague cleanup language.
- Be precise about trust boundaries. Foreman Agent Safety is not a sandbox and should not be described as one.
- Be precise about trust boundaries. TraceBrake is not a sandbox and should not be described as one.
- Treat false positives as product bugs worth tuning.
- Keep UI copy calm and direct. Avoid theatrical destructive labels.
- Preserve privacy: do not include tokens, private paths, project names, or command output in screenshots or examples.
- New artwork must be original, generated specifically for Foreman Agent Safety, or otherwise GPL-compatible.
- New artwork must be original, generated specifically for TraceBrake, or otherwise GPL-compatible.

## Pull Requests

Expand All @@ -84,4 +84,4 @@ Before publishing binaries, use `docs/release-checklist.md`.

## License

Foreman Agent Safety is licensed under GPL-3.0-or-later. By contributing, you agree that your contributions are licensed under the same terms.
TraceBrake is licensed under GPL-3.0-or-later. By contributing, you agree that your contributions are licensed under the same terms.
8 changes: 4 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<Project>
<PropertyGroup>
<Product>Foreman Agent Safety</Product>
<Title>Foreman Agent Safety</Title>
<Product>TraceBrake</Product>
<Title>TraceBrake</Title>
<Company>aXL333</Company>
<Authors>aXL333</Authors>
<Version>0.1.0</Version>
<Description>Foreman Agent Safety is a Windows safety monitor for AI coding agents: watch risky commands, stuck runs, MCP changes, and cross-agent audit workflows.</Description>
<Description>TraceBrake is a Windows safety broker and black box for AI agents: watch risky actions, broker computer use, preserve evidence, and keep the operator in control.</Description>
<Copyright>Copyright (c) 2026 aXL333</Copyright>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<RepositoryUrl>https://github.com/aXL333/Foreman</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/aXL333/Foreman</PackageProjectUrl>
<PackageProjectUrl>https://tracebrake.com</PackageProjectUrl>
<PackageTags>ai;agent-safety;mcp;windows;monitoring;security</PackageTags>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
Loading