BuildMender 0.2: detailed run and testing guide
Updated: 4 November 2026 Application: BuildMender 0.2.0 (existing package: ci-resolve) Workspace path: /Users/subashthiruppathy/Documents/projects/ci-resolve Product name: BuildMender; see naming notes. The website and dashboard use BuildMender. The application directory, package, environment variables, repair branches and commands still use ci-resolve for compatibility.
Product website: / includes interactive platform and workflow sections. Browser-readable guides are under /guides/; the application remains at /app. See website deployment and testing for the standalone static build.
This guide covers one-time installation, running the dashboard, running automated tests, connecting unattended operation, testing a real repair, observing results, troubleshooting, and maintaining a background service.
Normal operation after setup: collect → reproduce → repair → verify → publish → observe CI/merge → resolve. Manual log uploads and per-failure commands are optional diagnostic tools, not requirements for the automated path.
Contents
- Choose what you want to run
- Prerequisites
- Open the project and check the installation
- Run a preview without live automation
- Run the automated test suite
- Enable browser tests
- Run selected tests
- Understand what the tests prove
- Connect a target repository once
- Configure credentials once
- Configure the execution policy
- Start unattended operation
- Perform a real GitHub canary test
- Read the dashboard and API
- Interpret workflow states
- Test rejection and recovery behavior
- Optional manual diagnostic commands
- Run automatically after macOS login
- Stop, restart, and change configuration
- Back up and restore local state
- Troubleshoot common problems
- Current support limits
- Acceptance checklist
- Quick command reference
- References
1. Choose what you want to run
| Goal | GitHub/model credentials | Docker | Browser dependency | Starting section |
|---|---|---|---|---|
| View the dashboard and labeled sample | No | No | Your normal browser | Section 4 |
| Run core, API, CLI and automation tests | No | No | No | Section 5 |
| Include automated desktop/mobile browser tests | No | No | Python Playwright + Chromium | Section 6 |
| Run unattended repairs against GitHub | Yes | Yes for default backend | Optional | Sections 9–13 |
| Run a trusted-local controlled pilot | Yes for live services | No | Optional | Section 11 |
The test suite uses temporary local repositories and simulated external responses. It does not need access to your GitHub repositories, a paid model account, or a running Docker daemon.
Live automation can create repair branches, PRs and merges in the repositories you configure. Use a dedicated canary repository for the first live test.
2. Prerequisites
Required for the application and core tests
- Node.js 24 or newer with npm.
- Git available in
PATH. - A terminal with permission to create local files and localhost listeners.
- This application source directory.
There are no npm runtime dependencies. SQLite is provided through Node's built-in node:sqlite module.
Additional requirements for live automation
- Docker installed and running for the default execution backend.
- A checked-out target repository with a standard
github.comorigin. - A Node.js target with an
npm testscript and supported TAP/Node spec results. - GitHub credentials with access to that target repository.
- A repair-model API key and an available model ID.
- Network access to GitHub, its log-storage destinations, the model API, and any permitted dependency registry.
- CI configured to run on repair PRs and the resulting merged commits.
Additional requirement for browser tests
A supported Python 3 installation, the Python playwright package, and its Chromium browser. These are development-test dependencies, not application runtime dependencies.
The command examples use macOS/Linux shell syntax. Native Windows service installation and Windows execution recipes are not covered.
3. Open the project and check the installation
Open Terminal and run:
cd /Users/subashthiruppathy/Documents/projects/ci-resolve
export CI_GUIDE_APP="$PWD"
node --version
npm --version
git --version
Expected: Node reports v24.x or newer; npm and Git print their versions.
The variables above belong to that terminal session. In a new terminal, rerun the absolute cd command and export CI_GUIDE_APP="$PWD" before using the variable-based examples.
Check JavaScript syntax:
npm run check
Expected: exit status zero with no syntax errors.
A dependency installation is not required to start this version. If you want npm to verify the lockfile state, run:
npm ci --ignore-scripts
Run commands from the application directory unless a section explicitly switches to the target repository. The application directory and the repository being repaired are different concepts.
4. Run a preview without live automation
4.1 Create isolated preview state
This makes the preview independent of any existing live policy or database:
cd "$CI_GUIDE_APP"
CI_GUIDE_PREVIEW="$(mktemp -d)"
CI_RESOLVE_CONFIG="$CI_GUIDE_PREVIEW/no-automation.json" \
CI_RESOLVE_DB="$CI_GUIDE_PREVIEW/preview.sqlite" \
npm start
Do not create no-automation.json; its absence intentionally disables the worker for this preview. These environment assignments apply only to this command.
Expected terminal message:
CI Resolve: http://127.0.0.1:4310/app
4.2 Open the application
- Workbench:
http://127.0.0.1:4310/app - Product website:
http://127.0.0.1:4310/ - Health API:
http://127.0.0.1:4310/api/health
On macOS, from a second terminal:
open http://127.0.0.1:4310/app
Expected dashboard: empty investigation inbox and Connect once. Resolve automatically.
4.3 Explore the labeled sample
Click Explore a sample run. Inspect Diagnosis, Occurrences, Verification and Activity. You can assign an owner, add a note, start an investigation and use the filters.
The sample is fictional. It is explicitly labeled, cannot receive real verification evidence and cannot demonstrate live repair or merge.
4.4 Check HTTP responses
While the preview is running, use another terminal:
curl --fail --silent --show-error http://127.0.0.1:4310/api/health
curl --fail --silent --show-error http://127.0.0.1:4310/api/automation
Expected health fields include ok: true, version: "0.2.0", and mode: "local". Automation reports configured: false for this preview.
4.5 Stop the preview
Press Control-C in its terminal. The preview database remains in the temporary directory; it does not replace .data/ci-resolve.sqlite.
If port 4310 is occupied, choose another port:
PORT=4311 npm start
Use http://127.0.0.1:4311/app for that process. A bare npm start uses the normal default policy/database, so keep the isolated assignments from step 4.1 if you still want preview-only mode.
5. Run the automated test suite
From the application folder:
cd "$CI_GUIDE_APP"
npm test
The current version defines 56 tests, including two optional browser tests:
| Browser configuration | Expected result for the current source |
|---|---|
| No configured Python Playwright interpreter | 54 pass, 2 explicitly skipped, 0 failures |
| Working configured Python Playwright + Chromium | 56 pass, 0 skipped, 0 failures |
| Interpreter configured but package/browser missing | Browser tests fail; fix that dependency |
The count may change with future code updates. The decisive result is zero unexpected failures and successful execution of the test groups you intended to run.
The suite starts its own temporary HTTP servers on available ports. You do not need to leave the app running. It also creates and removes temporary Git fixtures; it does not intentionally patch your registered repository.
The existing .private/browser-python file can enable browser tests even when you did not set an environment variable in this shell.
6. Enable browser tests
6.1 Create a Python environment
cd "$CI_GUIDE_APP"
python3 -m venv .private/browser-venv
.private/browser-venv/bin/python -m pip install playwright
.private/browser-venv/bin/python -m playwright install chromium
On Linux, Playwright may also require OS browser dependencies; follow its official installation guidance. Network access is required to install the package/browser. The current test scripts use the Playwright Python library directly, not pytest.
6.2 Run all tests with this interpreter
CI_RESOLVE_BROWSER_PYTHON="$PWD/.private/browser-venv/bin/python" npm test
Expected: all 56 tests pass, including:
browser workflows, website and mobile layoutautomatic workflow browser experience
6.3 Persist the interpreter choice locally
Optional one-time convenience:
printf '%s\n' "$PWD/.private/browser-venv/bin/python" > .private/browser-python
npm test
.private/ is Git-ignored. The environment variable takes precedence over the local file.
6.4 View generated screenshots
Browser tests write these files under artifacts/:
workbench-empty.pngworkbench-desktop.pngworkbench-mobile.pngimport-mobile.pngwebsite-desktop.pngwebsite-mobile.pngautopilot-desktop.pngautopilot-mobile.png
For example, on macOS:
open artifacts/autopilot-desktop.png
open artifacts/autopilot-mobile.png
Screenshots are local test artifacts and are not committed by default.
7. Run selected tests
Use the Node test runner directly when selecting files or names. Put runner options before file paths.
Core diagnostic and persistence tests
node --test test/core.test.js
HTTP/API tests
node --test test/server.test.js
CLI and local command verification
node --test test/cli.test.js test/verify.test.js
Full unattended automation tests
node --test test/automation.test.js
Provider, model-contract and policy tests
node --test test/providers.test.js
Browser tests only
CI_RESOLVE_BROWSER_PYTHON="$PWD/.private/browser-venv/bin/python" \
node --test test/browser.test.js
One complete unattended-flow test
node --test \
--test-name-pattern='unattended failure collection' \
test/automation.test.js
Expected: the matching test passes; nonmatching tests may be omitted or reported skipped depending on runner output.
8. Understand what the tests prove
| Stage | What runs for real in the test suite | What is simulated |
|---|---|---|
| Source fixture | Temporary Git repository and committed failing source | No customer repository |
| Reproduction | Real Node process executes a failing test | Remote CI acquisition responses |
| Repair proposal | Patch contract, path restrictions and exact edit application | The model's generated response |
| Verification | Real test execution against candidate source; original tests preserved | No live model quality claim |
| PR publication | Client request shape and ambiguous-response recovery | GitHub remote state/network responses |
| Merge and final CI | State machine evaluates required checks and merge identity | GitHub merge/check responses |
| Browser | Real Chromium on desktop/mobile viewports | Fixture account/repository data |
| Docker | Execution command/policy code exists | Real Docker runtime is not exercised by the current suite |
A green suite validates implemented behavior under these conditions. It does not establish live credentials, Docker readiness, a production deployment, or the model's repair success rate on your repositories.
During development, 56 tests passed with Chromium enabled. Live GitHub/model/Docker validation remains a separate acceptance step.
9. Connect a target repository once
Use an existing supported repository, or first create the disposable canary from section 13.
In your terminal:
export CI_GUIDE_TARGET=/absolute/path/to/your/repository
git -C "$CI_GUIDE_TARGET" remote get-url origin
Supported origins look like:
https://github.com/your-org/your-repo.git
git@github.com:your-org/your-repo.git
GitHub Enterprise hosts, custom SSH aliases and a checkout without an origin are not supported by this version.
Check the target's test command:
cd "$CI_GUIDE_TARGET"
npm test
cd "$CI_GUIDE_APP"
Start Docker Desktop or the Docker service, then verify:
docker version
docker info
Expected: both client and server details are available. A client binary alone is insufficient.
Generate the policy:
node bin/ci-resolve.js setup --cwd "$CI_GUIDE_TARGET"
Setup pulls node:24, resolves an immutable image digest, detects npm scripts and writes .private/automation.json. It does not create GitHub/model credentials or change repository review rules.
Expected output contains configured: true, the target repository and the policy filename. This means the local policy was generated, not that live authentication has passed.
If you already have an appropriate pinned image:
CI_GUIDE_IMAGE="$(docker image inspect node:24 --format '{{index .RepoDigests 0}}')"
node bin/ci-resolve.js setup --cwd "$CI_GUIDE_TARGET" --image "$CI_GUIDE_IMAGE"
Setup refuses to overwrite an existing policy. For additional repositories, edit its repositories array once; do not repeatedly run setup against the same policy file.
10. Configure credentials once
10.1 Create a private environment file
cd "$CI_GUIDE_APP"
mkdir -p .private
chmod 700 .private
touch .private/automation.env
chmod 600 .private/automation.env
Edit .private/automation.env using your editor. Put real values into that private file, not into a tracked document or a pasted terminal command. Do not overwrite an existing credential file while following this guide.
10.2 GitHub token option
The application reads this exact variable:
CI_RESOLVE_GITHUB_TOKEN=YOUR_SCOPED_GITHUB_TOKEN
Choose only the intended repository access. Permissions needed by the implemented flow include Actions read, Checks read, Commit statuses read, Contents read/write, Pull requests read/write and Metadata read. Organization policies or App installation settings may further restrict access.
gh auth login configures GitHub CLI; it does not automatically populate CI_RESOLVE_GITHUB_TOKEN for this application.
10.3 GitHub App option
Instead of a token, configure:
CI_RESOLVE_GITHUB_APP_ID=YOUR_NUMERIC_APP_ID
CI_RESOLVE_GITHUB_INSTALLATION_ID=YOUR_NUMERIC_INSTALLATION_ID
CI_RESOLVE_GITHUB_PRIVATE_KEY_FILE=/absolute/private/path/to/app-key.pem
Install the App on the chosen repositories and grant the required permissions. The private key remains on the service host; the client obtains and refreshes installation tokens.
If both options are set, CI_RESOLVE_GITHUB_TOKEN takes precedence. Use the option you intend rather than leaving an old token configured accidentally.
10.4 Repair model
CI_RESOLVE_ANTHROPIC_KEY=YOUR_MODEL_API_KEY
CI_RESOLVE_ANTHROPIC_MODEL=YOUR_AVAILABLE_MODEL_ID
Use a model available to your API account. The adapter uses the Claude Messages API, requires a structured JSON repair response, and has a bounded context/output budget.
Model calls send bounded source excerpts, protected test context and redacted diagnostic evidence. GitHub/model credentials are not passed into worker subprocess environments. Redaction is best effort; avoid placing secrets in source and logs.
10.5 Check presence without printing values
node --env-file-if-exists=.private/automation.env --input-type=module <<'JS'
console.log({
githubToken: Boolean(process.env.CI_RESOLVE_GITHUB_TOKEN),
githubApp: Boolean(
process.env.CI_RESOLVE_GITHUB_APP_ID &&
process.env.CI_RESOLVE_GITHUB_INSTALLATION_ID &&
process.env.CI_RESOLVE_GITHUB_PRIVATE_KEY_FILE
),
modelKey: Boolean(process.env.CI_RESOLVE_ANTHROPIC_KEY),
modelId: Boolean(process.env.CI_RESOLVE_ANTHROPIC_MODEL)
});
JS
Expected: at least one GitHub option and both model fields are true. Presence is not proof that the credentials have valid permissions or billing.
11. Configure the execution policy
Inspect the generated policy locally:
node --input-type=module <<'JS'
import { loadConfig } from './src/automation/config.js';
const config = loadConfig();
console.log(config ? {
repositories: config.repositories.map(r => ({
repository: r.repository,
backend: r.backend,
commands: r.commands,
allowPaths: r.allowPaths,
autoMerge: r.autoMerge
})),
pollIntervalMs: config.pollIntervalMs,
concurrency: config.concurrency
} : { configured: false });
JS
Important fields
| Field | Current behavior |
|---|---|
version | Must be 1 |
pollIntervalMs | Default 60,000; allowed 1,000–3,600,000 |
concurrency | Default 2; allowed 1–8 |
repository | Exact GitHub owner/name |
checkout | Absolute local source-cache checkout |
backend | docker, or explicitly opted-in trusted-local |
image | Required Docker image digest; mutable tags rejected |
install | Preparation commands as arrays, not shell strings |
installNetwork | none or bridge; setup initially chooses bridge |
commands | First command reproduces/tests; all commands verify candidates |
allowPaths | Editable source globs; protected paths stay prohibited |
jobs | Optional exact job-name allowlist |
requiredChecks | Additional exact check names alongside the failed source job |
autoMerge | Defaults true; requests a native merge where permitted |
timeoutMs | Default 120,000; allowed 100–600,000 |
A command is represented as ["npm", "test"], not "npm test". Shell operators such as && are not parsed in an argument array.
Setup's initial editable patterns are src/**/*.js, src/**/*.ts, and lib/**/*.js. If your source uses .cjs, .mjs, .tsx or app/, add the appropriate bounded source patterns during setup. This does not allow modifications to tests, fixtures, snapshots or package configuration.
The first command must expose the supported test inventory and the failing behavior. A build-only command or a test command that always exits zero will not satisfy the normal reproduction contract.
Fully unattended merge prerequisites
The service can merge a ready repair via GitHub's merge endpoint or request native auto-merge while waiting for repository policy. It does not disable review requirements or required checks.
For a completely unattended canary, its repository policies must permit the scoped service identity to merge verified repairs without an additional human review. Keep your real repository's desired governance rules; configure the intended policy once rather than treating a blocked review as an application test failure.
CI must produce the required check names on both the repair head and the merged commit. Otherwise the task remains in observe and cannot claim resolution.
Trusted-local alternative
For code you already trust to execute as your local user, an explicitly configured policy can use:
{
"backend": "trusted-local",
"trustedLocalExecution": true
}
These are fields within a complete repository policy, not a complete configuration file. This backend does not provide Docker/network/OS isolation. It is useful for controlled local environments; the automatic test fixture uses it.
Restart the service after policy or environment changes. Existing tasks retain their original policy digest. A changed policy is not silently applied to already queued work.
12. Start unattended operation
Dashboard and workers together
cd "$CI_GUIDE_APP"
npm start
When .private/automation.json exists, this loads .private/automation.env and starts the collector/workers with the server.
Worker without a dashboard
npm run automate
One collection/processing cycle
node --env-file-if-exists=.private/automation.env \
bin/ci-resolve.js automate --mode once
A single cycle may leave a PR waiting for CI/merge. It is not a promise that an asynchronous remote repair completes in one invocation. The continuous service performs later reconciliation.
Also, exit code zero alone does not mean live readiness: collector errors can be represented in the returned health data. Inspect that output or the dashboard.
Use explicit state paths for a service
CI_RESOLVE_CONFIG="$PWD/.private/automation.json" \
CI_RESOLVE_DB="$PWD/.data/ci-resolve.sqlite" \
PORT=4310 npm start
All processes sharing work should use the same absolute database path and the same application working directory. The execution work root is .data/automation relative to that working directory, not relative to the database filename.
The default reconciliation interval is 60 seconds; the browser refreshes approximately every eight seconds when you are not editing a form. Collection, execution and remote CI add their own time. Use section 18 for automatic launch after login.
13. Perform a real GitHub canary test
This is an optional live acceptance test in a dedicated disposable repository. It creates actual remote commits and can create/merge an automatic repair. Do not introduce the intentional defect into a production repository.
13.1 Prepare an empty canary repository
Create a private test repository on GitHub and clone it into a separate directory. Set CI_GUIDE_TARGET to that checkout. Keep CI_GUIDE_APP pointing to the CI Resolve application.
Create these files in the canary checkout:
`package.json`
{
"name": "ci-resolve-canary",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "node --test --test-reporter=tap"
}
}
`src/add.js`
export function add(a, b) {
return a + b;
}
`test/add.test.js`
import test from 'node:test';
import assert from 'node:assert/strict';
import { add } from '../src/add.js';
test('adds two positive numbers', () => {
assert.equal(add(2, 3), 5);
});
`.github/workflows/ci.yml`
name: Canary CI
on:
push:
pull_request:
permissions:
contents: read
jobs:
test:
name: Unit tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: '24'
package-manager-cache: false
- run: npm test
The action versions follow the official repositories' examples checked on the guide date. Follow your organization's action-version pinning policy for a production workflow.
There are no package dependencies, so this fixture does not require a lockfile or dependency-install step.
13.2 Establish a passing baseline
In the canary checkout:
cd "$CI_GUIDE_TARGET"
npm test
git add package.json src/add.js test/add.test.js .github/workflows/ci.yml
git commit -m "test(canary): add passing automation fixture"
git push
Confirm that GitHub Actions reports Unit tests passing. Ensure the checkout is on a normal branch name, such as main, rather than ci-resolve/...; the collector intentionally excludes its own repair branches.
Register this repository using sections 9–11, configure its credential access and start the unattended service. If a different repository policy already exists, add this canary as a separate policy entry rather than overwriting the existing file.
13.3 Introduce one source defect
Change only the source implementation:
export function add(a, b) {
return a - b;
}
Confirm the local test fails, then create the intentionally failing canary commit:
cd "$CI_GUIDE_TARGET"
npm test
git add src/add.js
git commit -m "test(canary): introduce intentional addition regression"
git push
Do not edit the expected assertion. Leave the remote source branch at this commit while the automation investigates it; an additional push can supersede that evidence.
13.4 Observe the automatic repair
The configured service should:
- Discover the failed Unit tests job.
- Reproduce
adds two positive numbersfailing in a disposable workspace. - Request a source repair from the configured model.
- Reject any proposed test modification.
- Verify the candidate against the original test inventory.
- Publish a
ci-resolve/<task-id>branch and repair PR targeting the failing branch. - Confirm original CI checks on the repair head.
- Merge/request auto-merge if native policy permits.
- Observe Unit tests on the merged commit.
- Mark the investigation resolved automatically.
A model may abstain or produce an invalid candidate; the expected correct behavior then is a recorded stop/exhaustion, not fabricated success. The acceptance test demonstrates live success only when an actual correct repair completes.
13.5 Record acceptance evidence
Retain the source workflow/run/attempt/job IDs, source commit, task ID, repair PR/head SHA, verification results, merged SHA and resulting CI result. The original tests must remain unchanged.
The service does not patch the registered checkout's working files. After remote merge, refresh your checkout through your normal Git workflow if you want to inspect the merged repair locally.
A failing check on a merged commit is recorded as blocked; version 0.2 does not implement automatic rollback. Do not infer rollback from the presence of merge reconciliation.
14. Read the dashboard and API
Dashboard
- Automation status: configured policies, connection errors and active/stopped workflows.
- Inbox: grouped failure investigations and occurrences.
- Automatic workflow: reproduction/repair/verification/publication/observation stages.
- Workflow evidence & decisions: captured transition evidence and stop reasons.
- Verification: real configured command results and the source/patch identity.
- Activity: assignments, transitions, notes and errors.
For automated cases, resolution is owned by the worker. The legacy Mark resolved action is not the normal automated path.
Read-only API inspection
While the server is running:
curl --fail --silent --show-error http://127.0.0.1:4310/api/automation
curl --fail --silent --show-error http://127.0.0.1:4310/api/cases
To pretty-print without installing another tool:
curl --fail --silent --show-error http://127.0.0.1:4310/api/automation \
| python3 -m json.tool
Use an actual case ID for details:
curl --fail --silent --show-error \
http://127.0.0.1:4310/api/cases/REPLACE_WITH_CASE_ID
configured: true means a policy was loaded. Read health and task error/phase to determine actual progress. The overview lists the newest 200 tasks; per-case details retain that case's workflow evidence.
15. Interpret workflow states
| Task phase | Meaning | Normal next behavior |
|---|---|---|
queued | Imported failed job has a durable task | Source revision check |
prepare | Disposable checkout/environment preparation | Reproduction |
reproduce | Run the first configured command | Require a comparable failing symptom/test inventory |
repair | Request/validate a structured source proposal | Candidate verification or bounded retry |
verify | Run protected tests and all configured checks | Publish only if verification succeeds |
publish | Create/reconcile deterministic repair branch and PR | Remote CI observation |
observe | Wait for checks, native merge and merged-commit checks | Automatic resolution when all required evidence exists |
resolved | Required evidence and merge checks accepted | Terminal success |
unreproduced | Original supported failure not reproduced | Terminal; no repair claimed |
superseded | Source, repair head or newer occurrence invalidated work | Terminal obsolete task |
blocked | Explicit unsupported condition, rejected remote CI or unavailable policy | Terminal recorded stop |
failed | Generic retry budget exhausted | Terminal error |
exhausted | Candidate or lifetime budget exhausted | Terminal; no repair claimed |
An investigation's legacy status is separate from its task phase. For example, investigating can accompany a stopped automatic task; inspect the task's exact phase and evidence.
Transient errors use bounded retries. Missing repair-model setup parks the current phase for a later retry. The service must be restarted to load edited environment-file values. Terminal tasks are not automatically reset by editing SQL or restarting; create fresh provider evidence after correcting setup rather than altering recorded evidence by hand.
16. Test rejection and recovery behavior
The following automated tests already cover negative paths without modifying a real repository:
node --test test/automation.test.js test/providers.test.js
Important cases include:
| Test scenario | Expected result |
|---|---|
| Proposal edits a protected test | Rejected; no publication |
| Source patch still fails tests | Another bounded candidate or exhausted outcome |
| Model returns no changes | Recorded abstention/blocked outcome |
| Reproduced failure differs from imported symptom | Unreproduced outcome |
| Source branch advances | Old task superseded |
| Repair head changes | Old evidence rejected; obsolete observed PR closed where possible |
| Original CI rejects repair | No successful resolution |
| Merged-commit checks are missing | Stay in observation |
| Response is lost after PR creation | Reconcile existing PR instead of blindly duplicating it |
| Worker lease expires | Stale worker cannot commit a checkpoint |
| Model setup is temporarily missing | Retry later without inventing repair evidence |
For a restart experiment in a live canary, stop the service with Control-C during observation and restart it using the same policy, database and application directory. It should resume reconciliation rather than generate another repair simply because the process restarted. A workspace lost before verification requires reproduction/re-verification, which is intentional.
17. Optional manual diagnostic commands
These help with ad hoc inspection and backward compatibility. They are not required for daily unattended operation.
cd "$CI_GUIDE_APP"
node bin/ci-resolve.js --help
node bin/ci-resolve.js list
node bin/ci-resolve.js show --case REPLACE_WITH_CASE_ID
Import the fictional fixture into a separate diagnostic database:
CI_RESOLVE_DB="$PWD/.private/manual-demo.sqlite" \
node bin/ci-resolve.js import --file examples/failed-run.json
Use that same database setting for subsequent list/show commands if inspecting the fixture. A manual import does not automatically become provider-authenticated evidence or enqueue a live repair task.
For a real manual investigation, an explicitly chosen local command can be recorded:
node bin/ci-resolve.js verify \
--case REPLACE_WITH_CASE_ID \
--cwd "$CI_GUIDE_TARGET" \
-- npm test
Sample cases reject real verification. The local command runs with your user permissions; it is not the Docker automation path. A passing manual command is not full CI-equivalence proof.
18. Run automatically after macOS login
This optional one-time setup keeps the dashboard and workers running without opening Terminal each day. It is for a local macOS installation, not a production hosting deployment.
First complete a foreground live canary. Stop any foreground CI Resolve process before installing the login service so the two do not fight for port 4310. Docker Desktop must also be available after login if the policy uses Docker.
The following command creates a user LaunchAgent under your home folder and points it at this application. It does not change repository code or install a system-wide daemon.
cd "$CI_GUIDE_APP"
export CI_GUIDE_APP="$PWD"
python3 <<'PY'
import os
import pathlib
import plistlib
import shutil
app = pathlib.Path(os.environ['CI_GUIDE_APP']).resolve()
node = shutil.which('node')
if not node:
raise SystemExit('Node is not available in PATH.')
node = pathlib.Path(node).resolve()
private = app / '.private'
private.mkdir(exist_ok=True)
agent = pathlib.Path.home() / 'Library/LaunchAgents/in.spekra.ci-resolve.plist'
agent.parent.mkdir(parents=True, exist_ok=True)
if agent.exists():
raise SystemExit('LaunchAgent already exists; inspect it instead of overwriting.')
path = ':'.join([str(node.parent), '/opt/homebrew/bin', '/usr/local/bin', '/usr/bin', '/bin'])
payload = {
'Label': 'in.spekra.ci-resolve',
'ProgramArguments': [
str(node),
'--env-file-if-exists=' + str(private / 'automation.env'),
str(app / 'src/server.js'),
],
'WorkingDirectory': str(app),
'EnvironmentVariables': {'PATH': path},
'RunAtLoad': True,
'KeepAlive': True,
'StandardOutPath': str(private / 'service.stdout.log'),
'StandardErrorPath': str(private / 'service.stderr.log'),
}
with agent.open('wb') as stream:
plistlib.dump(payload, stream)
print(agent)
PY
Register it:
launchctl bootstrap "gui/$(id -u)" \
"$HOME/Library/LaunchAgents/in.spekra.ci-resolve.plist"
Check it:
launchctl print "gui/$(id -u)/in.spekra.ci-resolve"
curl --fail --silent --show-error http://127.0.0.1:4310/api/health
The service loads credentials from .private/automation.env; it does not inherit arbitrary exports from your current Terminal. The resolved Node executable must remain installed at that path. Regenerate the service definition deliberately if its Node installation is removed or relocated.
The LaunchAgent example is an operator setup recipe, not a service installed or validated by this development session. On Linux, use your normal user/system service manager with the same working directory, Node executable and environment-file arguments.
19. Stop, restart, and change configuration
Foreground process
Press Control-C, then use npm start again. Let the shutdown finish before starting another process against the same state.
macOS LaunchAgent
Restart after editing a one-time environment/policy setting:
launchctl kickstart -k "gui/$(id -u)/in.spekra.ci-resolve"
Remove the running registration:
launchctl bootout "gui/$(id -u)" \
"$HOME/Library/LaunchAgents/in.spekra.ci-resolve.plist"
The plist remains on disk. If you intend to disable launch after future logins, move that specific plist out of ~/Library/LaunchAgents as well. Do not delete application evidence to stop a service.
Change policy carefully
Stop/restart to load the edited policy. Existing tasks are bound to their previous digest and can stop with a policy-changed result. After correcting a recipe, rerun the canary workflow to produce a fresh provider attempt or create a new canary commit. Restarting alone does not re-enqueue an already terminal task.
20. Back up and restore local state
Application state includes .data/ci-resolve.sqlite, SQLite companion/WAL files where present, and any retained execution workspaces under .data/automation/. Configuration and credentials are separate in .private/.
For a simple filesystem backup, first stop all app/worker instances, including any LaunchAgent. Then:
cd "$CI_GUIDE_APP"
CI_GUIDE_BACKUP="$PWD/.private/backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$CI_GUIDE_BACKUP"
cp -R .data "$CI_GUIDE_BACKUP/data"
cp .private/automation.json "$CI_GUIDE_BACKUP/automation.json"
The policy copy assumes live setup exists. Back up credential material separately using your chosen secret-management procedure; do not add it to a shared support archive.
To restore, keep every instance stopped, preserve the existing .data directory under another name, and restore the selected backup to the original state path. Confirm the policy checkout paths still exist before restarting. Do not copy only the main SQLite file from an actively writing process and assume its WAL-backed state was captured.
Execution workspaces can contain private source. Treat backups and evidence as sensitive application data.
21. Troubleshoot common problems
| Symptom | Likely cause | What to check/do |
|---|---|---|
node:sqlite unavailable | Wrong Node version | Run Node 24+ from the same shell/service PATH |
EADDRINUSE | Another process owns the port | Stop the intended previous service or choose another PORT |
listen EPERM | Terminal/agent socket restriction | Use a normal terminal that permits localhost listeners |
| Docker client exists, server missing/denied | Docker daemon or socket unavailable | Start Docker and run docker info as the service user |
| Setup says configuration exists | Overwrite protection | Inspect/edit the existing policy; do not discard it blindly |
| Setup rejects origin | Missing/custom/enterprise origin | Use a supported standard github.com checkout |
| GitHub 401/403/404 | Invalid token, wrong installation, insufficient access, policy, or unavailable resource | Check selected repositories, permissions and organization requirements |
Dashboard says setup required despite gh auth login | App-specific variables absent | Configure the exact CI Resolve credential variables |
API shows configured: true but no tasks | No eligible failure, filters, or connection error | Inspect health, job allowlist and provider run age/conclusion |
| Browser tests skip | No configured interpreter | Set CI_RESOLVE_BROWSER_PYTHON or .private/browser-python |
| Browser tests fail on import | Wrong Python environment | Install Playwright into the exact configured interpreter |
| Browser executable missing | Chromium not installed for that environment | Run that interpreter's -m playwright install chromium |
unreproduced | Different symptom, missing environment, empty inventory or skipped tests | Inspect baseline output and verify the supported recipe |
| Preparation modifies tracked inputs | Install/build step changes protected files | Prepare the appropriate image/recipe; do not bypass the integrity check |
| Repair rejected for path | Source extension outside allowlist or protected file | Review one-time bounded source patterns; tests/config remain protected |
| Model credentials missing | Key/model unset or wrong environment file | Set both model fields and restart; parked tasks can retry |
| Model HTTP error/incomplete JSON | Account/model/API issue or truncated response | Inspect task error and model access; no patch should be accepted |
PR exists but task stays in observe | Missing checks, policy requirements or merge waiting | Inspect exact required names and PR/merged-commit checks |
| Merged PR never resolves | No matching CI on the merged commit | Configure CI to run the required jobs on pushes/merged revisions |
| Source/repair head changed | Evidence became stale | Expected superseded behavior; inspect the newer revision/task |
| More than 1000 provider list records | Current reconciliation list budget exceeded | This workload needs narrower collection/product support; changing the job allowlist alone does not reduce the run-list query |
| Tasks appear in one process but not another | Different DB or working directory | Use the same absolute DB/config paths and application directory |
| Terminal task does not resume | Terminal outcome is retained | Correct setup, then produce fresh provider evidence; do not rewrite recorded results |
| GitHub push fails DNS/authentication | Publication environment unavailable | Restore network and configured GitHub authentication; local commits remain available |
The collector looks at failed workflows created in the preceding 24 hours, not every historical failure or every recently rerun old workflow. Workflows created earlier may be excluded even if retried recently.
Forks, ci-resolve/... repair branches and merge-group source events are excluded intentionally. The original failed job's name is always required during reconciliation; requiredChecks adds checks rather than replacing it.
22. Current support limits
- Local single-user service; no hosted tenant/login boundary.
- GitHub Actions only; no live GitLab/CircleCI connector in version 0.2.
- Node test inventory required; general Jest/Pytest/JUnit support is not implied.
- No tracked symlinks/submodules or arbitrary service-topology reconstruction.
- Generated default policy requires review for nondefault source extensions.
- Two repair candidates and a 24-hour task lifetime.
- No universal functional-correctness proof, automatic rollback or guarantee that a model can repair every failure.
- Actual external GitHub/model/Docker success was not demonstrated in the development environment.
- No automatic OS-service installation; section 18 is optional one-time operator setup.
These limits do not require per-failure manual action for the supported happy path. They define when automation should stop with evidence instead of claiming success.
23. Acceptance checklist
Local application/test readiness
- [ ] Node, npm and Git report valid versions.
- [ ]
npm run checksucceeds. - [ ] Core/API/CLI/automation tests pass.
- [ ] Both browser tests pass when browser coverage is required.
- [ ] Preview and website open without horizontal overflow.
- [ ] Optional sample remains labeled and cannot be mistaken for live evidence.
Live unattended readiness
- [ ] Registered repository, origin and execution recipe match.
- [ ] GitHub and model credentials are valid, not merely present.
- [ ] Docker/default image or explicitly permitted trusted-local backend works.
- [ ] CI reports the required job names on repair and merged commits.
- [ ] Repository policy permits the intended automatic merge behavior.
- [ ] A canary failure reproduces, receives a source repair, passes protected tests, merges and resolves automatically.
- [ ] Restarting during observation does not duplicate the repair PR.
- [ ] Rejected/unsupported cases show a stop reason rather than resolution.
- [ ] Persistent service, logs and backup ownership are configured once.
Only a completed live canary establishes live readiness; green simulated-service tests alone do not.
24. Quick command reference
| Task | Command from the application directory |
|---|---|
| Syntax checks | npm run check |
| Full suite | npm test |
| Unattended-flow tests | node --test test/automation.test.js |
| Provider/policy tests | node --test test/providers.test.js |
| Browser tests | node --test test/browser.test.js with a configured interpreter |
| One-time target setup | node bin/ci-resolve.js setup --cwd /absolute/target/path |
| Dashboard + configured workers | npm start |
| Worker-only service | npm run automate |
| One live cycle | node --env-file-if-exists=.private/automation.env bin/ci-resolve.js automate --mode once |
| CLI help | node bin/ci-resolve.js --help |
| List investigations | node bin/ci-resolve.js list |
| Inspect case | node bin/ci-resolve.js show --case ACTUAL_CASE_ID |
| Health | curl --fail http://127.0.0.1:4310/api/health |
| Automation status | curl --fail http://127.0.0.1:4310/api/automation |
25. References
- Current application README
- Implemented architecture
- Validation status
- Enterprise target research
- Product naming recommendations
- Playwright Python installation
- Official checkout action
- Official setup-node action
- GitHub App installation authentication
- Claude Messages API
Commands were checked against version 0.2 source and local tests. External dependency installation, the live canary, the LaunchAgent recipe and remote credentials require their respective environments and have not been executed as part of writing this guide.
Guide validation: the 25 sections and contents anchors, relative links, tables, JSON examples and all 46 shell examples were checked. The documented local canary passed with correct source and failed after introducing the source defect. The full 56-test application suite also passed, including both Chromium workflows. Live account, Docker and LaunchAgent setup remain environment-dependent steps.