Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
264fe8b
Consolidate BEAR assets under .bear package root
rore Feb 20, 2026
f88bde1
Track vendored CLI under .bear/tools package root
rore Feb 20, 2026
7fafb9d
Refresh vendored BEAR CLI from latest bear-cli build
rore Feb 20, 2026
75e0990
Sync BEAR agent package from bear-cli
rore Feb 20, 2026
e307c92
Sync BEAR package rules and refresh vendored CLI
rore Feb 20, 2026
ca62c8f
Add project-level safety guardrails for cleanup commands
rore Feb 20, 2026
da388df
Update BEAR documentation to reflect version changes and clarify gree…
rore Feb 21, 2026
842f0e3
Update BEAR CLI and kernel binaries to latest versions
rore Feb 21, 2026
fb0fd12
Update BEAR agent documentation and verify implementation paths for c…
rore Feb 21, 2026
854eb97
Update BEAR agent and workflow documentation to clarify implementatio…
rore Feb 21, 2026
5b8f542
Ignore BEAR Gradle cache directory
rore Feb 21, 2026
dc2e301
Enhance troubleshooting guidance in WORKFLOW.md and update BEAR CLI a…
rore Feb 21, 2026
808bf37
Update BEAR agent documentation and examples for clarity; enhance sem…
rore Feb 22, 2026
ca9fce2
Refine BEAR agent and workflow documentation for clarity on tooling/l…
rore Feb 22, 2026
2741721
Clarify handling of blocked markers in BEAR documentation; update adv…
rore Feb 22, 2026
f355c28
Reframe wallet demo spec to BEAR-safe scope
rore Feb 22, 2026
3f09cf7
Enhance BEAR agent and workflow documentation with strict hygiene pol…
rore Feb 22, 2026
5e91aaf
Refine BEAR documentation to clarify governed binding rules and gener…
rore Feb 22, 2026
1fbcbef
Enhance BEAR documentation with new compile command options and clari…
rore Feb 23, 2026
dbe1af9
Update BEAR agent and workflow documentation to enforce governed root…
rore Feb 23, 2026
4b698b2
Refine BEAR documentation to clarify governed source root rules and e…
rore Feb 23, 2026
6b9bf78
Update BEAR agent and workflow documentation to clarify containment s…
rore Feb 25, 2026
f24ec10
Update BEAR CLI and kernel binaries to latest versions.
rore Feb 25, 2026
781bf46
Refactor BEAR documentation structure and content
rore Feb 25, 2026
f638689
Enhance BEAR documentation: clarify bootstrap guardrails, contracts d…
rore Feb 25, 2026
85681f4
Enhance BEAR documentation: add conflict definitions, escalation rule…
rore Feb 25, 2026
c909f8a
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Feb 25, 2026
f47c237
Enhance BEAR documentation: update BOOTSTRAP, REPORTING, and TROUBLES…
rore Feb 26, 2026
762a2fd
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, and TROUBLES…
rore Feb 26, 2026
ee488fb
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Feb 26, 2026
76609cb
Enhance BEAR documentation: update BOOTSTRAP, REPORTING, and TROUBLES…
rore Mar 1, 2026
d4f6388
Enhance BEAR documentation: add policies for handling policy/tool ano…
rore Mar 1, 2026
08f335e
Update BEAR CLI and kernel binaries to latest versions
rore Mar 1, 2026
c3c0310
Enhance BEAR documentation: add agent package parity precondition, gr…
rore Mar 2, 2026
f628b24
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Mar 2, 2026
341f0bd
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Mar 2, 2026
38cfb69
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Mar 3, 2026
23dc38e
Enhance BEAR documentation: update BOOTSTRAP, REPORTING, and TROUBLES…
rore Mar 3, 2026
bdcba09
Refactor documentation: update SPEC.md to define a minimal bank-accou…
rore Mar 3, 2026
8fa02af
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, TROUBLESHOOT…
rore Mar 4, 2026
426f24e
Update CLI and kernel binaries to latest versions for improved perfor…
rore Mar 4, 2026
35c479f
Enhance BEAR documentation: update BOOTSTRAP, CONTRACTS, REPORTING, a…
rore Mar 4, 2026
c685643
Enhance BOOTSTRAP and REPORTING documentation: clarify decomposition …
rore Mar 5, 2026
f52dc79
Update BOOTSTRAP.md: enhance implementation preconditions and stop co…
rore Mar 5, 2026
8450257
Update BOOTSTRAP.md: refine agent command execution guidelines and cl…
rore Mar 5, 2026
97911fd
Update BOOTSTRAP and REPORTING documentation: refine stop conditions …
rore Mar 5, 2026
c6ebdd8
Update binary files for bear-cli and kernel: refresh app and kernel J…
rore Mar 5, 2026
c9c4316
Update binary files for bear-cli and kernel: refresh JARs for improve…
rore Mar 5, 2026
222f8cc
Update TROUBLESHOOTING.md and refresh binary files: add missing index…
rore Mar 6, 2026
390b1aa
Implement greenfield BEAR demo baseline
rore Mar 6, 2026
8b25a3d
Sync packaged BEAR runtime and agent bundle
rore Mar 7, 2026
ccc35ff
Refresh greenfield BEAR output baseline
rore Mar 7, 2026
d1721ba
Move baseline product spec into spec folder
rore Mar 7, 2026
2f99938
Remove stale pre-restart greenfield files
rore Mar 7, 2026
468f492
Document baseline branch base
rore Mar 7, 2026
95650ef
Read README before choosing pr-check base
rore Mar 7, 2026
370331b
Adopt packaged BEAR CI observe workflow
rore Mar 7, 2026
7b34a5b
Merge main into baseline/greenfield-output
rore Mar 7, 2026
1d51779
Mark packaged shell launchers executable
rore Mar 7, 2026
84b8baf
Sync packaged BEAR runtime and agent bundle
rore Mar 7, 2026
c65be36
Add BEAR PR summary comment
rore Mar 8, 2026
a4ff853
Sync packaged BEAR runtime and agent bundle
rore Mar 8, 2026
be21d96
Compile BEAR artifacts before CI gates
rore Mar 8, 2026
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
11 changes: 6 additions & 5 deletions .bear/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ Files:
- `baseline-allow.json`: exact-match allow file for approved boundary expansion

