Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
89633d1
fix: close audit-critical safety and reliability gaps
aXL333 Jul 21, 2026
866af36
fix: close round-two P0 sibling bypasses
aXL333 Jul 22, 2026
40d2ff1
feat: add opt-in payment card vault access
aXL333 Jul 23, 2026
915fdd3
build: harden maintained installer path
aXL333 Jul 23, 2026
7770ec3
ci: verify the Inno compiler banner
aXL333 Jul 23, 2026
970782e
fix: close round-three P0 invariant classes
aXL333 Jul 26, 2026
1024f0f
feat: complete TraceBrake hardening and platform updates
aXL333 Aug 13, 2026
b1c5dbd
docs: publish TraceBrake product overview
aXL333 Aug 13, 2026
5b72e2f
docs: make product overview harness-neutral
aXL333 Aug 13, 2026
0f6853c
feat: integrate agent hardening and harness process control
aXL333 Aug 26, 2026
fe0e255
docs: live review of the running TraceBrake instance (2026-09-04)
aXL333 Sep 4, 2026
37b2b2c
docs: adversarial audit of the branch and running instance (2026-09-05)
aXL333 Sep 4, 2026
c7c385e
build: make the test runner actually run, and pin CI to global.json
aXL333 Sep 4, 2026
d65e8a1
docs: plan for leaving Bitdefender and bridging to Microsoft Defender
aXL333 Sep 4, 2026
739b2c6
test: add the antivirus false-positive corpus and its evidence pack
aXL333 Sep 4, 2026
884bc6f
docs: whitepaper on harness output ambiguity and automation provenance
aXL333 Sep 4, 2026
344fcf9
docs: name the class automation provenance, and position it against MXC
aXL333 Sep 4, 2026
c970d45
spec: the Automation Declaration format v1.0, with normative conformance
aXL333 Sep 4, 2026
e036eb3
spec: conformance test vectors for the Automation Declaration format
aXL333 Sep 4, 2026
275d85c
chore: repoint operational paths at T: after the working-folder migra…
aXL333 Sep 5, 2026
c97b64c
fix: use the current repository name for provenance verification
aXL333 Sep 5, 2026
c0eb423
Lead alert popups with triggering evidence
aXL333 Sep 5, 2026
72209c7
Add shadow telemetry for hang learning
aXL333 Sep 5, 2026
57465c3
Specify hang-likelihood beta gates
aXL333 Sep 5, 2026
c9ffe3e
docs: the handbrake argument, TraceBrake as the second brake for codi…
aXL333 Sep 5, 2026
f09569e
spec: the Agent Handbrake v1.0, with a plain-language companion
aXL333 Sep 5, 2026
4b8cc5a
test: privacy leak count across every redactor egress channel, as one…
aXL333 Sep 5, 2026
c5dc5af
docs: the "it's all about the brakes" logo, dark-mode native
aXL333 Sep 5, 2026
feb7687
docs: roll the handbrake thesis out to the README, the site and the s…
aXL333 Sep 5, 2026
927c57d
docs: keep the scenario deck note out of the eyebrow so it survives m…
aXL333 Sep 5, 2026
877a47f
docs: amber for the brand, red reserved for the stop
aXL333 Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
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/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Security vulnerability
url: https://github.com/aXL333/Foreman/security/advisories/new
url: https://github.com/aXL333/TraceBrake/security/advisories/new
about: Please report suspected vulnerabilities privately.
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
4 changes: 2 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Summary

-
-

## Verification

- [ ] `dotnet build .\Foreman.slnx -c Release`
- [ ] `dotnet test .\Foreman.slnx -c Release`
- [ ] `powershell -NoProfile -File .\scripts\Invoke-DotNetTests.ps1 -Configuration Release -NoBuild`

## Safety / Privacy Notes

Expand Down
20 changes: 16 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@ jobs:
name: Build & test
runs-on: windows-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- name: Set up .NET 10
uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
with:
dotnet-version: '10.0.x'
# global.json is the single source of truth for the SDK band. Installing
# '10.0.x' would fetch a newer feature band that global.json's
# rollForward: latestPatch then refuses, failing the run on SDK release day.
global-json-file: global.json