Canonical outputs:
- console summary lines for `MODE`, `CHECK`, and `PR-CHECK`
- console summary starts with `BEAR Decision: PASS|REVIEW REQUIRED|FAIL|ALLOWED EXPANSION`, followed by the structured `MODE=... DECISION=... BASE=...` line and the `CHECK` / `PR-CHECK` lines
- optional `ALLOW_ENTRY_CANDIDATE` block on enforce-mode boundary expansion
- report artifact at `build/bear/ci/bear-ci-report.json`
- markdown summary at `build/bear/ci/bear-ci-summary.md`
- markdown summary at `build/bear/ci/bear-ci-summary.md`, using the same `BEAR Decision: ...` header near the top
- when `GITHUB_STEP_SUMMARY` is set, the wrapper appends the exact markdown summary content there

Canonical usage:

PowerShell:

```powershell
.\.bear\ci\bear-gates.ps1 --mode enforce
.\.bear\ci\bear-gates.ps1 --mode observe
```

bash:

```sh
./.bear/ci/bear-gates.sh --mode enforce
./.bear/ci/bear-gates.sh --mode observe
```

Options:
Expand All @@ -35,11 +35,12 @@ Options:

Rules:
- wrappers run `check --all` first, then `pr-check --all` when allowed by the pinned decision matrix
- in `observe`, clean runs report `pass`, boundary expansion reports `review-required`, and blocking repo problems report `fail`
- `baseline-allow.json` is consulted only for `pr-check` boundary expansion in `enforce`
- the allow-entry candidate and markdown boundary section use the full boundary-expanding delta set from `pr-check --all` repo-level plus block-level results
- report and decision output must be reproducible from BEAR raw outputs plus wrapper mode and allow-file state