- name: Restore
run: dotnet restore Foreman.slnx
Expand All @@ -30,11 +33,20 @@ jobs:
node --check $file.FullName
if ($LASTEXITCODE -ne 0) { throw "JavaScript syntax check failed: $($file.FullName)" }
}
node --test extension-liveweave/tests/project-model.test.mjs
$testPaths = @(Get-ChildItem extension-liveweave/tests -Recurse -File -Filter '*.test.mjs' |
Sort-Object FullName |
ForEach-Object { $_.FullName })
if ($testPaths.Count -eq 0) { throw "No LiveWeave tests were discovered." }
& node --test @testPaths
if ($LASTEXITCODE -ne 0) { throw "LiveWeave tests failed." }
node --test scripts/Test-ExtensionCuPanic.mjs
if ($LASTEXITCODE -ne 0) { throw "Browser CU panic/lease contract tests failed." }
node --test scripts/Test-ExtensionVaultPolicy.mjs
if ($LASTEXITCODE -ne 0) { throw "Browser vault policy bypass tests failed." }

- name: Build
run: dotnet build Foreman.slnx -c Release --no-restore

- name: Test
run: dotnet test Foreman.slnx -c Release --no-build --verbosity normal
shell: pwsh
run: ./scripts/Invoke-DotNetTests.ps1 -Configuration Release -NoBuild
130 changes: 114 additions & 16 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,14 +29,35 @@ 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
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # 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
with:
dotnet-version: '10.0.x'
# global.json is the single source of truth for the SDK band. See ci.yml.
global-json-file: global.json

- name: Compute version
id: ver
Expand All @@ -40,13 +66,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 All @@ -65,11 +97,20 @@ jobs:
node --check $file.FullName
if ($LASTEXITCODE -ne 0) { throw "JavaScript syntax check failed: $($file.FullName)" }
}
node --test extension-liveweave/tests/project-model.test.mjs
$testPaths = @(Get-ChildItem extension-liveweave/tests -Recurse -File -Filter '*.test.mjs' |
Sort-Object FullName |
ForEach-Object { $_.FullName })
if ($testPaths.Count -eq 0) { throw "No LiveWeave tests were discovered." }
& node --test @testPaths
if ($LASTEXITCODE -ne 0) { throw "LiveWeave tests failed." }
node --test scripts/Test-ExtensionCuPanic.mjs
if ($LASTEXITCODE -ne 0) { throw "Browser CU panic/lease contract tests failed." }
node --test scripts/Test-ExtensionVaultPolicy.mjs
if ($LASTEXITCODE -ne 0) { throw "Browser vault policy bypass tests failed." }

- name: Test release commit
run: dotnet test Foreman.slnx -c Release --verbosity minimal
shell: pwsh
run: ./scripts/Invoke-DotNetTests.ps1 -Configuration Release

- name: Publish self-contained single-file
env:
Expand Down Expand Up @@ -103,7 +144,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 +194,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 All @@ -167,15 +218,15 @@ jobs:
- name: Upload unsigned app payload
id: upload-app
if: ${{ env.SIGN == 'true' }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: foreman-app-unsigned
path: publish
retention-days: 1

- name: Sign app payload (SignPath)
if: ${{ env.SIGN == 'true' }}
uses: signpath/github-action-submit-signing-request@b9d91eadd323de506c0c81cf0c7fe7438f3360fd # v2
uses: signpath/github-action-submit-signing-request@c92b958760219087e01f8d67a1669ed57afe2627 # v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORGANIZATION_ID }}'
Expand All @@ -196,29 +247,40 @@ 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
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: foreman-installer-unsigned
name: tracebrake-installer-unsigned
path: installer/Output/*.exe
retention-days: 1

- name: Sign installer (SignPath)
if: ${{ env.SIGN == 'true' }}
uses: signpath/github-action-submit-signing-request@b9d91eadd323de506c0c81cf0c7fe7438f3360fd # v2
uses: signpath/github-action-submit-signing-request@c92b958760219087e01f8d67a1669ed57afe2627 # v2
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '${{ vars.SIGNPATH_ORGANIZATION_ID }}'
Expand Down Expand Up @@ -251,28 +313,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
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/TraceBrake/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 ${{ github.repository }}`.'
'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
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4
if: ${{ github.event_name == 'push' || inputs.publish_release }}
uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[Oo]ut/
publish/
artifacts/
.artifacts/

## Visual Studio / Rider / VS Code
.vs/
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
Loading
Loading