Runtime note:
- on bash-based GitHub runners, `bear-gates.sh` requires `pwsh`
- if `pwsh` is unavailable, `bear-gates.sh` fails deterministically and tells the operator to install PowerShell 7 or run `bear-gates.ps1` directly
- if local bash cannot launch PowerShell reliably, run `bear-gates.ps1` directly
- if local bash cannot launch PowerShell reliably, run `bear-gates.ps1` directly
124 changes: 121 additions & 3 deletions .bear/ci/bear-gates.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ function Get-PropertyValue($object, $name) {
return $property.Value
}

function Get-FirstNormalizedValue($value) {
if ($null -eq $value) {
return $null
}
if ($value -is [string]) {
return [string]$value
}
foreach ($item in @($value)) {
$candidate = [string]$item
if (-not [string]::IsNullOrWhiteSpace($candidate)) {
return $candidate
}
}
return $null
}

function Normalize-Lines($text) {
if ($null -eq $text -or $text.Length -eq 0) {
return @()
Expand Down Expand Up @@ -117,6 +133,82 @@ function Parse-FailureFooter($text, $exitCode) {
}
}

function Parse-AgentFailure($agentJson, $exitCode) {
if ($exitCode -eq 0) {
return [ordered]@{
valid = $true
code = $null
path = $null
remediation = $null
}
}
if ($null -eq $agentJson) {
return New-InvalidFooter
}
$nextAction = Get-PropertyValue $agentJson 'nextAction'
$primaryClusterId = [string](Get-PropertyValue $nextAction 'primaryClusterId')
$clusters = New-OrderedArray (Get-PropertyValue $agentJson 'clusters')
$primaryCluster = $null
foreach ($cluster in $clusters) {
if ([string](Get-PropertyValue $cluster 'clusterId') -eq $primaryClusterId) {
$primaryCluster = $cluster
break
}
}
if ($null -eq $primaryCluster -and $clusters.Count -gt 0) {
$primaryCluster = $clusters[0]
}
$problems = New-OrderedArray (Get-PropertyValue $agentJson 'problems')
$primaryProblem = if ($problems.Count -gt 0) { $problems[0] } else { $null }

$codeCandidates = @(
[string](Get-PropertyValue $primaryCluster 'reasonKey'),
[string](Get-PropertyValue $primaryCluster 'ruleId'),
[string](Get-PropertyValue $primaryCluster 'failureCode'),
[string](Get-PropertyValue $primaryProblem 'reasonKey'),
[string](Get-PropertyValue $primaryProblem 'ruleId'),
[string](Get-PropertyValue $primaryProblem 'failureCode'),
[string](Get-PropertyValue $primaryProblem 'messageKey')
)
$code = $null
foreach ($candidate in $codeCandidates) {
if (-not [string]::IsNullOrWhiteSpace($candidate)) {
$code = $candidate
break
}
}
if ([string]::IsNullOrWhiteSpace($code)) {
return New-InvalidFooter
}

$pathCandidates = @(
(Get-FirstNormalizedValue (Get-PropertyValue $primaryCluster 'files')),
[string](Get-PropertyValue $primaryProblem 'file')
)
$path = $null
foreach ($candidate in $pathCandidates) {
if (-not [string]::IsNullOrWhiteSpace($candidate)) {
$path = $candidate
break
}
}
if ([string]::IsNullOrWhiteSpace($path)) {
$path = 'agent.json'
}

$steps = New-OrderedArray (Get-PropertyValue $nextAction 'steps')
$remediation = if ($steps.Count -gt 0 -and -not [string]::IsNullOrWhiteSpace([string]$steps[0])) {
[string]$steps[0]
} else {
'Inspect BEAR agent diagnostics and apply the listed next action.'
}
return [ordered]@{
valid = $true
code = $code
path = $path
remediation = $remediation
}
}
function Try-ParseAgentJson($text) {
if ([string]::IsNullOrWhiteSpace($text)) {
return [ordered]@{
Expand Down Expand Up @@ -402,15 +494,30 @@ function Get-ClassesDisplay($classes) {
return ($classes -join ',')
}

function Get-DecisionHeader($decision) {
switch ($decision) {
'pass' { return 'BEAR Decision: PASS' }
'review-required' { return 'BEAR Decision: REVIEW REQUIRED' }
'fail' { return 'BEAR Decision: FAIL' }
'allowed-expansion' { return 'BEAR Decision: ALLOWED EXPANSION' }
default { return 'BEAR Decision: ' + $decision.ToUpperInvariant() }
}
}

function New-MarkdownSummary($modeValue, $decision, $baseResolution, $checkReport, $prReport, $combinedBoundaryDeltas, $allowEntryCandidate) {
$baseDisplay = if ($baseResolution.resolved) { $baseResolution.value } else { 'unresolved' }
$lines = New-Object System.Collections.Generic.List[string]
$lines.Add('# BEAR CI Governance')
$lines.Add('')
$lines.Add((Get-DecisionHeader $decision))
$lines.Add('')
$lines.Add('- Mode: ' + $modeValue)
$lines.Add('- Decision: ' + $decision)
$lines.Add('- Base SHA: ' + $baseDisplay)
$lines.Add('- Report: build/bear/ci/bear-ci-report.json')
if ($decision -eq 'review-required') {
$lines.Add('- Review Required: boundary expansion detected.')
}
$lines.Add('')
$lines.Add('## Check')
$lines.Add('- Exit: ' + $checkReport.exitCode)
Expand Down Expand Up @@ -558,6 +665,9 @@ function Invoke-BearCommand($label, $commandText, $commandPath, $commandArgs) {
$stderrHash = if (Test-Path $stderrPath) { (Get-FileHash -Algorithm SHA256 $stderrPath).Hash.ToLowerInvariant() } else { $null }
$agent = Try-ParseAgentJson $stdoutText
$footer = Parse-FailureFooter $stderrText $exitCode
if (-not $footer.valid -and $agent.valid) {
$footer = Parse-AgentFailure $agent.json $exitCode
}
return [ordered]@{
label = $label
command = $commandText
Expand Down Expand Up @@ -622,15 +732,21 @@ try {
$allowEntryCandidate = Get-AllowEntryCandidate $mode $prResult $prTelemetry $baseResolution.value

$decision = 'pass'
if ($checkResult.exitCode -in @(2, 5, 64, 70, 74)) {
if ($checkClasses -contains 'CI_INTERNAL_ERROR') {
$decision = 'fail'
} elseif ($mode -eq 'observe' -and $checkResult.exitCode -in @(2, 3, 4, 5, 6, 7, 64, 70, 74)) {
$decision = 'fail'
} elseif ($checkResult.exitCode -in @(2, 5, 64, 70, 74)) {
$decision = 'fail'
} elseif (-not $baseResolution.resolved) {
$decision = 'fail'
} elseif ($null -eq $prResult) {
$decision = 'fail'
} elseif ($mode -eq 'observe') {
if ($prResult.exitCode -in @(2, 64, 70, 74)) {
if (($prClasses -contains 'CI_INTERNAL_ERROR') -or $prResult.exitCode -in @(2, 64, 70, 74)) {
$decision = 'fail'
} elseif ($prResult.exitCode -eq 5) {
$decision = 'review-required'
}
} elseif ($checkResult.exitCode -ne 0) {
$decision = 'fail'
Expand All @@ -641,7 +757,6 @@ try {
} else {
$decision = 'fail'
}

$checkReport = [ordered]@{
status = 'ran'
exitCode = $checkResult.exitCode
Expand Down Expand Up @@ -708,6 +823,7 @@ try {
$baseDisplay = if ($baseResolution.resolved) { $baseResolution.value } else { '<unresolved>' }
$checkCodeDisplay = Get-CodeDisplay $checkResult.footer.code
$checkClassesDisplay = Get-ClassesDisplay $checkClasses
Write-Output (Get-DecisionHeader $decision)
Write-Output ('MODE=' + $mode + ' DECISION=' + $decision + ' BASE=' + $baseDisplay)
Write-Output ('CHECK exit=' + $checkResult.exitCode + ' code=' + $checkCodeDisplay + ' classes=' + $checkClassesDisplay)
if ($prStatus -eq 'ran') {
Expand Down Expand Up @@ -742,3 +858,5 @@ try {





Empty file modified .bear/ci/bear-gates.sh
100644 → 100755
Empty file.
Empty file modified .bear/tools/bear-cli/bin/bear
100644 → 100755
Empty file.
Binary file modified .bear/tools/bear-cli/lib/app-0.1.0-SNAPSHOT.jar
Binary file not shown.
Binary file modified .bear/tools/bear-cli/lib/kernel-0.1.0-SNAPSHOT.jar
Binary file not shown.
63 changes: 63 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:

permissions:
contents: read
issues: write
pull-requests: write

jobs:
governance:
Expand All @@ -21,9 +23,70 @@ jobs:
distribution: temurin
java-version: '21'

- name: Generate BEAR artifacts
run: ./.bear/tools/bear-cli/bin/bear compile --all --project .

- name: Run BEAR governance (observe)
run: ./.bear/ci/bear-gates.sh --mode observe

- name: Publish BEAR PR summary
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const marker = '<!-- bear-ci-governance -->';
const reportPath = 'build/bear/ci/bear-ci-report.json';
const summaryPath = 'build/bear/ci/bear-ci-summary.md';

let body = `${marker}\n## BEAR CI\n\nBEAR did not produce its expected CI report. Check the workflow logs.`;
if (fs.existsSync(reportPath) && fs.existsSync(summaryPath)) {
const report = JSON.parse(fs.readFileSync(reportPath, 'utf8'));
const summary = fs.readFileSync(summaryPath, 'utf8').trim();
const decision = String(report.decision || 'unknown').toUpperCase().replace(/-/g, ' ');
const mode = report.mode || 'unknown';
const baseSha = report.resolvedBaseSha || 'unknown';
body = [
marker,
'## BEAR CI',
'',
`- Decision: \`${decision}\``,
`- Mode: \`${mode}\``,
`- Base SHA: \`${baseSha}\``,
'',
'<details><summary>BEAR summary</summary>',
'',
summary,
'',
'</details>'
].join('\n');
}

const pr = context.payload.pull_request;
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
per_page: 100
});

const existing = comments.find((comment) => comment.user?.type === 'Bot' && comment.body?.includes(marker));
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body
});
}

- name: Upload BEAR CI artifacts
if: always()
uses: actions/upload-artifact@v4
Expand Down
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# AGENTS.md (Project Bootstrap)
# AGENTS.md (Project Bootstrap)

This project uses the BEAR agent profile.

Startup (mandatory):
1. Read `.bear/agent/BEAR_AGENT.md`.
2. Follow `.bear/agent/BEAR_AGENT.md` for the full session.
1. Read `.bear/agent/BOOTSTRAP.md`.
2. Follow `.bear/agent/BOOTSTRAP.md` for the full session.

Safety (mandatory before cleanup/delete commands):
1. Read `doc/SAFETY_RULES.md`.
2. Do not run ad-hoc recursive deletes.
3. Use `scripts/safe-clean-temp.ps1` for temp cleanup.

7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ CI demo:
- `scenario/02-feature-extension -> baseline/greenfield-output`

Product specification:
- `doc/SPEC.md`
- `spec/SPEC.md`

Branch context:
- Branch role: demo main/spec-only base
- Use this branch as the PR target for the greenfield baseline review.
- Branch role: greenfield implementation baseline
- Cut from: `scenario/01-agent-greenfield-implementation`
- Use this governance base for `pr-check`: `origin/main`
Loading