@engineeros/connector 1.56.10 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,585 +1,611 @@
1
- # EngineerOS Connector
2
-
3
- The connector uses an authenticated EngineerOS WebSocket for pairing, workspace identity, run lifecycle, and evidence. Coding work can run through any agent in the official ACP registry, a custom ACP v1-compatible command over stdio, or the Forge command line. Direct Codex CLI remains available as the compatibility path.
4
-
5
- ## Hunt a running app without a repository
6
-
7
- Choose **Find bugs in a running app** in EngineerOS, register a preview or staging URL, and copy its command:
8
-
9
- ```sh
10
- npx --yes @engineeros/connector@latest hunt-host CODE --url https://your-backend.example --project PROJECT_UUID --agent codex-acp
11
- ```
12
-
13
- Use `claude-acp` for Claude. This installs the selected agent, pairs immediately, sets up Playwright and checks a browser
14
- and agent session. It uses `~/.engineeros/hunt-hosts/PROJECT_UUID`; it never initializes or inspects a repository,
15
- submits workspace snapshots, or starts a Goal runner. Keep this terminal open.
16
-
17
- If prompted, run `codex login`, or run `claude` and `/login`, in another terminal on this machine. The host checks again
18
- every 30 seconds for 30 minutes, then every five minutes. EngineerOS shows the same sign-in instructions.
19
- If auto-start was selected, the first public-page hunt starts once readiness passes. Writing is limited to 10 minutes;
20
- proving failures and reviewing them follow. Continuous hunting stays off, and failures are never retried automatically.
21
-
22
- Restart a paired host with:
23
-
24
- ```sh
25
- npx --yes @engineeros/connector@latest hunt-host --project PROJECT_UUID
26
- ```
27
-
28
- Add test accounts in Bug Hunter Setup to go deeper. **Connect your code** opens the existing Steering connection flow
29
- and pairs a separate connector in your repository. `hunt-host` refuses `--workspace` and `--onboard`.
30
-
31
- ## Independent Goal runner
32
-
33
- Connector 1.2.0 hands Goal jobs to a separate local runner. Closing the connector terminal or losing its WebSocket does not stop an executing Goal. Progress and final results use HTTP; undelivered results remain on disk for retry. Windows supervisors and workers use a windowless launcher; Goal runs and agent commands do not open new terminals.
34
-
35
- Install explicitly, or let the first Goal dispatch install and start the runner:
36
-
37
- ```text
38
- engineeros-connector runner install --workspace D:\Puli\work\workspaces\caresched
39
- engineeros-connector runner status --workspace D:\Puli\work\workspaces\caresched
40
- ```
41
-
42
- When started through `npx`, the connector installs that exact version into `~/.engineeros/connector/versions/<version>` with lifecycle scripts disabled, SHA-512 lockfile verification, npm registry signature checks and a version smoke test. Global installations and repository checkouts use their existing entry. A version change reinstalls the service; existing workers keep their code. Registry or verification failures leave Goals queued with a setup remedy. Update the backend for the HTTP claim endpoint before dispatching Goals.
43
-
44
- Windows uses Task Scheduler under your current user, restarts after failure, and resumes saved jobs at sign-in following reboot. Linux uses a systemd user service; enable user lingering separately if recovery must start before login. Existing running jobs stay with their current process; resume an interrupted run to hand it to the new service.
45
-
46
- On macOS, the runner is a per-user launchd agent in your GUI login session. It starts at login, retains your installer PATH and uses your signed-in coding agent and login Keychain. Expect a **Background Items Added** notice; manage it in **System Settings > General > Login Items**. A disabled runner stays queued until you enable it with `engineeros-connector runner start --workspace PATH`. `doctor` reports disabled, unloaded and failed services; startup output is in `.engineeros/runner/launchd.log`.
47
-
48
- macOS can deny a background Node process access to Desktop, Documents, Downloads or iCloud Drive even when your terminal has access. Move the workspace elsewhere, or allow `node` in **Privacy & Security > Files and Folders**. During each Goal, `caffeinate -i -w <worker pid>` prevents idle sleep; it does not prevent lid-close sleep. Inactivity and heartbeat monitoring allow time to resume after sleep. To disable keep-awake for this workspace, run `engineeros-connector runner install --workspace PATH --keep-awake off` (use `on` to restore it). This saves `runner_keep_awake` in the paired connector configuration.
49
-
50
- Remove the background service on any platform with `engineeros-connector runner uninstall --workspace PATH`. Queued jobs, checkpoints and results stay on disk and resume after installation. Running workers are independent of the service. Verified releases used by the runner are retained across updates until uninstall.
51
-
52
- Files under your project's `.engineeros` directory:
53
-
54
- - `runner/inbox/`: durable job dispatch requests.
55
- - `runner/service.json`: supervisor PID and heartbeat.
56
- - `runner/service.log`: supervisor startup and cleanup diagnostics.
57
- - `runner/launchd.log`: macOS output before service logging starts.
58
- - `runs/<run-id>/job.json`: execution/delivery status, saved assignment, pending result or failure.
59
- - `runs/<run-id>/state.json`: coding session and implementation/verification checkpoints.
60
- - `runs/<run-id>/activity.log`: timestamped activity and periodic inactivity status.
61
- - `runs/<run-id>/worker.log`: worker console diagnostics.
62
-
63
- The runner stops and records a resumable failure after ten minutes without agent events, except when explicitly waiting for user input. Restore missing prerequisites or agent usage before using **Resume run**. Acceptance and integration remain controlled by EngineerOS.
64
-
65
- There is no wall-clock execution cutoff. Runs stop after at most two repair-and-review cycles following the initial review. The inactivity safeguard above still stops a silent agent; waiting for your answer does not consume a repair cycle. Successful results awaiting upload are not executed again.
66
-
67
- Before the independent checks, the connector runs each frozen `command` Proof itself in the Goal worktree and sends the measured exit code, duration, best-effort pass/fail/skip counts and a 4000-character log tail as `test_run` evidence (`measured_by: "connector"`). A non-zero exit, or an exit 0 whose recognised summary counted no tests, fails that Proof and starts a repair cycle; the result is saved per revision so a resumed run does not run it again. Commands that need a shell (`&&`, pipes, redirects, globs), and commands whose executable is not installed, are not run and stay with the independent verifier. Each command and everything it started stops after 15 minutes unless `ENGINEEROS_TEST_COMMAND_TIMEOUT_MS` says otherwise, and a command that exits is measured even when a leftover process still holds its output. The implementation agent is told to add or update automated tests with its code, and the verifier and reviewer fail a change whose behavior has no tests.
68
-
69
- ### Delete a Goal and its sandboxes
70
-
71
- Choose **Delete Goal** in the Goal detail header and confirm. This deletes all revisions, runs, receipts, proof results, attachments and run questions for that Goal. Connected runners first stop every run in the revision family, then remove owned isolated Git worktrees (including uncommitted sandbox files), checkpoints, queued dispatches and logs. The source repository, its local changes, Git branches and unrelated worktrees are preserved. External registered worktrees require their matching saved checkpoints to establish ownership. Manually managed external environments remain the external runner's responsibility.
72
-
73
- Deletion remains visible as **Deleting** until every assigned connector acknowledges cleanup. The supervisor polls authenticated cleanup requests every 15 seconds, including while the connector terminal is closed. Offline machines and lost acknowledgements retry safely. Cleanup errors are displayed on the Goal with **Retry cleanup**; a live worker lock or ambiguous sandbox ownership prevents removal. Active backend verification must finish before deletion starts. Small markers in `runner/deleted-runs/` prevent delayed dispatches from restarting deleted work.
74
-
75
- After updating an existing installation, reinstall the runner task with `runner install` and restart the existing supervisor to load the new code. The Windows scheduled action must use `wscript.exe` and `runner/launch.vbs`. Logs remain in the project's `.engineeros` directory; no terminal is needed for a run.
76
-
77
- If the Windows runner task was disabled, `engineeros-connector runner start --workspace PATH` explicitly enables it and starts processing queued jobs. Incoming dispatches remain queued while the task is disabled and print this recovery command; they do not enable it automatically. Do not resend the Goal just to start its queued job.
78
-
79
-
80
- ## Connect an official ACP agent
81
-
82
- Connector 0.33.0 supports **Deliver capability**. EngineerOS immediately queues the capability as a Goal request;
83
- it does not generate or require approval of a separate implementation slice first. The coding agent reads the
84
- frozen local design, writes its implementation plan inside the run worktree, then implements, tests and repairs
85
- the work. Independent testing and review agents verify the delivered commit. Required user choices use the
86
- existing run questions and resume the same work. The final handover includes the committed plan, source changes,
87
- test evidence and review results. Integration still requires the user's review.
88
-
89
- Planning and verification read the assigned design from its local Git commit, so later design synchronization
90
- does not silently change a running delivery. The implementation plan is stored at
91
- `docs/delivery/<goal-id>/implementation-plan.md` and remains part of the delivered repository history.
92
-
93
- EngineerOS reads the curated [ACP agent registry](https://agentclientprotocol.com/registry), caches it for 24 hours, and uses the registry's pinned distribution for the current platform. The catalog includes Codex, Claude, Gemini, GitHub Copilot, Goose, OpenCode, Qwen Code, Cursor, and other compatible agents as they are published. List the current catalog, prepare the selected agent, then pair the workspace:
94
-
95
- ```sh
96
- npx --yes @engineeros/connector@latest agents
97
- npx --yes @engineeros/connector@latest agent gemini install
98
- npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard --agent gemini
99
- ```
100
-
101
- Registry `npx` and `uvx` packages are prepared with their native package runner. Registry binaries are downloaded into `~/.engineeros/agents`, checked against the published SHA-256 digest when present, and launched from that managed location. The connector checks the selected distribution before pairing. Agent processes stay alive while the connector is active, project conversations reuse their ACP sessions, and response chunks reach Copilot as the agent produces them.
102
-
103
- ## Pair an ACP coding agent
104
-
105
- Run the command from the repository the agent should work in:
106
-
107
- ```powershell
108
- npx --yes @engineeros/connector@latest pair PAIRING-CODE --url http://localhost:8000 --workspace . --onboard --agent-name "My ACP agent" --agent-command my-agent --agent-args '["--acp"]'
109
- ```
110
-
111
- `--agent-command` must start an ACP v1 agent over NDJSON stdio. `--agent-args` is a JSON array so arguments are passed without invoking a shell. Omit `--agent` and the custom command options to use the installed Codex CLI directly.
112
-
113
- Connect a local Codex CLI workspace to EngineerOS through an outbound WebSocket.
114
-
115
- ## Pair Forge
116
-
117
- [Forge](https://forgecode.dev) is driven through its own command line rather than ACP. Install it, sign in to a provider, then pair the workspace:
118
-
119
- ```sh
120
- forge provider login
121
- npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard --agent-protocol forge
122
- ```
123
-
124
- Forge runs its own agents, so `--agent` and `--agent-command` are rejected for this protocol. The connector selects the Forge agent that carries the access an assignment is entitled to: `sage` for read-only research, planning, assessment, and verification work, and `forge` for the writable implementation phase of a registered Goal. Pairing stops with the corrective command when Forge is missing, unauthenticated, or no longer provides both agents.
125
-
126
- Each EngineerOS session maps onto a Forge conversation, so project prompts and multi-stage assessments resume with their history intact. Token usage is reported per turn, measured as the growth of the conversation while the turn ran.
127
-
128
- Every model Forge offers through the providers you are signed in to is published to EngineerOS, named with its provider because the same model is offered by more than one, along with every reasoning effort Forge accepts. Forge takes the provider, model and reasoning effort of a run from the environment of its process, so the choice made in EngineerOS applies to that run alone: it does not change the model set with `forge config set model`, and it does not disturb a run beside it. The model and effort configured in Forge are marked as the default. Pairing stops when Forge offers no models, which means no provider is signed in: run `forge provider login`, then restart the connector.
129
-
130
- The connector registers the EngineerOS project artifact tools with Forge for the current user, which is the only scope Forge trusts without a person approving a file in the workspace, so nothing is written into the repository being worked on. Forge shares that one registration across every workspace and discovers the tools once, so the run each tool acts on is carried in the environment of the Forge process rather than in the registration. Concurrent runs stay separate, and a tool called outside an EngineerOS run is refused with the reason.
131
-
132
- ## Agent roles and skills
133
-
134
- The selected ACP, Forge, or Codex agent is the execution engine. EngineerOS chooses a provider-neutral role for each activity and the connector injects exactly one bundled skill:
135
-
136
- - `research` uses `project-research` to answer questions from observed project evidence.
137
- - `assessment` uses the internal `assessment-maintenance` skill to inspect source without changing it and edit only the assigned assessment Markdown document.
138
- - `planning` remains read-only and uses one server-selected skill: `product-discovery`, `experience-design`, `solution-design`, `requirements-and-acceptance`, or `delivery-planning`. Product discovery covers both intent discovery and capability shaping; delivery planning covers accepted greenfield slices and brownfield changes.
139
- - `implementation` uses `implementation` with workspace-write access only for a registered Goal.
140
- - `verification` uses `independent-verification` with read-only access for artifact review and independent Goal proof.
141
-
142
- This is intentionally a small executable catalog. Skills for hypothetical release, quality, or agent-workflow phases are not advertised until EngineerOS has a workflow that can invoke them. Harness-wide access, evidence, clarification, and output rules remain outside skill bodies, so an assignment pays only for the specialized judgment it needs. Direct Codex runs also disable ambient skill instructions; ACP providers receive the selected EngineerOS skill in the assignment prompt rather than the rest of the catalog.
143
-
144
- The connector rejects a role whose access does not match the assignment before starting the agent. Role-specific sessions preserve useful context without mixing planning, research, implementation, or verification responsibilities. A shared interaction contract makes the Agent infer the current project situation, lead with the useful outcome, and suggest one concrete next activity only when it genuinely helps. User-visible responses refer neutrally to the Agent; provider and harness details remain operational metadata.
145
-
146
- ## Onboard a workspace
147
-
148
- Create a connection command from **Project steering -> Connect workspace**, then run it inside the local folder:
149
-
150
- ```sh
151
- npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard
152
- ```
153
-
154
- The connector uploads a bounded ZIP snapshot for a safe file inventory, then stays online for deep assessments, rescans, and Goal Runs. Inventory never executes repository code. It excludes known secrets, dependency directories, build output, compiled binaries, files larger than 5 MB, agent-tool caches, Git metadata, and connector state before upload.
155
-
156
- From **Project steering -> Workspace**, run the workspace assessment to use the connected agent subscription already authenticated on that computer. Select any combination of fifteen brownfield assessment domains, collectively covering 133 internal checks from product and architecture through security, privacy, project-specific compliance, delivery, reliability, governance, and modernization planning. Reports include only material conclusions and actions; routine healthy checklist rows are not published. Capability entries state what they own, what they link to, and what they depend on. Connector `0.17.0` starts assessments with three parallel workers and accepts the run's UI-selected limit from three through eight for every coding-agent provider. It keeps one local assessment area at `.engineeros/assessment`: `assessment.md` is the canonical document, `sections/` holds the independently editable stage documents, `.work/` is the resumable transaction area, and an accepted update adds only a concise derived entry under `changes/`. A new run seeds each stage from its durable document, and a reconnect preserves any partially edited `.work` copy, so the coding agent updates affected content instead of regenerating the assessment. ACP agents such as OpenCode use isolated stage sessions within one persistent coding-agent process. The connector owns the worker pool and sends one aggregate heartbeat containing every active worker's phase, progress, last activity, and event count; report content is no longer streamed over the WebSocket or written into backend assessment JSON. The backend validates stage checkpoints so dependency fan-out remains authoritative, while the connector retains completed reports and reloads interrupted ACP or Codex sessions after reconnect when the coding agent supports session restoration. Transient ACP, app-server, provider-availability, and rate-limit failures receive two bounded attempts to continue the saved session without repeating completed inspection. A changed Git commit edits the same durable assessment, retains the prior commit in assessment history, and updates published artifacts in place. Connector reports and session checkpoints are tagged with their target commit so an earlier revision cannot leak into the update. If no assessment exists, EngineerOS creates the initial assessment identity and documents. Capability detail and project-specific compliance controls fan out after their catalogs. Final synthesis reads the connector-local Markdown files, then one completed bundle is revalidated, persisted, published as canonical artifacts, and archived locally. Compliance findings describe repository-verifiable engineering readiness and missing external context, never legal compliance or certification. The connector prints each worker's safe activity and elapsed time every 30 seconds, stops a worker that produces no agent activity for ten minutes instead of waiting indefinitely, and asks the same agent session to repair the same document when structure or backend validation fails. Assessment cannot modify tracked workspace source outside its assigned document.
157
-
158
- Every backend `422` content-validation response is returned to the stage agent with the exact failed item. Distinct validation failures continue through correction and resubmission until the complete stage is accepted. Three repetitions of the same unresolved validation error stop the automatic loop while preserving the latest local report for retry. Authentication, cancellation, source drift, and transport failures remain operational errors rather than agent-correction prompts.
159
-
160
- If Codex reports that its refresh token was already used, stop every connector process using Codex before reauthenticating. Run `codex logout`, then `codex login` in a normal terminal, and restart one connector with `start --workspace ...`. The existing EngineerOS workspace pairing remains valid. The connector stops the failed ACP runtime and reports these recovery steps without exposing its internal stack trace.
161
-
162
- Assessment runs start by reporting whether an accepted assessment exists and how stale it is. Every assigned stage still runs against the current repository revision; durable reports do not contain a trustworthy dependency manifest, so the connector never presents an old section as newly inspected. Connector-owned files under `.engineeros` are ignored before drafts or context packs are created and therefore do not pollute repository change scans.
163
-
164
- After onboarding, every project prompt is routed to this connection. Copilot, shaping, planning, architecture, and experience generation use the connected agent subscription and workspace context. Interactive prompts run independently from assessments and Goal scheduling. Prompt runs are read-only; only an explicitly registered Goal Run receives workspace-write access. If the connector is offline, EngineerOS asks the user to reconnect instead of silently switching models.
165
-
166
- Capability implementation planning uses committed local context in connector `0.32.0`. The synchronized
167
- `INDEX.md` links to the design, product intent, preparation context, decision revisions, implementation plans,
168
- current Facts and normalized Sources. A planning assignment carries the task, new guidance, record references
169
- and the expected snapshot revision; it does not resend those artifact bodies or an assignment-specific evidence
170
- copy. Before starting the agent, the connector checks the revision, saves the snapshot in local Git and supplies
171
- a `git show` pointer to that commit. All linked records are read from the same commit, so background sync does
172
- not change a running plan's input. The backend rechecks the context before saving a generated plan; stale input
173
- or invalid output leaves the accepted plan intact. No remote push is performed.
174
-
175
- Other greenfield generation prompts receive a bounded project-evidence manifest. EngineerOS normalizes uploaded text,
176
- PDF, DOCX, CSV, workbook, presentation, and image Sources, and the connector materializes normalized Markdown
177
- and available original attachments under an assignment-specific directory in `.engineeros/context/inputs/`.
178
- These files are connector-owned, ignored project
179
- context; the active coding agent reads them as untrusted evidence through ordinary file access. Only the most
180
- relevant Sources are included in each assignment. Normalized text is capped at one million characters and
181
- original attachments at 10 MB across the assignment so the WebSocket payload stays bounded; image, workbook,
182
- and presentation originals receive priority because their normalized text is only a descriptor. The connector
183
- removes the assignment directory after the Agent finishes.
184
-
185
- When material evidence or a user decision is missing, a generation Agent can return structured clarification
186
- questions instead of an artifact. EngineerOS stores and presents those questions, accepts free-text or newly
187
- uploaded evidence, and supplies answered clarifications when the same phase is retried. The connector does not
188
- hold a process or WebSocket request open while waiting for a user.
189
-
190
- The complete-product greenfield path performs that question review before each generation stage. After the user
191
- confirms the answers, connector `0.25.0` validates the Agent's complete structured Markdown bundle and atomically
192
- stores its files under `.engineeros/design/01-discovery` through `.engineeros/design/06-delivery`. Every stage has
193
- a manifest and remains directly editable by a human. Later stages read the approved earlier directories as their
194
- authoritative inputs. The planning Agent remains read-only: the connector, not the Agent process, owns the bounded
195
- local write, and an existing stage directory must be deleted explicitly before regeneration.
196
-
197
- Project prompts use resumable, role- and purpose-specific agent sessions. The connector keeps the external session identifiers in its local configuration, so Copilot and artifact conversations survive connector restarts. Changing the role, purpose, model, or reasoning effort starts a separate session. Goal implementation and verification remain isolated runs.
198
-
199
- An empty or document-only folder establishes a greenfield baseline. A code-bearing folder is assessed as brownfield. Use **Rescan** in Steering after the local workspace changes.
200
-
201
- ## Reconnect
202
-
203
- Connector 1.0.0 requires the updated EngineerOS backend. Upgrade both together, then restart the existing
204
- connector with `start`; its saved pairing remains valid. The WebSocket carries dispatch and control messages.
205
- Goal progress, assessment worker status, prompt output, failure reports and results use authenticated HTTP.
206
- There is no application JSON ping/pong. WebSocket protocol keepalive detects connection loss; quiet Goal work
207
- sends an HTTP heartbeat after 15 seconds without a progress update. Idle connectors need no application heartbeat.
208
-
209
- HTTP progress keeps one request in flight and retains the latest unsent state. Prompt deltas are ordered and
210
- bounded; a failed progress stream does not discard the final completed response. Requests have timeouts and
211
- bounded retries. Goal execution attempts and sequence numbers protect against delayed updates.
212
-
213
- Run the backend as **one worker and one replica**: dispatch sockets and pending prompt waiters currently live
214
- in process memory. The production image now uses one worker. Multiple backend workers require a shared dispatch
215
- broker before enabling them. An incompatible backend or connector fails with an upgrade instruction.
216
-
217
- ```sh
218
- npx --yes @engineeros/connector@latest start --workspace .
219
- ```
220
-
221
- Each workspace's settings are saved under `~/.engineeros/connectors` with owner-only permissions where supported. The connector token is not in that file: it is kept in the platform's protected store (Windows Data Protection, also under WSL; the macOS login Keychain; the Linux Secret Service), or, on a machine without one such as a headless Linux server or a container, in an owner-only file beside the settings. A token an earlier connector saved in the settings file is moved there the next time the connector reads it. If the store loses the token, `start` says so; pair again with a new pairing command.
222
- If a new pairing command is accidentally run from the same folder against the same EngineerOS server, the connector reuses this saved identity instead of creating another baseline assessment.
223
-
224
- ## Self-check
225
-
226
- Connector 1.12.0 checks itself and reports the result to EngineerOS, so a local problem is visible in **Project steering -> Connect workspace** instead of only in this terminal. The checks cover the Node runtime, the saved pairing, whether the EngineerOS backend answers from this machine, whether the coding agent starts, the tool registry, and stuck local Goal jobs.
227
-
228
- The report is sent when the connector connects, every five minutes while it is idle, and once more when a startup problem is about to stop it, which is the case EngineerOS could not see before: the workspace simply appeared offline. Run the same checks locally at any time, paired or not:
229
-
230
- ```sh
231
- npx --yes @engineeros/connector@latest doctor --workspace .
232
- ```
233
-
234
- The command prints every check with its reason and remedy, sends the report when the workspace is paired, and exits non-zero when a check failed.
235
-
236
- ## Local Git history
237
-
238
- Pairing or starting connector 0.31.0 initializes a local Git repository when the project has none and creates its initial commit from source files and durable design/assessment artifacts. An empty project also gets a usable baseline. Existing repositories and their pending source changes are preserved. Git must be installed; no remote is created and nothing is pushed.
239
-
240
- As design context syncs, the connector commits new, changed and deleted durable artifact files locally. These explicit artifact paths are included even though connector runtime state is ignored. Source generated by a capability is committed by the existing implementation and verification workflow on its capability branch. Environment secrets, credentials, dependency/build directories, context indexes and temporary handover files remain excluded. Identical snapshots produce no extra commits, and artifact sync waits while an implementation run is active.
241
-
242
- ## Run Goals
243
-
244
- From capability delivery, choose **Implement capability** and an online coding connector. EngineerOS prepares any missing implementation plan from the saved design, validates its prerequisites, and starts the run. **Preview plan** is optional; the detailed plan remains available without becoming a separate mandatory document review.
245
-
246
- The connector coordinates implementation, independent testing and independent code review. Native implementation subagents may work on independent tasks when the selected coding harness supports them. Testing and review run as separate read-only processes after the implementation is committed. At most two repair-and-review cycles follow the initial review; completed allowances survive resume. Repository finalization has its own single recovery attempt. Unresolved findings are then handed back with failed evidence instead of starting another repair. The handover includes the implementation report, exact revision, changed files and final check reports; persistent failures remain failed.
247
-
248
- Reuse existing shared foundations. A necessary out-of-scope prerequisite requires a recorded approval through `engineeros_request_input` with `decision_area: scope_expansion`, a stable question key, the precise addition and its reason and impact. Each run permits at most two expansion requests, including rejected or dismissed requests. Select **Approve scope expansion** in EngineerOS to authorize that specific addition; other answers do not authorize work. These approvals reach the implementer, independent reviewers and final handover. They do not reset the repair allowance or rewrite the original frozen Goal. Further expansion requires a separate Goal.
249
-
250
- When a consequential choice is missing, the implementation agent calls `engineeros_request_input` and finishes its turn. Answer the question in the active run using a suggestion or your own words. The connector keeps heartbeats active, preserves the workspace and resumes with the saved answer. Dismissal and cancellation never count as answers. Cancellation stops all workers in the run. This feature requires the updated backend and connector; it does not deploy the product or automatically approve its handover.
251
-
252
- Keep the connector online to receive Goals assigned from EngineerOS. Each run explicitly selects one workspace
253
- mode. `local_branch` creates or reuses the capability branch in the connected repository, runs with its exact
254
- local dependencies and properties, and returns to the original branch after a clean committed run. It is the
255
- default for a dedicated agent machine. Work left uncommitted on the current branch, staged or untracked, is
256
- stashed before the Goal branch is created and reapplied when the repository is handed back, so it never blocks
257
- a Goal and never becomes part of it. Ignored files are left in place. Work that no longer applies cleanly stays
258
- in `git stash list` with its recovery command reported on the run.
259
- `isolated_worktree` creates one durable worktree at `<project>/.engineeros/goals/<goal-id>` and reuses it
260
- across retries. The worktree shares Git configuration and hooks and copies individual ignored local configuration
261
- files; ignored dependency and build directories are not duplicated. The coding-agent process inherits the
262
- connector environment in both modes. Cancellation stops the agent. The connector returns changed paths, a bounded
263
- diff, and the exact repository ZIP; a human still performs independent attestation. Accepted work fast-forwards
264
- into an unchanged clean connected branch, or cherry-picks the complete Goal commit range onto a clean branch that
265
- advanced, then refreshes the workspace snapshot. Dirty or conflicting workspaces are never overwritten: the Goal
266
- branch remains available for explicit review and merge.
267
-
268
- During the writable implementation phase, Codex receives an authenticated EngineerOS MCP server automatically. It can list, read, create, update, reclassify, soft-delete, and materialize project artifacts into canonical Product records through the same repository boundary used by Copilot. The backend accepts those calls only while the assigned Goal is running. Read-only project prompts and the independent verification phase do not receive mutation tools.
269
-
270
- ### Resume a failed or interrupted Goal run
271
-
272
- Connector 0.34.0 keeps new isolated Goal worktrees inside the project at `.engineeros/goals/<goal-id>`.
273
- Execution checkpoints live at `.engineeros/runs/<run-id>`. Start the connector with its existing pairing,
274
- open the Goal's run panel and select **Resume run**. A disconnected running run becomes resumable after
275
- 90 seconds without a heartbeat. Offline resume requests wait for the assigned connector to reconnect.
276
-
277
- Resume preserves the run ID, frozen assignment, branch, files and completed implementation. It restores the
278
- agent session when supported and reruns interrupted verification. A completed result is retained for another
279
- upload attempt; changing the code causes it to be verified again. Existing worktrees are reused through Git's
280
- registry, so an upgrade does not move your current work. A missing workspace or corrupt checkpoint must be
281
- restored before resuming. Submitted results and final acceptance receipts retain their existing review flow.
282
-
283
- ## Local context engine
284
-
285
- The connector keeps a local index for each workspace under `~/.engineeros/context/<connector id>/workspaces/`: file classifications, symbols, document headings, and import relationships for every safe file. Separating indexes by resolved workspace keeps the source checkout and concurrent Goal worktrees from replacing one another. An index is built at onboarding, refreshed incrementally from file digests when EngineerOS triggers a workspace refresh, and re-checked before every assignment. Symbols in Python, JavaScript, TypeScript, Go, Java, Rust, Ruby and PHP come from tree-sitter syntax trees, using grammars shipped with the connector, so methods inside classes are indexed and `engineeros_read_symbol` returns exactly one declaration; other languages use line patterns.
286
-
287
- Before a workspace assessment stage runs, the connector also extracts repository facts from that index without a model: routes and pages, data models and migrations, integrations declared in dependency manifests, configuration keys, delivery and runtime files, and files that check authentication. They are cached per commit in `.engineeros/context/repository-facts.json`. Each stage receives only a bounded slice of the facts it starts from, with no full copy for an agent to read at once, and the capability catalog receives draft capability areas with their locations, so stages confirm a known inventory instead of rediscovering it.
288
-
289
- Every assignment prompt arrives with a bounded, task-ranked Markdown working set. It names the most relevant paths, symbol and heading locations, local dependencies, direct consumers, and candidate tests, followed by a pointer to the durable source map at `.engineeros/context/source-map.md`. The connector ranks from the assignment's focused context query, frozen Goal packet, assessment stage identity, or current project request as appropriate. It never pastes source-file contents into the prompt; the Agent reads deeper through the source map, the listed files, assessment sections, ordinary file tools, or the attached `engineeros_*` MCP tools. Ranking is structural and lexical, using indexed paths, symbols, summaries, and imports; it does not generate or store embeddings.
290
-
291
- Context preparation is a launch prerequisite for every role. The connector refreshes the correct workspace index, verifies that the source map exists, and stops before starting an agent with an actionable error when pairing identity, indexing, or map generation is unavailable. Resumed project sessions also receive a bounded `Session Memory` digest of relevant earlier turns in the same session, kept under `~/.engineeros/context/<connector id>/sessions/`, so follow-up prompts build on prior conclusions instead of re-deriving them. Entries carry a derived kind (fix, decision, change, or conclusion), and cross-session recall is stamped with its source session and last-active time.
292
-
293
- Every direct Codex assignment — project prompt, assessment, Goal implementation, and independent verification — receives the local read-only context MCP server with `engineeros_search`, `engineeros_outline`, `engineeros_read_symbol`, `engineeros_similar`, `engineeros_blast_radius`, and `engineeros_recall`. Registry-backed ACP adapters receive the same runtime-workspace server through `session/new` and `session/load`. Only a writable Goal implementation receives the authenticated EngineerOS artifact MCP server; project prompts, assessments, and verification never receive mutation tools. Custom ACP commands receive no injected servers because they have no registry MCP contract.
294
-
295
- After Goal implementation commits its isolated worktree change, the connector rebuilds context from that exact post-commit workspace before starting the independent verifier. Verification therefore receives the current task-ranked working set plus a bounded `Change Impact` section naming changed files, direct importers, and candidate tests rather than relying on the pre-change index. `engineeros_similar` helps the Agent extend existing functions, classes, and types instead of duplicating them. Stored symbol outlines omit literal constant values, MCP search responses are capped at one hundred files, and the index, source map, prompt context, and session memory remain on the local computer.
296
-
297
- ## Local design artifacts
298
-
299
- Connector 0.28.0 synchronizes persisted design records into
300
- `.engineeros/design/projects/<project-id>/`, with `INDEX.md` linking the named
301
- Markdown artifacts and their current review status. Sync runs on connection,
302
- every ten seconds, and before project prompts and Goal execution. Goal worktrees
303
- receive their own copy. Assignments point the agent to the index explicitly.
304
-
305
- The database remains authoritative. Confirm edits through EngineerOS Copilot;
306
- local changes are overwritten by the next successful sync. Renames and deletions
307
- remove outdated Markdown files from this managed directory. An offline connector
308
- refreshes when it reconnects. The backend must provide the matching design-context
309
- endpoint; sync failures are reported and block new agent tasks from using stale context.
310
-
311
- ## Autonomous work scan
312
-
313
- Connector 1.23.0 can tell EngineerOS what this workspace should deliver next. It scans only when the
314
- autonomy policy for the project asks it to: EngineerOS answers each five-minute self-check with whether
315
- it wants a scan, and an autonomy policy that is off, out of budget or already running a Goal never
316
- causes one. Turn it on, and off again, in **Project steering -> Autonomy**.
317
-
318
- When a scan is requested, the connector waits until nothing else is running here — no assessment stage,
319
- no prompt, no local Goal job — and then reads evidence that is already on disk: the synced design index,
320
- the local assessment, and Goal runs that stopped. One read-only agent turn ranks that evidence and names
321
- at most five capabilities worth starting, each with its reason. The turn has no write, command or tool
322
- access, and the scan repeats at most every thirty minutes.
323
-
324
- The connector never starts work of its own. Candidates are reported as evidence; EngineerOS re-validates
325
- every one against its own records, applies the policy, budget and concurrency limits, and decides whether
326
- to dispatch a Goal. A candidate naming a capability EngineerOS never published to this workspace is
327
- discarded before it is sent. A failing scan backs off like other maintenance and names itself in the
328
- self-check.
329
-
330
- Each report comes back with what EngineerOS turned down. The next scan asks for different work and drops
331
- a refused candidate even if the agent repeats it. When neither the workspace nor those refusals have
332
- changed, the shortlist is repeated from memory and no agent turn is spent at all, so an idle workspace
333
- costs nothing to keep watching.
334
-
335
- ## Requirements
336
-
337
- Node.js 22 or newer, Git, and an authenticated agent. `npx` distributions use npm, `uvx` distributions require uv, and binary archives require `tar` (`unzip` for ZIP files on Linux). Registry agents report their own authentication prerequisites when they start.
338
-
339
- ## Execution profiles
340
-
341
- EngineerOS can set a workspace default model and reasoning effort, then override either value for an individual Goal. The same workspace default is used for assessments, Copilot, and generated artifacts. The connector passes the resolved values to Codex CLI and reports unsupported profiles instead of silently ignoring them.
342
-
343
- Codex connectors advertise `gpt-5.6-sol` and `gpt-5.6-terra` by default. Override the choices shown in EngineerOS before starting the connector:
344
-
345
- ```sh
346
- ENGINEEROS_AGENT_MODELS="model-a,model-b" npx @engineeros/connector start --workspace .
347
- ```
348
-
349
- ## Codex CLI compatibility
350
-
351
- The connector prints the exact Codex CLI version it will use before connecting. If the
352
- configured model requires a newer CLI, update Codex and restart the connector:
353
-
354
- ```sh
355
- npm install -g @openai/codex@latest
356
- codex --version
357
- npx @engineeros/connector start --workspace .
358
- ```
359
-
360
- ## Supervisor recovery
361
-
362
- The workspace runner monitors worker health separately from progress reporting. Continuous reporting failures pause coding after one minute; missing worker health is detected after ninety seconds. Recovery preserves the sandbox and checkpoint. It allows one restart per failure category and at most two per run, with a cooldown and storage check before restarting.
363
-
364
- Unknown runtime failures may use one read-only LLM diagnosis per run through the configured agent, with a two-minute deadline. Known filesystem and network faults do not call an LLM. Diagnosis recommends retrying the checkpoint or a manual fix; it does not execute generated commands or modify the connector. Repeated failures stop automatic recovery. Inspect `runner status` and `.engineeros/runner/recovery/<run-id>.json`, fix the reported cause, then explicitly resume the existing run. Recovery budgets are retained.
365
-
366
- Verification results are cached per commit and role. Completed checks are reused. An interrupted check requires inspection before a new revision; it is not automatically billed again. Existing workers must load the new connector code before these protections apply.
367
-
368
- ## Updates without restarting
369
-
370
- `engineeros-connector start` keeps running across connector releases. It runs the connector as a child process; a release is installed into `~/.engineeros/connector/versions/<version>` beside the running one with `npm install --ignore-scripts`, checked against the registry's lockfile integrity, its npm registry signatures and the Node.js range it declares, and smoke-tested (`engineeros-connector version`) there before anything switches. When a release is activated, the connector waits until no assessment, connected prompt, integration request or local command is in flight, then restarts only its own process on the new release. EngineerOS, conversations and Goal runs are not interrupted: Goal workers run in their own processes. A release that stops before it ever reaches EngineerOS is rolled back automatically and not retried; the previous verified release stays installed for **Roll back**.
371
-
372
- The connector also keeps what it runs up to date:
373
-
374
- - **Coding agent.** A connector paired with an agent from the official ACP catalog (`--agent codex`, `claude`, `gemini` and so on) moves to the version the catalog lists now. It checks once connected, so EngineerOS never waits on the download, and then hourly, only while no Goal, prompt, assessment or hunt is running. The new version is installed and started once before the saved configuration changes; if either fails, the version that works stays and the next check tries again. Once switched, the connector signs in to EngineerOS again so the new version and its models show there. Saved conversations are kept; one the new version cannot load starts a new session that is sent the whole conversation.
375
- - **Tools.** On each start, every enabled tool set up from the catalog (Playwright, CodeGraph, ast-grep and the rest) moves to the newer reviewed pin this release ships, exactly as `tools upgrade` does; a tool that fails keeps its version, and a tool you rolled back stays rolled back until a later pin ships. Playwright's browser is then prepared for the Playwright version in use. Pins move to each tool's newest npm release every week: a scheduled job installs every moved pin through this setup, runs the tool tests and publishes a connector release.
376
-
377
- The `manual` update policy turns both off. Forge and Codex CLI (`--agent-protocol codex`) are your own global installs, which the connector never changes; when a newer release is out, the self-check (`doctor`, and the connector's diagnostics in EngineerOS) warns with the command to update it.
378
-
379
- ```sh
380
- engineeros-connector update # version, policy and state
381
- engineeros-connector update check # ask npm for the latest release
382
- engineeros-connector update apply # prepare (if needed) and activate it, including a major release
383
- engineeros-connector update rollback # switch back to the kept verified release
384
- engineeros-connector update policy approve # manual | approve | auto-patch | auto-minor
385
- ```
386
-
387
- `/update` at the connector's terminal and **Connector updates** under **Project → Steering → Local workspace** do the same; only the connector's owner can use them in EngineerOS. The default `approve` policy checks every six hours and prepares patch and minor releases, but activates one only when you approve it. `auto-patch` and `auto-minor` also activate those; a major release always waits for approval, and `manual` never checks on its own. Updates are shared by every connector on the machine. A connector started from a source checkout rather than the published package is updated with git, not from npm, and a connector run without `start` (for example under a service manager that sets `ENGINEEROS_CONNECTOR_SUPERVISED=1`) reports **Connector restart required** instead of switching itself.
388
-
389
- ## Integrations: GitHub, GitLab, Jira, Linear and monday.com
390
-
391
- EngineerOS holds no credentials for these services and none of them calls EngineerOS. When EngineerOS needs one (pull request review, Goal pull requests, repository import, backlog triage, filing defects in Linear), it asks the connector, which makes the call with this machine's own sign-in and sends back only the answer.
392
-
393
- ```sh
394
- engineeros-connector integrations # what this machine is signed in to
395
- gh auth login # GitHub, through the GitHub CLI
396
- glab auth login # GitLab, through the GitLab CLI
397
- engineeros-connector connect linear # prompts for a Linear API key
398
- engineeros-connector connect jira --site https://acme.atlassian.net --email you@acme.com
399
- engineeros-connector connect monday # prompts for a monday.com API token
400
- engineeros-connector disconnect linear # removes the key from this machine
401
- ```
402
-
403
- The GitHub and GitLab CLIs need not be installed beforehand. **Install** beside the machine in Admin → Integrations, or `connect github` / `connect gitlab` here, has the connector download the release it pins (GitHub CLI 2.102.0, GitLab CLI 1.120.0) from the vendor's own release page, refuse it unless it matches the SHA-256 recorded in `src/integration-install.mjs`, and unpack it into `~/.engineeros/tools/<tool>/<version>`. Only the connector uses that copy, and only when the tool is not already on PATH; nothing is installed system-wide. Then sign in: **Sign in** beside the machine in Admin → Integrations starts the CLI's own device sign-in here (`gh auth login --web`, `glab auth login --device`) and shows its one-time code and page in EngineerOS. Whoever approves the code becomes the machine's GitHub or GitLab identity, so only the machine's owner can start it; the CLI keeps the token in the system keyring, and an unapproved code is abandoned after 15 minutes. `gh auth login`, `glab auth login` or `connect github` / `connect gitlab` in a terminal work too.
404
-
405
- A token is read without echo (or from stdin when piped), checked with the provider, and kept in the platform's protected store: Windows Data Protection, the macOS login Keychain, or the Linux Secret Service (install `secret-tool` and run a keyring such as GNOME Keyring). Sign-ins belong to the machine's user, so every workspace connected on the machine shares them. The running connector reads them on each request; no restart is needed. EngineerOS can ask only for the operations the connector lists (`src/integration-requests.mjs`), each with checked arguments, and answers travel back over the connector's authenticated HTTP channel.
406
-
407
- ## Optional tool and plugin inventory
408
-
409
- Connector 1.7 advertises a curated candidate catalog alongside the operator-managed inventory. The catalog covers code intelligence, design, work management, source control, documentation, research, API development, browser testing, quality and security, data, infrastructure, observability and development environments. Candidate entries are metadata only: they are not installed, authenticated, admitted, started or exposed to coding agents.
410
-
411
- The catalog includes CodeGraph, Serena, JetBrains IDE MCP, ast-grep, Figma, Storybook, Miro, Lucid, Linear, monday.com, Atlassian Rovo, YouTrack, Notion, Slack, GitHub, GitLab, Context7, Postman, Exa, Tavily, Firecrawl, Perplexity, Playwright, Chrome DevTools, BrowserStack, Semgrep, SonarQube, Snyk, Gitleaks, Trivy, PostgreSQL MCP, Supabase, Terraform, AWS, Azure, Cloudflare, Vercel, Sentry, Grafana, Datadog, PagerDuty, Renovate, Dev Container CLI and Docker MCP Gateway. Each entry records its category, selection group, activation condition, eligible workflow profiles, provenance and default policy. Overlapping selection groups are alternatives, not permission to load every provider.
412
-
413
- Inspect the catalog and locally registered providers without starting software:
414
-
415
- ```sh
416
- engineeros-connector tools list --workspace PATH
417
- engineeros-connector tools register /absolute/path/manifest.json --workspace PATH
418
- engineeros-connector tools disable PROVIDER_ID --workspace PATH
419
- engineeros-connector tools disable all --workspace PATH
420
- engineeros-connector tools enable PROVIDER_ID --workspace PATH
421
- engineeros-connector tools remove PROVIDER_ID --workspace PATH
422
- engineeros-connector tools sign-in PROVIDER_ID --workspace PATH
423
- engineeros-connector tools auth-status PROVIDER_ID --workspace PATH
424
- engineeros-connector tools sign-out PROVIDER_ID --workspace PATH
425
- ```
426
-
427
- After pairing connector 1.8 or newer, open **Project → Steering → Local workspace → Tools and plugins** to search the catalog and control registered providers. The web UI can enable, disable and remove registrations through the authenticated connector session. Enabling and removal require confirmation. Registration remains local because its evaluated manifest contains machine paths and integrity metadata that are never advertised to EngineerOS.
428
-
429
- Use `enable all` to clear the global disable. Registration never installs packages or executes a provider. Providers set up from the catalog are installed into `tools/<provider>/<version>` beside the registry file; when a connector release ships a newer reviewed pin, the connector applies it to enabled tools when it next starts (see [Updates without restarting](#updates-without-restarting)), and **Update to** (or `tools upgrade PROVIDER_ID`) applies it at once after console approval. Either way it is installed into its own version directory, verified, and the registration pointed at it. New agent sessions use it with no restart; sessions already running keep the previous version, which stays installed for **Roll back to** (`tools rollback PROVIDER_ID`) as long as it still passes its integrity check. Replacing any other pin requires explicit removal and registration. Registry files live beside the user-owned connector configuration as `<workspace-key>.tools.json`, outside the repository. The connected workspace displays their inventory, refreshed through authenticated heartbeats. Stop any abandoned operator update before removing its `.tools.json.lock` file.
430
-
431
- Manifests are strict internal JSON configuration with these required fields:
432
-
433
- | Field | Required value |
434
- | --- | --- |
435
- | `id`, `name`, `provider`, `capability_class` | Stable lowercase ID, display labels and `tool`, `skill` or `agent`. |
436
- | `source`, `version`, `license` | Credential-free HTTPS source, exact semantic version and license. No `latest` or version range. |
437
- | `launch` | For `stdio` or skill `file`: `transport`, absolute `entrypoint`, absolute `package_json` and lowercase `sha256` of the entrypoint. For `https`: `transport` and credential-free `endpoint`. No commands, arguments or environment values are accepted. |
438
- | `platforms` | Array containing supported `win32`, `linux` and/or `darwin`. |
439
- | `permissions` | `workspace` (`none`, `read`, `write`), `process` boolean, `network` HTTPS URL array, `browser` (`none`, `isolated`), `secrets` reference-name array and `external_mutations` boolean. These record requests, not runtime grants. |
440
- | `authentication` | `none`, operator-owned `external` instructions, or `oauth` with exact scopes and either dynamic client registration or a provider-issued public client ID. Secret values are never accepted in a manifest. Older manifests without this field remain loadable but report setup required for HTTPS or secret-bearing providers. |
441
- | `profiles` | Array of `discovery`, `research`, `implementation`, `verification`, `handover`. |
442
- | `tasks`, `exclusions` | Arrays of lowercase task IDs; at least one eligible task. |
443
- | `tools` | Array of objects with `name` (`provider-id:operation_name`), concise `description`, and `response_mode` (`summary` or `reference`). |
444
- | `policy` | `approval_required: true`, `timeout_ms` from 100 to 30000, `retry_limit` 0 or 1. Reserved for bounded provider adapters; inspection executes nothing. |
445
- | `evidence` | `metadata-only`. |
446
- | `evaluation` | `status` (`experimental` or `standard`) and a real evidence `reference`. Standard status requires completed comparative evaluation. |
447
-
448
- At most 16 providers may be registered per workspace even though the read-only catalog is larger. Local files must be regular files (resolve symlinks before registration). Inspection compares installed package metadata and entrypoint bytes; it does not verify the entire dependency tree. Local version/hash mismatches and unavailable files report preparation actions. Registered HTTPS providers may use connector-managed OAuth: open **Tools and plugins**, choose **Sign in**, and complete consent in the browser opened on the connected machine. The connector follows MCP authorization discovery, uses PKCE with a loopback callback, and advertises only status, scopes and expiry. Windows protects the credential payload with current-user DPAPI outside the repository; unsupported platform keychains fail closed. Sign out deletes the local credential but does not remove the provider registration. MCP protocol, runtime and index health remain unchecked until a provider pilot implements them. Every entry remains execution-disabled, even if authentication succeeds. Launch paths, endpoints, tokens, authorization codes and raw file errors are excluded from advertised inventory. Do not put secrets in labels, URLs, descriptions or evidence references.
449
-
450
- ## Implement designed test cases
451
-
452
- In **Quality → Test design**, select cases marked **To automate**, choose **Generate automated tests**, and review the resulting testing Goal. Mark it ready and run it with the connected coding agent. The Goal freezes the selected case definitions and uses the repository's existing framework. Test design shows progress and links back to the same Goal for retries or revisions.
453
-
454
- Include exactly one designed case reference in each implemented test name, such as `TC-SIGN-001 rejects a wrong password` or Python's `test_TC_SIGN_001_wrong_password`. The frozen test command must produce per-case JUnit XML inside the workspace. The connector collects that measured report and the committed repository inventory; a comment containing the reference or an aggregate pass count does not establish coverage. Tests must have real assertions and be active and passing. QA then reviews whether the assertions implement the case's steps and expected results before the case becomes **Automated**.
455
-
456
- Use connector 1.40.0 with backend migration `20261015_000132`. If verification says the per-case report or inventory is missing, correct the reporting command or connector and continue through the existing Goal. Work and failed measurements are preserved. Delete the implementation Goal only when intentionally starting over; repeated selections reuse its ownership.
457
-
458
- ## Record CI test results
459
-
460
- Your CI can record each test suite's results in EngineerOS, where they sit beside manual and scheduled results on the project's Quality page, link to the test inventory, and open or resolve defects. No pairing is needed. Have your test runner write JUnit XML (pytest `--junitxml`, Vitest `--reporter=junit`, `jest-junit`, Playwright's `junit` reporter, `node --test --test-reporter=junit`, Maven Surefire, `go-junit-report`, `dotnet test --logger junit`), then run this after the tests, also when they failed:
461
-
462
- ```sh
463
- npx --yes @engineeros/connector@latest results upload --label backend --junit "reports/**/*.xml" --coverage coverage.xml
464
- ```
465
-
466
- Set three variables in the CI system: `ENGINEEROS_URL` (your EngineerOS address), `ENGINEEROS_API_TOKEN` (an organization API token with write access, from **Organization admin → API tokens**; keep it secret) and `ENGINEEROS_PROJECT_ID` (shown on the Quality page under **CI and schedules**). `--url`, `--token` and `--project-id` override them. The branch, commit and run link are read from GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, CircleCI and Bitbucket Pipelines; `--branch`, `--commit` and `--run-url` override them.
467
-
468
- `--junit` and `--coverage` take paths or globs (`*`, `?`, `[abc]`, `**`) and can be repeated; quote globs so the command expands them the same way on every platform. Coverage is a Cobertura XML or lcov report. One upload takes at most 50 JUnit and 20 coverage reports of up to 20 MB each.
469
-
470
- Recording results never fails your build: without the variables (a fork's pull request has no secrets) the command says so and exits 0, and a missing report or a failed upload is printed as a warning (a GitHub Actions or Azure Pipelines annotation where available) with exit code 0. Pass `--strict` to exit non-zero instead. The token is never printed.
471
-
472
- ### GitHub Action
473
-
474
- The `github-action` folder of this package is a composite action that runs the same command. It is published from a public repository rather than with the npm package:
475
-
476
- ```yaml
477
- - name: Record test results in EngineerOS
478
- if: ${{ !cancelled() }}
479
- uses: engineeros/connector/github-action@v1
480
- with:
481
- label: backend
482
- junit: |
483
- reports/junit.xml
484
- reports/e2e/*.xml
485
- coverage: coverage.xml
486
- url: ${{ vars.ENGINEEROS_URL }}
487
- token: ${{ secrets.ENGINEEROS_API_TOKEN }}
488
- project-id: ${{ vars.ENGINEEROS_PROJECT_ID }}
489
- ```
490
-
491
- Inputs: `label` and `junit` (required; one path or glob per line), `coverage`, `url`, `token`, `project-id` (each defaults to its `ENGINEEROS_*` variable), `strict` (`"true"` fails the step when the results cannot be recorded) and `connector-version` (defaults to the connector release the action belongs to). The action sets up Node.js 22 only when the runner does not already have it.
492
-
493
- ## Scheduled regression runs
494
-
495
- A project can schedule a test command on the Quality page (**CI and schedules**): a plain command line, the folder it runs in, a cron expression and its time zone, and optionally a test environment. When a run is due, EngineerOS sends it to an online connector of the person who last saved the schedule. The connector runs it exactly like a Goal's command Proof - without a shell, stopped after 15 minutes unless `ENGINEEROS_TEST_COMMAND_TIMEOUT_MS` says otherwise, with the output redacted - collects the JUnit and coverage reports the command wrote, and reports what it measured, together with the checked-out branch and commit. Scheduled runs on one connector run one at a time. When no connector is online the run is recorded as skipped, with the reason, and is not queued.
496
-
497
- ## Bug Hunter
498
-
499
- Bug Hunter tests a running test environment of the project (`bug_hunt.session`). The coding agent writes test cases; the connector runs them in a browser, with no model involved, so a recorded case is re-run on every new version for free. The connector does not need the project's code: a connector paired in an empty folder hunts from the project's EngineerOS artifacts.
500
-
501
- Both repository connectors and dedicated hunt hosts set up Playwright and check the browser each time `pair`, `start` or `hunt-host` connects; there is no separate setup command to run. They reuse working Google Chrome or Microsoft Edge, or download the Chromium version required by their managed Playwright tool. Bug Hunter becomes ready only after the browser starts successfully.
502
-
503
- To retry browser setup manually, point it at the connector's folder: `--project` for a hunt host, `--workspace` for a repository connector.
504
-
505
- ```bash
506
- npx --yes @engineeros/connector@latest tools setup playwright --project PROJECT_UUID # hunt host
507
- npx --yes @engineeros/connector@latest tools setup playwright --workspace . # in the repository
508
- ```
509
-
510
- On Linux, missing Chromium system libraries require administrator access. At a terminal, setup asks for your password; otherwise it prints the exact installation command to run. Download or launch failures are reported and can be retried with the command above. Installing the npm connector package alone does not download a browser; the connected workspace setup does.
511
-
512
- - **Catalogue runs** execute the recorded cases. A failure is run twice more from a fresh start: failing all three times it is reproduced, otherwise flaky.
513
- - **Hunts** run one agent turn in `.engineeros/bug-hunt/<session>/`. The agent writes each scenario as a case file in `cases/` and probes a draft with `node .engineeros/bug-hunt/<session>/probe.mjs <case file>`, which runs it through the same runner. Case files that cannot be read get one correction turn. The connector registers the cases with EngineerOS, which refuses duplicates, then runs each one.
514
- - **Review**: newly reproduced failures go to one reviewer turn in a fresh session. Its verdicts decide what becomes a bug.
515
- - **Rules of engagement** are enforced by the runner. Only the environment's hosts and the allowed hosts may be opened or written to. A step that a forbidden-action rule names (a quoted element name or a path) is refused.
516
- - **Stopping**: EngineerOS can stop a session at any time. Stop ends the agent's turn and still runs and reviews what it wrote; stop without review skips the review; abort ends everything at once.
517
- - **One at a time**: a hunt starts only while the coding agent is idle, and one session runs on a connector at a time. The session folder is removed when it ends.
518
- - **Versions**: when the environment's version path is set (a path such as `/version`, or `header:X-App-Version`), the connector reads it at the start of each session and reports it. EngineerOS then compares each page with the previous version.
519
- - **Command line**: a case's `run` step runs a program without a shell, in this folder, with the environment's variables and any input the case gives. Only programs the hunter allows may run.
520
- - **Locale, time zone and network**: `set locale` and `set time zone` shape the browser sessions a case starts after them. `set network` makes the current session `offline`, `online` or `slow` (Chromium throttling).
521
- - **Mobile web, budgets and jobs**: `set device` gives the sessions a case starts a phone's or tablet's screen, touch and browser (any device name Playwright knows), and `tap` touches an element. `responds within`, `loads within` and `largest contentful paint within` check timings. `poll` repeats a request every two seconds until its check holds, for background jobs.
522
- - **Local instance**: when the hunter has a launch command, the connector starts it from this checkout before the session. It waits up to three minutes for the environment's address to answer, and stops the whole process tree when the session ends.
523
-
524
- ## Bug Hunter app surfaces and production watch
525
-
526
- Configure the application surface in Bug Hunter Setup. Web uses the managed Playwright tool. Electron uses
527
- Playwright's Electron launcher and requires `ENGINEEROS_HUNT_HOST=dedicated` on a VM or spare machine. Give its
528
- executable path and arguments; the optional launch command builds it before the session. Each case starts with
529
- `open app`; the application closes at the end, and the environment's seed command runs before each case.
530
-
531
- WebDriver uses your team's Android (Appium/UiAutomator2) or Windows server. Add the server to Allowed hosts and
532
- write capabilities as Markdown, for example:
533
-
534
- ```markdown
535
- - platformName: Android
536
- - appium:automationName: UiAutomator2
537
- - appium:app: /apps/example.apk
538
- ```
539
-
540
- Use `testid` for accessibility ids, or a supported role and accessible name. The connector supports opening the app,
541
- clicking/tapping, filling, checking/unchecking, remembering element text and checking element text/value/state.
542
- Unsupported actions fail with a repair message. The authorization header is encrypted in Setup and delivered only
543
- to the assigned connector. No local device or desktop control is performed by Bug Hunter itself.
544
-
545
- A device-cloud Playwright endpoint makes `set device` connect to a real remote device. Configure a BrowserStack-compatible
546
- `caps` endpoint and encrypted `username:access key` credentials. Session counters show cloud sessions consumed.
547
-
548
- `looks like the baseline` compares PNG screenshots using a perceptual pixel diff. The default allowed difference is
549
- 0.1% of pixels. The first passing run records the page/viewport reference; a project operator can accept a new one
550
- from a finding. Baseline URLs refresh through the authenticated connector channel when their signatures expire.
551
-
552
- Flaky cases stay quarantined unless a fresh reviewer reproduces the failure through the case probe (at most five
553
- attempts), reads its screenshots and confirms a real bug. Those findings carry grade B; deterministic failures carry
554
- A. Session folders retain raw evidence for recovery.
555
-
556
- Production is never available to ordinary hunts or catalogue runs. The separate public-check schedule runs only
557
- cases a person marked production-safe, using `open`, `request GET`, checks and timing budgets, without accounts,
558
- seed commands, launch commands or write actions. Requests are paced and sessions start at least five minutes apart.
559
- A non-production hunter can also read its connected Sentry or Datadog tool hourly; imported signals guide staging
560
- hunts. A failed or unavailable monitoring query never becomes an empty successful result.
561
-
562
- To run the real Electron fixture, set `HUNT_ELECTRON_EXECUTABLE` to an installed Electron executable and
563
- `HUNT_PLAYWRIGHT_PACKAGE` to the absolute package.json path of the managed Playwright installation. The test skips
564
- when these prerequisites are absent.
565
-
566
-
567
- ### Backend storage and CI security reports
568
-
569
- Before starting Bug Hunter, configure the backend's `EVIDENCE_STORE_URL`, `EVIDENCE_STORE_BUCKET`,
570
- `EVIDENCE_STORE_ACCESS_KEY` and `EVIDENCE_STORE_SECRET` for a private S3-compatible bucket. The endpoint must be
571
- reachable by the backend, browsers and connectors that read signed images. Apply migration `20261021_000148`,
572
- then run `python -m src.bug_hunter.move_evidence` from `apps/backend`. The move can be resumed safely. The command
573
- clears database bytes only after each object upload succeeds. Keep the old columns until all environments have moved.
574
-
575
- Images are served through authenticated redirects to five-minute signed URLs. The daily sweep keeps passing
576
- snapshots for `EVIDENCE_RETENTION_DAYS` (14 by default), resolved-bug evidence for
577
- `EVIDENCE_RESOLVED_RETENTION_DAYS` (90), and the latest baseline for each environment, page and viewport.
578
- Open failure evidence is retained. Storage credentials never go to the connector.
579
-
580
- Your CI can upload a completed ZAP SARIF 2.1 report with project operator authentication to
581
- `POST /api/v1/projects/{project_id}/bug-hunter/hunters/{environment_id}/security-scan`.
582
- The API body has `report` (the SARIF object) and `complete` (a boolean). Set `complete: true` only for a successful
583
- full scan: only complete reports resolve missing findings. Uploads require an authorized non-production hunter,
584
- and every finding URL must be in its allowed hosts. Findings deduplicate by environment, rule and URL and can be
1
+ # EngineerOS Connector
2
+
3
+ The connector uses an authenticated EngineerOS WebSocket for pairing, workspace identity, run lifecycle, and evidence. Coding work can run through any agent in the official ACP registry, a custom ACP v1-compatible command over stdio, or the Forge command line. Direct Codex CLI remains available as the compatibility path.
4
+
5
+ ## Hunt a running app without a repository
6
+
7
+ Choose **Find bugs in a running app** in EngineerOS, register a preview or staging URL, and copy its command:
8
+
9
+ ```sh
10
+ npx --yes @engineeros/connector@latest hunt-host CODE --url https://your-backend.example --project PROJECT_UUID --agent codex-acp
11
+ ```
12
+
13
+ Use `claude-acp` for Claude. This installs the selected agent, pairs immediately, sets up Playwright and checks a browser
14
+ and agent session. It uses `~/.engineeros/hunt-hosts/PROJECT_UUID`; it never initializes or inspects a repository,
15
+ submits workspace snapshots, or starts a Goal runner. Keep this terminal open.
16
+
17
+ If prompted, run `codex login`, or run `claude` and `/login`, in another terminal on this machine. The host checks again
18
+ every 30 seconds for 30 minutes, then every five minutes. EngineerOS shows the same sign-in instructions.
19
+ If auto-start was selected, the first public-page hunt starts once readiness passes. Writing is limited to 10 minutes;
20
+ proving failures and reviewing them follow. Continuous hunting stays off, and failures are never retried automatically.
21
+
22
+ Restart a paired host with:
23
+
24
+ ```sh
25
+ npx --yes @engineeros/connector@latest hunt-host --project PROJECT_UUID
26
+ ```
27
+
28
+ Add test accounts in Bug Hunter Setup to go deeper. **Connect your code** opens the existing Steering connection flow
29
+ and pairs a separate connector in your repository. `hunt-host` refuses `--workspace` and `--onboard`.
30
+
31
+ ## Independent Goal runner
32
+
33
+ Connector 1.2.0 hands Goal jobs to a separate local runner. Closing the connector terminal or losing its WebSocket does not stop an executing Goal. Progress and final results use HTTP; undelivered results remain on disk for retry. Windows supervisors and workers use a windowless launcher; Goal runs and agent commands do not open new terminals.
34
+
35
+ Install explicitly, or let the first Goal dispatch install and start the runner:
36
+
37
+ ```text
38
+ engineeros-connector runner install --workspace D:\Puli\work\workspaces\caresched
39
+ engineeros-connector runner status --workspace D:\Puli\work\workspaces\caresched
40
+ ```
41
+
42
+ When started through `npx`, the connector installs that exact version into `~/.engineeros/connector/versions/<version>` with lifecycle scripts disabled, SHA-512 lockfile verification, npm registry signature checks and a version smoke test. Global installations and repository checkouts use their existing entry. A version change reinstalls the service; existing workers keep their code. Registry or verification failures leave Goals queued with a setup remedy. Update the backend for the HTTP claim endpoint before dispatching Goals.
43
+
44
+ Windows uses Task Scheduler under your current user, restarts after failure, and resumes saved jobs at sign-in following reboot. Linux uses a systemd user service; enable user lingering separately if recovery must start before login. Existing running jobs stay with their current process; resume an interrupted run to hand it to the new service.
45
+
46
+ On macOS, the runner is a per-user launchd agent in your GUI login session. It starts at login, retains your installer PATH and uses your signed-in coding agent and login Keychain. Expect a **Background Items Added** notice; manage it in **System Settings > General > Login Items**. A disabled runner stays queued until you enable it with `engineeros-connector runner start --workspace PATH`. `doctor` reports disabled, unloaded and failed services; startup output is in `.engineeros/runner/launchd.log`.
47
+
48
+ macOS can deny a background Node process access to Desktop, Documents, Downloads or iCloud Drive even when your terminal has access. Move the workspace elsewhere, or allow `node` in **Privacy & Security > Files and Folders**. During each Goal, `caffeinate -i -w <worker pid>` prevents idle sleep; it does not prevent lid-close sleep. Inactivity and heartbeat monitoring allow time to resume after sleep. To disable keep-awake for this workspace, run `engineeros-connector runner install --workspace PATH --keep-awake off` (use `on` to restore it). This saves `runner_keep_awake` in the paired connector configuration.
49
+
50
+ Remove the background service on any platform with `engineeros-connector runner uninstall --workspace PATH`. Queued jobs, checkpoints and results stay on disk and resume after installation. Running workers are independent of the service. Verified releases used by the runner are retained across updates until uninstall.
51
+
52
+ Files under your project's `.engineeros` directory:
53
+
54
+ - `runner/inbox/`: durable job dispatch requests.
55
+ - `runner/service.json`: supervisor PID and heartbeat.
56
+ - `runner/service.log`: supervisor startup and cleanup diagnostics.
57
+ - `runner/launchd.log`: macOS output before service logging starts.
58
+ - `runs/<run-id>/job.json`: execution/delivery status, saved assignment, pending result or failure.
59
+ - `runs/<run-id>/state.json`: coding session and implementation/verification checkpoints.
60
+ - `runs/<run-id>/activity.log`: timestamped activity and periodic inactivity status.
61
+ - `runs/<run-id>/worker.log`: worker console diagnostics.
62
+
63
+ The runner stops and records a resumable failure after ten minutes without agent events, except when explicitly waiting for user input. Restore missing prerequisites or agent usage before using **Resume run**. Acceptance and integration remain controlled by EngineerOS.
64
+
65
+ There is no wall-clock execution cutoff. Runs stop after at most two repair-and-review cycles following the initial review. The inactivity safeguard above still stops a silent agent; waiting for your answer does not consume a repair cycle. Successful results awaiting upload are not executed again.
66
+
67
+ Before the independent checks, the connector runs each frozen `command` Proof itself in the Goal worktree and sends the measured exit code, duration, best-effort pass/fail/skip counts and a 4000-character log tail as `test_run` evidence (`measured_by: "connector"`). A non-zero exit, or an exit 0 whose recognised summary counted no tests, fails that Proof and starts a repair cycle; the result is saved per revision so a resumed run does not run it again. Commands that need a shell (`&&`, pipes, redirects, globs), and commands whose executable is not installed, are not run and stay with the independent verifier. Each command and everything it started stops after 15 minutes unless `ENGINEEROS_TEST_COMMAND_TIMEOUT_MS` says otherwise, and a command that exits is measured even when a leftover process still holds its output. The implementation agent is told to add or update automated tests with its code, and the verifier and reviewer fail a change whose behavior has no tests.
68
+
69
+ ### Delete a Goal and its sandboxes
70
+
71
+ Choose **Delete Goal** in the Goal detail header and confirm. This deletes all revisions, runs, receipts, proof results, attachments and run questions for that Goal. Connected runners first stop every run in the revision family, then remove owned isolated Git worktrees (including uncommitted sandbox files), checkpoints, queued dispatches and logs. The source repository, its local changes, Git branches and unrelated worktrees are preserved. External registered worktrees require their matching saved checkpoints to establish ownership. Manually managed external environments remain the external runner's responsibility.
72
+
73
+ Deletion remains visible as **Deleting** until every assigned connector acknowledges cleanup. The supervisor polls authenticated cleanup requests every 15 seconds, including while the connector terminal is closed. Offline machines and lost acknowledgements retry safely. Cleanup errors are displayed on the Goal with **Retry cleanup**; a live worker lock or ambiguous sandbox ownership prevents removal. Active backend verification must finish before deletion starts. Small markers in `runner/deleted-runs/` prevent delayed dispatches from restarting deleted work.
74
+
75
+ After updating an existing installation, reinstall the runner task with `runner install` and restart the existing supervisor to load the new code. The Windows scheduled action must use `wscript.exe` and `runner/launch.vbs`. Logs remain in the project's `.engineeros` directory; no terminal is needed for a run.
76
+
77
+ If the Windows runner task was disabled, `engineeros-connector runner start --workspace PATH` explicitly enables it and starts processing queued jobs. Incoming dispatches remain queued while the task is disabled and print this recovery command; they do not enable it automatically. Do not resend the Goal just to start its queued job.
78
+
79
+
80
+ ## Connect an official ACP agent
81
+
82
+ Connector 0.33.0 supports **Deliver capability**. EngineerOS immediately queues the capability as a Goal request;
83
+ it does not generate or require approval of a separate implementation slice first. The coding agent reads the
84
+ frozen local design, writes its implementation plan inside the run worktree, then implements, tests and repairs
85
+ the work. Independent testing and review agents verify the delivered commit. Required user choices use the
86
+ existing run questions and resume the same work. The final handover includes the committed plan, source changes,
87
+ test evidence and review results. Integration still requires the user's review.
88
+
89
+ Planning and verification read the assigned design from its local Git commit, so later design synchronization
90
+ does not silently change a running delivery. The implementation plan is stored at
91
+ `docs/delivery/<goal-id>/implementation-plan.md` and remains part of the delivered repository history.
92
+
93
+ EngineerOS reads the curated [ACP agent registry](https://agentclientprotocol.com/registry), caches it for 24 hours, and uses the registry's pinned distribution for the current platform. The catalog includes Codex, Claude, Gemini, GitHub Copilot, Goose, OpenCode, Qwen Code, Cursor, and other compatible agents as they are published. List the current catalog, prepare the selected agent, then pair the workspace:
94
+
95
+ ```sh
96
+ npx --yes @engineeros/connector@latest agents
97
+ npx --yes @engineeros/connector@latest agent gemini install
98
+ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard --agent gemini
99
+ ```
100
+
101
+ Registry `npx` and `uvx` packages are prepared with their native package runner. Registry binaries are downloaded into `~/.engineeros/agents`, checked against the published SHA-256 digest when present, and launched from that managed location. The connector checks the selected distribution before pairing. Agent processes stay alive while the connector is active, project conversations reuse their ACP sessions, and response chunks reach Copilot as the agent produces them.
102
+
103
+ ## Pair an ACP coding agent
104
+
105
+ Run the command from the repository the agent should work in:
106
+
107
+ ```powershell
108
+ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url http://localhost:8000 --workspace . --onboard --agent-name "My ACP agent" --agent-command my-agent --agent-args '["--acp"]'
109
+ ```
110
+
111
+ `--agent-command` must start an ACP v1 agent over NDJSON stdio. `--agent-args` is a JSON array so arguments are passed without invoking a shell. Omit `--agent` and the custom command options to use the installed Codex CLI directly.
112
+
113
+ Connect a local Codex CLI workspace to EngineerOS through an outbound WebSocket.
114
+
115
+ ## Pair Forge
116
+
117
+ [Forge](https://forgecode.dev) is driven through its own command line rather than ACP. Install it, sign in to a provider, then pair the workspace:
118
+
119
+ ```sh
120
+ forge provider login
121
+ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard --agent-protocol forge
122
+ ```
123
+
124
+ Forge runs its own agents, so `--agent` and `--agent-command` are rejected for this protocol. The connector selects the Forge agent that carries the access an assignment is entitled to: `sage` for read-only research, planning, assessment, and verification work, and `forge` for the writable implementation phase of a registered Goal. Pairing stops with the corrective command when Forge is missing, unauthenticated, or no longer provides both agents.
125
+
126
+ Each EngineerOS session maps onto a Forge conversation, so project prompts and multi-stage assessments resume with their history intact. Token usage is reported per turn, measured as the growth of the conversation while the turn ran.
127
+
128
+ Every model Forge offers through the providers you are signed in to is published to EngineerOS, named with its provider because the same model is offered by more than one, along with every reasoning effort Forge accepts. Forge takes the provider, model and reasoning effort of a run from the environment of its process, so the choice made in EngineerOS applies to that run alone: it does not change the model set with `forge config set model`, and it does not disturb a run beside it. The model and effort configured in Forge are marked as the default. Pairing stops when Forge offers no models, which means no provider is signed in: run `forge provider login`, then restart the connector.
129
+
130
+ The connector registers the EngineerOS project artifact tools with Forge for the current user, which is the only scope Forge trusts without a person approving a file in the workspace, so nothing is written into the repository being worked on. Forge shares that one registration across every workspace and discovers the tools once, so the run each tool acts on is carried in the environment of the Forge process rather than in the registration. Concurrent runs stay separate, and a tool called outside an EngineerOS run is refused with the reason.
131
+
132
+ ## Agent roles and skills
133
+
134
+ The selected ACP, Forge, or Codex agent is the execution engine. EngineerOS chooses a provider-neutral role for each activity and the connector injects exactly one bundled skill:
135
+
136
+ - `research` uses `project-research` to answer questions from observed project evidence.
137
+ - `assessment` uses the internal `assessment-maintenance` skill to inspect source without changing it and edit only the assigned assessment Markdown document.
138
+ - `planning` remains read-only and uses one server-selected skill: `product-discovery`, `experience-design`, `solution-design`, `requirements-and-acceptance`, or `delivery-planning`. Product discovery covers both intent discovery and capability shaping; delivery planning covers accepted greenfield slices and brownfield changes.
139
+ - `implementation` uses `implementation` with workspace-write access only for a registered Goal.
140
+ - `verification` uses `independent-verification` with read-only access for artifact review and independent Goal proof.
141
+
142
+ This is intentionally a small executable catalog. Skills for hypothetical release, quality, or agent-workflow phases are not advertised until EngineerOS has a workflow that can invoke them. Harness-wide access, evidence, clarification, and output rules remain outside skill bodies, so an assignment pays only for the specialized judgment it needs. Direct Codex runs also disable ambient skill instructions; ACP providers receive the selected EngineerOS skill in the assignment prompt rather than the rest of the catalog.
143
+
144
+ The connector rejects a role whose access does not match the assignment before starting the agent. Role-specific sessions preserve useful context without mixing planning, research, implementation, or verification responsibilities. A shared interaction contract makes the Agent infer the current project situation, lead with the useful outcome, and suggest one concrete next activity only when it genuinely helps. User-visible responses refer neutrally to the Agent; provider and harness details remain operational metadata.
145
+
146
+ ## Onboard a workspace
147
+
148
+ Create a connection command from **Project steering -> Connect workspace**, then run it inside the local folder:
149
+
150
+ ```sh
151
+ npx --yes @engineeros/connector@latest pair PAIRING-CODE --url https://your-engineeros.example --workspace . --onboard
152
+ ```
153
+
154
+ The connector uploads a bounded ZIP snapshot for a safe file inventory, then stays online for deep assessments, rescans, and Goal Runs. Inventory never executes repository code. It excludes known secrets, dependency directories, build output, compiled binaries, files larger than 5 MB, agent-tool caches, Git metadata, and connector state before upload.
155
+
156
+ From **Project steering -> Workspace**, run the workspace assessment to use the connected agent subscription already authenticated on that computer. Select any combination of fifteen brownfield assessment domains, collectively covering 133 internal checks from product and architecture through security, privacy, project-specific compliance, delivery, reliability, governance, and modernization planning. Reports include only material conclusions and actions; routine healthy checklist rows are not published. Capability entries state what they own, what they link to, and what they depend on. Connector `0.17.0` starts assessments with three parallel workers and accepts the run's UI-selected limit from three through eight for every coding-agent provider. It keeps one local assessment area at `.engineeros/assessment`: `assessment.md` is the canonical document, `sections/` holds the independently editable stage documents, `.work/` is the resumable transaction area, and an accepted update adds only a concise derived entry under `changes/`. A new run seeds each stage from its durable document, and a reconnect preserves any partially edited `.work` copy, so the coding agent updates affected content instead of regenerating the assessment. ACP agents such as OpenCode use isolated stage sessions within one persistent coding-agent process. The connector owns the worker pool and sends one aggregate heartbeat containing every active worker's phase, progress, last activity, and event count; report content is no longer streamed over the WebSocket or written into backend assessment JSON. The backend validates stage checkpoints so dependency fan-out remains authoritative, while the connector retains completed reports and reloads interrupted ACP or Codex sessions after reconnect when the coding agent supports session restoration. Transient ACP, app-server, provider-availability, and rate-limit failures receive two bounded attempts to continue the saved session without repeating completed inspection. A changed Git commit edits the same durable assessment, retains the prior commit in assessment history, and updates published artifacts in place. Connector reports and session checkpoints are tagged with their target commit so an earlier revision cannot leak into the update. If no assessment exists, EngineerOS creates the initial assessment identity and documents. Capability detail and project-specific compliance controls fan out after their catalogs. Final synthesis reads the connector-local Markdown files, then one completed bundle is revalidated, persisted, published as canonical artifacts, and archived locally. Compliance findings describe repository-verifiable engineering readiness and missing external context, never legal compliance or certification. The connector prints each worker's safe activity and elapsed time every 30 seconds, stops a worker that produces no agent activity for ten minutes instead of waiting indefinitely, and asks the same agent session to repair the same document when structure or backend validation fails. Assessment cannot modify tracked workspace source outside its assigned document.
157
+
158
+ Every backend `422` content-validation response is returned to the stage agent with the exact failed item. Distinct validation failures continue through correction and resubmission until the complete stage is accepted. Three repetitions of the same unresolved validation error stop the automatic loop while preserving the latest local report for retry. Authentication, cancellation, source drift, and transport failures remain operational errors rather than agent-correction prompts.
159
+
160
+ If Codex reports that its refresh token was already used, stop every connector process using Codex before reauthenticating. Run `codex logout`, then `codex login` in a normal terminal, and restart one connector with `start --workspace ...`. The existing EngineerOS workspace pairing remains valid. The connector stops the failed ACP runtime and reports these recovery steps without exposing its internal stack trace.
161
+
162
+ Assessment runs start by reporting whether an accepted assessment exists and how stale it is. Every assigned stage still runs against the current repository revision; durable reports do not contain a trustworthy dependency manifest, so the connector never presents an old section as newly inspected. Connector-owned files under `.engineeros` are ignored before drafts or context packs are created and therefore do not pollute repository change scans.
163
+
164
+ After onboarding, every project prompt is routed to this connection. Copilot, shaping, planning, architecture, and experience generation use the connected agent subscription and workspace context. Interactive prompts run independently from assessments and Goal scheduling. Prompt runs are read-only; only an explicitly registered Goal Run receives workspace-write access. If the connector is offline, EngineerOS asks the user to reconnect instead of silently switching models.
165
+
166
+ Capability implementation planning uses committed local context in connector `0.32.0`. The synchronized
167
+ `INDEX.md` links to the design, product intent, preparation context, decision revisions, implementation plans,
168
+ current Facts and normalized Sources. A planning assignment carries the task, new guidance, record references
169
+ and the expected snapshot revision; it does not resend those artifact bodies or an assignment-specific evidence
170
+ copy. Before starting the agent, the connector checks the revision, saves the snapshot in local Git and supplies
171
+ a `git show` pointer to that commit. All linked records are read from the same commit, so background sync does
172
+ not change a running plan's input. The backend rechecks the context before saving a generated plan; stale input
173
+ or invalid output leaves the accepted plan intact. No remote push is performed.
174
+
175
+ Other greenfield generation prompts receive a bounded project-evidence manifest. EngineerOS normalizes uploaded text,
176
+ PDF, DOCX, CSV, workbook, presentation, and image Sources, and the connector materializes normalized Markdown
177
+ and available original attachments under an assignment-specific directory in `.engineeros/context/inputs/`.
178
+ These files are connector-owned, ignored project
179
+ context; the active coding agent reads them as untrusted evidence through ordinary file access. Only the most
180
+ relevant Sources are included in each assignment. Normalized text is capped at one million characters and
181
+ original attachments at 10 MB across the assignment so the WebSocket payload stays bounded; image, workbook,
182
+ and presentation originals receive priority because their normalized text is only a descriptor. The connector
183
+ removes the assignment directory after the Agent finishes.
184
+
185
+ When material evidence or a user decision is missing, a generation Agent can return structured clarification
186
+ questions instead of an artifact. EngineerOS stores and presents those questions, accepts free-text or newly
187
+ uploaded evidence, and supplies answered clarifications when the same phase is retried. The connector does not
188
+ hold a process or WebSocket request open while waiting for a user.
189
+
190
+ The complete-product greenfield path performs that question review before each generation stage. After the user
191
+ confirms the answers, connector `0.25.0` validates the Agent's complete structured Markdown bundle and atomically
192
+ stores its files under `.engineeros/design/01-discovery` through `.engineeros/design/06-delivery`. Every stage has
193
+ a manifest and remains directly editable by a human. Later stages read the approved earlier directories as their
194
+ authoritative inputs. The planning Agent remains read-only: the connector, not the Agent process, owns the bounded
195
+ local write, and an existing stage directory must be deleted explicitly before regeneration.
196
+
197
+ Project prompts use resumable, role- and purpose-specific agent sessions. The connector keeps the external session identifiers in its local configuration, so Copilot and artifact conversations survive connector restarts. Changing the role, purpose, model, or reasoning effort starts a separate session. Goal implementation and verification remain isolated runs.
198
+
199
+ An empty or document-only folder establishes a greenfield baseline. A code-bearing folder is assessed as brownfield. Use **Rescan** in Steering after the local workspace changes.
200
+
201
+ ## Reconnect
202
+
203
+ Connector 1.0.0 requires the updated EngineerOS backend. Upgrade both together, then restart the existing
204
+ connector with `start`; its saved pairing remains valid. The WebSocket carries dispatch and control messages.
205
+ Goal progress, assessment worker status, prompt output, failure reports and results use authenticated HTTP.
206
+ There is no application JSON ping/pong. WebSocket protocol keepalive detects connection loss; quiet Goal work
207
+ sends an HTTP heartbeat after 15 seconds without a progress update. Idle connectors need no application heartbeat.
208
+
209
+ HTTP progress keeps one request in flight and retains the latest unsent state. Prompt deltas are ordered and
210
+ bounded; a failed progress stream does not discard the final completed response. Requests have timeouts and
211
+ bounded retries. Goal execution attempts and sequence numbers protect against delayed updates.
212
+
213
+ Run the backend as **one worker and one replica**: dispatch sockets and pending prompt waiters currently live
214
+ in process memory. The production image now uses one worker. Multiple backend workers require a shared dispatch
215
+ broker before enabling them. An incompatible backend or connector fails with an upgrade instruction.
216
+
217
+ ```sh
218
+ npx --yes @engineeros/connector@latest start --workspace .
219
+ ```
220
+
221
+ Each workspace's settings are saved under `~/.engineeros/connectors` with owner-only permissions where supported. The connector token is not in that file: it is kept in the platform's protected store (Windows Data Protection, also under WSL; the macOS login Keychain; the Linux Secret Service), or, on a machine without one such as a headless Linux server or a container, in an owner-only file beside the settings. A token an earlier connector saved in the settings file is moved there the next time the connector reads it. If the store loses the token, `start` says so; pair again with a new pairing command.
222
+ If a new pairing command is accidentally run from the same folder against the same EngineerOS server, the connector reuses this saved identity instead of creating another baseline assessment.
223
+
224
+ ## Self-check
225
+
226
+ Connector 1.12.0 checks itself and reports the result to EngineerOS, so a local problem is visible in **Project steering -> Connect workspace** instead of only in this terminal. The checks cover the Node runtime, the saved pairing, whether the EngineerOS backend answers from this machine, whether the coding agent starts, the tool registry, and stuck local Goal jobs.
227
+
228
+ The report is sent when the connector connects, every five minutes while it is idle, and once more when a startup problem is about to stop it, which is the case EngineerOS could not see before: the workspace simply appeared offline. Run the same checks locally at any time, paired or not:
229
+
230
+ ```sh
231
+ npx --yes @engineeros/connector@latest doctor --workspace .
232
+ ```
233
+
234
+ The command prints every check with its reason and remedy, sends the report when the workspace is paired, and exits non-zero when a check failed.
235
+
236
+ ## Local Git history
237
+
238
+ Pairing or starting connector 0.31.0 initializes a local Git repository when the project has none and creates its initial commit from source files and durable design/assessment artifacts. An empty project also gets a usable baseline. Existing repositories and their pending source changes are preserved. Git must be installed; no remote is created and nothing is pushed.
239
+
240
+ As design context syncs, the connector commits new, changed and deleted durable artifact files locally. These explicit artifact paths are included even though connector runtime state is ignored. Source generated by a capability is committed by the existing implementation and verification workflow on its capability branch. Environment secrets, credentials, dependency/build directories, context indexes and temporary handover files remain excluded. Identical snapshots produce no extra commits, and artifact sync waits while an implementation run is active.
241
+
242
+ ## Run Goals
243
+
244
+ From capability delivery, choose **Implement capability** and an online coding connector. EngineerOS prepares any missing implementation plan from the saved design, validates its prerequisites, and starts the run. **Preview plan** is optional; the detailed plan remains available without becoming a separate mandatory document review.
245
+
246
+ The connector coordinates implementation, independent testing and independent code review. Native implementation subagents may work on independent tasks when the selected coding harness supports them. Testing and review run as separate read-only processes after the implementation is committed. At most two repair-and-review cycles follow the initial review; completed allowances survive resume. Repository finalization has its own single recovery attempt. Unresolved findings are then handed back with failed evidence instead of starting another repair. The handover includes the implementation report, exact revision, changed files and final check reports; persistent failures remain failed.
247
+
248
+ Reuse existing shared foundations. A necessary out-of-scope prerequisite requires a recorded approval through `engineeros_request_input` with `decision_area: scope_expansion`, a stable question key, the precise addition and its reason and impact. Each run permits at most two expansion requests, including rejected or dismissed requests. Select **Approve scope expansion** in EngineerOS to authorize that specific addition; other answers do not authorize work. These approvals reach the implementer, independent reviewers and final handover. They do not reset the repair allowance or rewrite the original frozen Goal. Further expansion requires a separate Goal.
249
+
250
+ When a consequential choice is missing, the implementation agent calls `engineeros_request_input` and finishes its turn. Answer the question in the active run using a suggestion or your own words. The connector keeps heartbeats active, preserves the workspace and resumes with the saved answer. Dismissal and cancellation never count as answers. Cancellation stops all workers in the run. This feature requires the updated backend and connector; it does not deploy the product or automatically approve its handover.
251
+
252
+ Keep the connector online to receive Goals assigned from EngineerOS. Each run explicitly selects one workspace
253
+ mode. `local_branch` creates or reuses the capability branch in the connected repository, runs with its exact
254
+ local dependencies and properties, and returns to the original branch after a clean committed run. It is the
255
+ default for a dedicated agent machine. Work left uncommitted on the current branch, staged or untracked, is
256
+ stashed before the Goal branch is created and reapplied when the repository is handed back, so it never blocks
257
+ a Goal and never becomes part of it. Ignored files are left in place. Work that no longer applies cleanly stays
258
+ in `git stash list` with its recovery command reported on the run.
259
+ `isolated_worktree` creates one durable worktree at `<project>/.engineeros/goals/<goal-id>` and reuses it
260
+ across retries. The worktree shares Git configuration and hooks and copies individual ignored local configuration
261
+ files; ignored dependency and build directories are not duplicated. The coding-agent process inherits the
262
+ connector environment in both modes. Cancellation stops the agent. The connector returns changed paths, a bounded
263
+ diff, and the exact repository ZIP; a human still performs independent attestation. Accepted work fast-forwards
264
+ into an unchanged clean connected branch, or cherry-picks the complete Goal commit range onto a clean branch that
265
+ advanced, then refreshes the workspace snapshot. Dirty or conflicting workspaces are never overwritten: the Goal
266
+ branch remains available for explicit review and merge.
267
+
268
+ During the writable implementation phase, Codex receives an authenticated EngineerOS MCP server automatically. It can list, read, create, update, reclassify, soft-delete, and materialize project artifacts into canonical Product records through the same repository boundary used by Copilot. The backend accepts those calls only while the assigned Goal is running. Read-only project prompts and the independent verification phase do not receive mutation tools.
269
+
270
+ ### Resume a failed or interrupted Goal run
271
+
272
+ Connector 0.34.0 keeps new isolated Goal worktrees inside the project at `.engineeros/goals/<goal-id>`.
273
+ Execution checkpoints live at `.engineeros/runs/<run-id>`. Start the connector with its existing pairing,
274
+ open the Goal's run panel and select **Resume run**. A disconnected running run becomes resumable after
275
+ 90 seconds without a heartbeat. Offline resume requests wait for the assigned connector to reconnect.
276
+
277
+ Resume preserves the run ID, frozen assignment, branch, files and completed implementation. It restores the
278
+ agent session when supported and reruns interrupted verification. A completed result is retained for another
279
+ upload attempt; changing the code causes it to be verified again. Existing worktrees are reused through Git's
280
+ registry, so an upgrade does not move your current work. A missing workspace or corrupt checkpoint must be
281
+ restored before resuming. Submitted results and final acceptance receipts retain their existing review flow.
282
+
283
+ ## Local context engine
284
+
285
+ The connector keeps a local index for each workspace under `~/.engineeros/context/<connector id>/workspaces/`: file classifications, symbols, document headings, and import relationships for every safe file. Separating indexes by resolved workspace keeps the source checkout and concurrent Goal worktrees from replacing one another. An index is built at onboarding, refreshed incrementally from file digests when EngineerOS triggers a workspace refresh, and re-checked before every assignment. Symbols in Python, JavaScript, TypeScript, Go, Java, Rust, Ruby and PHP come from tree-sitter syntax trees, using grammars shipped with the connector, so methods inside classes are indexed and `engineeros_read_symbol` returns exactly one declaration; other languages use line patterns.
286
+
287
+ Before a workspace assessment stage runs, the connector also extracts repository facts from that index without a model: routes and pages, data models and migrations, integrations declared in dependency manifests, configuration keys, delivery and runtime files, and files that check authentication. They are cached per commit in `.engineeros/context/repository-facts.json`. Each stage receives only a bounded slice of the facts it starts from, with no full copy for an agent to read at once, and the capability catalog receives draft capability areas with their locations, so stages confirm a known inventory instead of rediscovering it.
288
+
289
+ Every assignment prompt arrives with a bounded, task-ranked Markdown working set. It names the most relevant paths, symbol and heading locations, local dependencies, direct consumers, and candidate tests, followed by a pointer to the durable source map at `.engineeros/context/source-map.md`. The connector ranks from the assignment's focused context query, frozen Goal packet, assessment stage identity, or current project request as appropriate. It never pastes source-file contents into the prompt; the Agent reads deeper through the source map, the listed files, assessment sections, ordinary file tools, or the attached `engineeros_*` MCP tools. Ranking is structural and lexical, using indexed paths, symbols, summaries, and imports; it does not generate or store embeddings.
290
+
291
+ Context preparation is a launch prerequisite for every role. The connector refreshes the correct workspace index, verifies that the source map exists, and stops before starting an agent with an actionable error when pairing identity, indexing, or map generation is unavailable. Resumed project sessions also receive a bounded `Session Memory` digest of relevant earlier turns in the same session, kept under `~/.engineeros/context/<connector id>/sessions/`, so follow-up prompts build on prior conclusions instead of re-deriving them. Entries carry a derived kind (fix, decision, change, or conclusion), and cross-session recall is stamped with its source session and last-active time.
292
+
293
+ Every direct Codex assignment — project prompt, assessment, Goal implementation, and independent verification — receives the local read-only context MCP server with `engineeros_search`, `engineeros_outline`, `engineeros_read_symbol`, `engineeros_similar`, `engineeros_blast_radius`, and `engineeros_recall`. Registry-backed ACP adapters receive the same runtime-workspace server through `session/new` and `session/load`. Only a writable Goal implementation receives the authenticated EngineerOS artifact MCP server; project prompts, assessments, and verification never receive mutation tools. Custom ACP commands receive no injected servers because they have no registry MCP contract.
294
+
295
+ After Goal implementation commits its isolated worktree change, the connector rebuilds context from that exact post-commit workspace before starting the independent verifier. Verification therefore receives the current task-ranked working set plus a bounded `Change Impact` section naming changed files, direct importers, and candidate tests rather than relying on the pre-change index. `engineeros_similar` helps the Agent extend existing functions, classes, and types instead of duplicating them. Stored symbol outlines omit literal constant values, MCP search responses are capped at one hundred files, and the index, source map, prompt context, and session memory remain on the local computer.
296
+
297
+ ## Local design artifacts
298
+
299
+ Connector 0.28.0 synchronizes persisted design records into
300
+ `.engineeros/design/projects/<project-id>/`, with `INDEX.md` linking the named
301
+ Markdown artifacts and their current review status. Sync runs on connection,
302
+ every ten seconds, and before project prompts and Goal execution. Goal worktrees
303
+ receive their own copy. Assignments point the agent to the index explicitly.
304
+
305
+ The database remains authoritative. Confirm edits through EngineerOS Copilot;
306
+ local changes are overwritten by the next successful sync. Renames and deletions
307
+ remove outdated Markdown files from this managed directory. An offline connector
308
+ refreshes when it reconnects. The backend must provide the matching design-context
309
+ endpoint; sync failures are reported and block new agent tasks from using stale context.
310
+
311
+ ## Autonomous work scan
312
+
313
+ Connector 1.23.0 can tell EngineerOS what this workspace should deliver next. It scans only when the
314
+ autonomy policy for the project asks it to: EngineerOS answers each five-minute self-check with whether
315
+ it wants a scan, and an autonomy policy that is off, out of budget or already running a Goal never
316
+ causes one. Turn it on, and off again, in **Project steering -> Autonomy**.
317
+
318
+ When a scan is requested, the connector waits until nothing else is running here — no assessment stage,
319
+ no prompt, no local Goal job — and then reads evidence that is already on disk: the synced design index,
320
+ the local assessment, and Goal runs that stopped. One read-only agent turn ranks that evidence and names
321
+ at most five capabilities worth starting, each with its reason. The turn has no write, command or tool
322
+ access, and the scan repeats at most every thirty minutes.
323
+
324
+ The connector never starts work of its own. Candidates are reported as evidence; EngineerOS re-validates
325
+ every one against its own records, applies the policy, budget and concurrency limits, and decides whether
326
+ to dispatch a Goal. A candidate naming a capability EngineerOS never published to this workspace is
327
+ discarded before it is sent. A failing scan backs off like other maintenance and names itself in the
328
+ self-check.
329
+
330
+ Each report comes back with what EngineerOS turned down. The next scan asks for different work and drops
331
+ a refused candidate even if the agent repeats it. When neither the workspace nor those refusals have
332
+ changed, the shortlist is repeated from memory and no agent turn is spent at all, so an idle workspace
333
+ costs nothing to keep watching.
334
+
335
+ ## Requirements
336
+
337
+ Node.js 22 or newer, Git, and an authenticated agent. `npx` distributions use npm, `uvx` distributions require uv, and binary archives require `tar` (`unzip` for ZIP files on Linux). Registry agents report their own authentication prerequisites when they start.
338
+
339
+ ## Execution profiles
340
+
341
+ EngineerOS can set a workspace default model and reasoning effort, then override either value for an individual Goal. The same workspace default is used for assessments, Copilot, and generated artifacts. The connector passes the resolved values to Codex CLI and reports unsupported profiles instead of silently ignoring them.
342
+
343
+ Codex connectors advertise `gpt-5.6-sol` and `gpt-5.6-terra` by default. Override the choices shown in EngineerOS before starting the connector:
344
+
345
+ ```sh
346
+ ENGINEEROS_AGENT_MODELS="model-a,model-b" npx @engineeros/connector start --workspace .
347
+ ```
348
+
349
+ ## Codex CLI compatibility
350
+
351
+ The connector prints the exact Codex CLI version it will use before connecting. If the
352
+ configured model requires a newer CLI, update Codex and restart the connector:
353
+
354
+ ```sh
355
+ npm install -g @openai/codex@latest
356
+ codex --version
357
+ npx @engineeros/connector start --workspace .
358
+ ```
359
+
360
+ ## Supervisor recovery
361
+
362
+ The workspace runner monitors worker health separately from progress reporting. Continuous reporting failures pause coding after one minute; missing worker health is detected after ninety seconds. Recovery preserves the sandbox and checkpoint. It allows one restart per failure category and at most two per run, with a cooldown and storage check before restarting.
363
+
364
+ Unknown runtime failures may use one read-only LLM diagnosis per run through the configured agent, with a two-minute deadline. Known filesystem and network faults do not call an LLM. Diagnosis recommends retrying the checkpoint or a manual fix; it does not execute generated commands or modify the connector. Repeated failures stop automatic recovery. Inspect `runner status` and `.engineeros/runner/recovery/<run-id>.json`, fix the reported cause, then explicitly resume the existing run. Recovery budgets are retained.
365
+
366
+ Verification results are cached per commit and role. Completed checks are reused. An interrupted check requires inspection before a new revision; it is not automatically billed again. Existing workers must load the new connector code before these protections apply.
367
+
368
+ ## Updates without restarting
369
+
370
+ `engineeros-connector start` keeps running across connector releases. It runs the connector as a child process; a release is installed into `~/.engineeros/connector/versions/<version>` beside the running one with `npm install --ignore-scripts`, checked against the registry's lockfile integrity, its npm registry signatures and the Node.js range it declares, and smoke-tested (`engineeros-connector version`) there before anything switches. When a release is activated, the connector waits until no assessment, connected prompt, integration request or local command is in flight, then restarts only its own process on the new release. EngineerOS, conversations and Goal runs are not interrupted: Goal workers run in their own processes. A release that stops before it ever reaches EngineerOS is rolled back automatically and not retried; the previous verified release stays installed for **Roll back**.
371
+
372
+ The connector also keeps what it runs up to date:
373
+
374
+ - **Coding agent.** A connector paired with an agent from the official ACP catalog (`--agent codex`, `claude`, `gemini` and so on) moves to the version the catalog lists now. It checks once connected, so EngineerOS never waits on the download, and then hourly, only while no Goal, prompt, assessment or hunt is running. The new version is installed and started once before the saved configuration changes; if either fails, the version that works stays and the next check tries again. Once switched, the connector signs in to EngineerOS again so the new version and its models show there. Saved conversations are kept; one the new version cannot load starts a new session that is sent the whole conversation.
375
+ - **Tools.** On each start, every enabled tool set up from the catalog (Playwright, CodeGraph, ast-grep and the rest) moves to the newer reviewed pin this release ships, exactly as `tools upgrade` does; a tool that fails keeps its version, and a tool you rolled back stays rolled back until a later pin ships. Playwright's browser is then prepared for the Playwright version in use. Pins move to each tool's newest npm release every week: a scheduled job installs every moved pin through this setup, runs the tool tests and publishes a connector release.
376
+
377
+ The `manual` update policy turns both off. Forge and Codex CLI (`--agent-protocol codex`) are your own global installs, which the connector never changes; when a newer release is out, the self-check (`doctor`, and the connector's diagnostics in EngineerOS) warns with the command to update it.
378
+
379
+ ```sh
380
+ engineeros-connector update # version, policy and state
381
+ engineeros-connector update check # ask npm for the latest release
382
+ engineeros-connector update apply # prepare (if needed) and activate it, including a major release
383
+ engineeros-connector update rollback # switch back to the kept verified release
384
+ engineeros-connector update policy approve # manual | approve | auto-patch | auto-minor
385
+ ```
386
+
387
+ `/update` at the connector's terminal and **Connector updates** under **Project → Steering → Local workspace** do the same; only the connector's owner can use them in EngineerOS. The default `approve` policy checks every six hours and prepares patch and minor releases, but activates one only when you approve it. `auto-patch` and `auto-minor` also activate those; a major release always waits for approval, and `manual` never checks on its own. Updates are shared by every connector on the machine. A connector started from a source checkout rather than the published package is updated with git, not from npm, and a connector run without `start` (for example under a service manager that sets `ENGINEEROS_CONNECTOR_SUPERVISED=1`) reports **Connector restart required** instead of switching itself.
388
+
389
+ ## Integrations: GitHub, GitLab, Jira, Linear and monday.com
390
+
391
+ EngineerOS holds no credentials for these services and none of them calls EngineerOS. When EngineerOS needs one (pull request review, Goal pull requests, repository import, backlog triage, filing defects in Linear), it asks the connector, which makes the call with this machine's own sign-in and sends back only the answer.
392
+
393
+ ```sh
394
+ engineeros-connector integrations # what this machine is signed in to
395
+ gh auth login # GitHub, through the GitHub CLI
396
+ glab auth login # GitLab, through the GitLab CLI
397
+ engineeros-connector connect linear # prompts for a Linear API key
398
+ engineeros-connector connect jira --site https://acme.atlassian.net --email you@acme.com
399
+ engineeros-connector connect monday # prompts for a monday.com API token
400
+ engineeros-connector disconnect linear # removes the key from this machine
401
+ ```
402
+
403
+ The GitHub and GitLab CLIs need not be installed beforehand. **Install** beside the machine in Admin → Integrations, or `connect github` / `connect gitlab` here, has the connector download the release it pins (GitHub CLI 2.102.0, GitLab CLI 1.120.0) from the vendor's own release page, refuse it unless it matches the SHA-256 recorded in `src/integration-install.mjs`, and unpack it into `~/.engineeros/tools/<tool>/<version>`. Only the connector uses that copy, and only when the tool is not already on PATH; nothing is installed system-wide. Then sign in: **Sign in** beside the machine in Admin → Integrations starts the CLI's own device sign-in here (`gh auth login --web`, `glab auth login --device`) and shows its one-time code and page in EngineerOS. Whoever approves the code becomes the machine's GitHub or GitLab identity, so only the machine's owner can start it; the CLI keeps the token in the system keyring, and an unapproved code is abandoned after 15 minutes. `gh auth login`, `glab auth login` or `connect github` / `connect gitlab` in a terminal work too.
404
+
405
+ A token is read without echo (or from stdin when piped), checked with the provider, and kept in the platform's protected store: Windows Data Protection, the macOS login Keychain, or the Linux Secret Service (install `secret-tool` and run a keyring such as GNOME Keyring). Sign-ins belong to the machine's user, so every workspace connected on the machine shares them. The running connector reads them on each request; no restart is needed. EngineerOS can ask only for the operations the connector lists (`src/integration-requests.mjs`), each with checked arguments, and answers travel back over the connector's authenticated HTTP channel.
406
+
407
+ ## Optional tool and plugin inventory
408
+
409
+ Connector 1.7 advertises a curated candidate catalog alongside the operator-managed inventory. The catalog covers code intelligence, design, work management, source control, documentation, research, API development, browser testing, quality and security, data, infrastructure, observability and development environments. Candidate entries are metadata only: they are not installed, authenticated, admitted, started or exposed to coding agents.
410
+
411
+ The catalog includes CodeGraph, Serena, JetBrains IDE MCP, ast-grep, Figma, Storybook, Miro, Lucid, Linear, monday.com, Atlassian Rovo, YouTrack, Notion, Slack, GitHub, GitLab, Context7, Postman, Exa, Tavily, Firecrawl, Perplexity, Playwright, Chrome DevTools, BrowserStack, Semgrep, SonarQube, Snyk, Gitleaks, Trivy, PostgreSQL MCP, Supabase, Terraform, AWS, Azure, Cloudflare, Vercel, Sentry, Grafana, Datadog, PagerDuty, Renovate, Dev Container CLI and Docker MCP Gateway. Each entry records its category, selection group, activation condition, eligible workflow profiles, provenance and default policy. Overlapping selection groups are alternatives, not permission to load every provider.
412
+
413
+ Inspect the catalog and locally registered providers without starting software:
414
+
415
+ ```sh
416
+ engineeros-connector tools list --workspace PATH
417
+ engineeros-connector tools register /absolute/path/manifest.json --workspace PATH
418
+ engineeros-connector tools disable PROVIDER_ID --workspace PATH
419
+ engineeros-connector tools disable all --workspace PATH
420
+ engineeros-connector tools enable PROVIDER_ID --workspace PATH
421
+ engineeros-connector tools remove PROVIDER_ID --workspace PATH
422
+ engineeros-connector tools sign-in PROVIDER_ID --workspace PATH
423
+ engineeros-connector tools auth-status PROVIDER_ID --workspace PATH
424
+ engineeros-connector tools sign-out PROVIDER_ID --workspace PATH
425
+ ```
426
+
427
+ After pairing connector 1.8 or newer, open **Project → Steering → Local workspace → Tools and plugins** to search the catalog and control registered providers. The web UI can enable, disable and remove registrations through the authenticated connector session. Enabling and removal require confirmation. Registration remains local because its evaluated manifest contains machine paths and integrity metadata that are never advertised to EngineerOS.
428
+
429
+ Use `enable all` to clear the global disable. Registration never installs packages or executes a provider. Providers set up from the catalog are installed into `tools/<provider>/<version>` beside the registry file; when a connector release ships a newer reviewed pin, the connector applies it to enabled tools when it next starts (see [Updates without restarting](#updates-without-restarting)), and **Update to** (or `tools upgrade PROVIDER_ID`) applies it at once after console approval. Either way it is installed into its own version directory, verified, and the registration pointed at it. New agent sessions use it with no restart; sessions already running keep the previous version, which stays installed for **Roll back to** (`tools rollback PROVIDER_ID`) as long as it still passes its integrity check. Replacing any other pin requires explicit removal and registration. Registry files live beside the user-owned connector configuration as `<workspace-key>.tools.json`, outside the repository. The connected workspace displays their inventory, refreshed through authenticated heartbeats. Stop any abandoned operator update before removing its `.tools.json.lock` file.
430
+
431
+ Manifests are strict internal JSON configuration with these required fields:
432
+
433
+ | Field | Required value |
434
+ | --- | --- |
435
+ | `id`, `name`, `provider`, `capability_class` | Stable lowercase ID, display labels and `tool`, `skill` or `agent`. |
436
+ | `source`, `version`, `license` | Credential-free HTTPS source, exact semantic version and license. No `latest` or version range. |
437
+ | `launch` | For `stdio` or skill `file`: `transport`, absolute `entrypoint`, absolute `package_json` and lowercase `sha256` of the entrypoint. For `https`: `transport` and credential-free `endpoint`. No commands, arguments or environment values are accepted. |
438
+ | `platforms` | Array containing supported `win32`, `linux` and/or `darwin`. |
439
+ | `permissions` | `workspace` (`none`, `read`, `write`), `process` boolean, `network` HTTPS URL array, `browser` (`none`, `isolated`), `secrets` reference-name array and `external_mutations` boolean. These record requests, not runtime grants. |
440
+ | `authentication` | `none`, operator-owned `external` instructions, or `oauth` with exact scopes and either dynamic client registration or a provider-issued public client ID. Secret values are never accepted in a manifest. Older manifests without this field remain loadable but report setup required for HTTPS or secret-bearing providers. |
441
+ | `profiles` | Array of `discovery`, `research`, `implementation`, `verification`, `handover`. |
442
+ | `tasks`, `exclusions` | Arrays of lowercase task IDs; at least one eligible task. |
443
+ | `tools` | Array of objects with `name` (`provider-id:operation_name`), concise `description`, and `response_mode` (`summary` or `reference`). |
444
+ | `policy` | `approval_required: true`, `timeout_ms` from 100 to 30000, `retry_limit` 0 or 1. Reserved for bounded provider adapters; inspection executes nothing. |
445
+ | `evidence` | `metadata-only`. |
446
+ | `evaluation` | `status` (`experimental` or `standard`) and a real evidence `reference`. Standard status requires completed comparative evaluation. |
447
+
448
+ At most 16 providers may be registered per workspace even though the read-only catalog is larger. Local files must be regular files (resolve symlinks before registration). Inspection compares installed package metadata and entrypoint bytes; it does not verify the entire dependency tree. Local version/hash mismatches and unavailable files report preparation actions. Registered HTTPS providers may use connector-managed OAuth: open **Tools and plugins**, choose **Sign in**, and complete consent in the browser opened on the connected machine. The connector follows MCP authorization discovery, uses PKCE with a loopback callback, and advertises only status, scopes and expiry. Windows protects the credential payload with current-user DPAPI outside the repository; unsupported platform keychains fail closed. Sign out deletes the local credential but does not remove the provider registration. MCP protocol, runtime and index health remain unchecked until a provider pilot implements them. Every entry remains execution-disabled, even if authentication succeeds. Launch paths, endpoints, tokens, authorization codes and raw file errors are excluded from advertised inventory. Do not put secrets in labels, URLs, descriptions or evidence references.
449
+
450
+ ## Implement designed test cases
451
+
452
+ In **Quality → Test design**, select cases marked **To automate**, choose **Generate automated tests**, and review the resulting testing Goal. Mark it ready and run it with the connected coding agent. The Goal freezes the selected case definitions and uses the repository's existing framework. Test design shows progress and links back to the same Goal for retries or revisions.
453
+
454
+ Include exactly one designed case reference in each implemented test name, such as `TC-SIGN-001 rejects a wrong password` or Python's `test_TC_SIGN_001_wrong_password`. The frozen test command must produce per-case JUnit XML inside the workspace. The connector collects that measured report and the committed repository inventory; a comment containing the reference or an aggregate pass count does not establish coverage. Tests must have real assertions and be active and passing. QA then reviews whether the assertions implement the case's steps and expected results before the case becomes **Automated**.
455
+
456
+ Use connector 1.40.0 with backend migration `20261015_000132`. If verification says the per-case report or inventory is missing, correct the reporting command or connector and continue through the existing Goal. Work and failed measurements are preserved. Delete the implementation Goal only when intentionally starting over; repeated selections reuse its ownership.
457
+
458
+ ## Record CI test results
459
+
460
+ Your CI can record each test suite's results in EngineerOS, where they sit beside manual and scheduled results on the project's Quality page, link to the test inventory, and open or resolve defects. No pairing is needed. Have your test runner write JUnit XML (pytest `--junitxml`, Vitest `--reporter=junit`, `jest-junit`, Playwright's `junit` reporter, `node --test --test-reporter=junit`, Maven Surefire, `go-junit-report`, `dotnet test --logger junit`), then run this after the tests, also when they failed:
461
+
462
+ ```sh
463
+ npx --yes @engineeros/connector@latest results upload --label backend --junit "reports/**/*.xml" --coverage coverage.xml
464
+ ```
465
+
466
+ Set three variables in the CI system: `ENGINEEROS_URL` (your EngineerOS address), `ENGINEEROS_API_TOKEN` (an organization API token with write access, from **Organization admin → API tokens**; keep it secret) and `ENGINEEROS_PROJECT_ID` (shown on the Quality page under **CI and schedules**). `--url`, `--token` and `--project-id` override them. The branch, commit and run link are read from GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, CircleCI and Bitbucket Pipelines; `--branch`, `--commit` and `--run-url` override them.
467
+
468
+ `--junit` and `--coverage` take paths or globs (`*`, `?`, `[abc]`, `**`) and can be repeated; quote globs so the command expands them the same way on every platform. Coverage is a Cobertura XML or lcov report. One upload takes at most 50 JUnit and 20 coverage reports of up to 20 MB each.
469
+
470
+ Recording results never fails your build: without the variables (a fork's pull request has no secrets) the command says so and exits 0, and a missing report or a failed upload is printed as a warning (a GitHub Actions or Azure Pipelines annotation where available) with exit code 0. Pass `--strict` to exit non-zero instead. The token is never printed.
471
+
472
+ ### GitHub Action
473
+
474
+ The `github-action` folder of this package is a composite action that runs the same command. It is published from a public repository rather than with the npm package:
475
+
476
+ ```yaml
477
+ - name: Record test results in EngineerOS
478
+ if: ${{ !cancelled() }}
479
+ uses: engineeros/connector/github-action@v1
480
+ with:
481
+ label: backend
482
+ junit: |
483
+ reports/junit.xml
484
+ reports/e2e/*.xml
485
+ coverage: coverage.xml
486
+ url: ${{ vars.ENGINEEROS_URL }}
487
+ token: ${{ secrets.ENGINEEROS_API_TOKEN }}
488
+ project-id: ${{ vars.ENGINEEROS_PROJECT_ID }}
489
+ ```
490
+
491
+ Inputs: `label` and `junit` (required; one path or glob per line), `coverage`, `url`, `token`, `project-id` (each defaults to its `ENGINEEROS_*` variable), `strict` (`"true"` fails the step when the results cannot be recorded) and `connector-version` (defaults to the connector release the action belongs to). The action sets up Node.js 22 only when the runner does not already have it.
492
+
493
+ ## Scheduled regression runs
494
+
495
+ A project can schedule a test command on the Quality page (**CI and schedules**): a plain command line, the folder it runs in, a cron expression and its time zone, and optionally a test environment. When a run is due, EngineerOS sends it to an online connector of the person who last saved the schedule. The connector runs it exactly like a Goal's command Proof - without a shell, stopped after 15 minutes unless `ENGINEEROS_TEST_COMMAND_TIMEOUT_MS` says otherwise, with the output redacted - collects the JUnit and coverage reports the command wrote, and reports what it measured, together with the checked-out branch and commit. Scheduled runs on one connector run one at a time. When no connector is online the run is recorded as skipped, with the reason, and is not queued.
496
+
497
+ ## Onboarding baseline (existing tests, run once)
498
+
499
+ After a repository is onboarded, an operator can ask EngineerOS to run the project's existing tests once (**Run your existing tests once**). It costs no model tokens and is never started without that click, unless the project switched on automatic baselines.
500
+
501
+ - **What runs.** Every test runner the repository declares and that needs no running app: pytest, Vitest, Jest, `node --test`, `go test` and Maven or Gradle. Playwright and Cypress are left for a confirmed environment, and other runners (cargo, rspec, xunit, mocha ...) are listed as unsupported with the reason. Failures that look like missing services (connection refused, a missing environment variable) are reported as needing setup, not as product failures.
502
+ - **Where.** In a Git worktree of its own at the checkout's current commit, `.engineeros/test-workers/baseline`, with the checkout's dependency folders (`node_modules`, virtual environments) linked in. It measures committed code: your uncommitted edits and untracked files are not run.
503
+ - **What it writes.** Nothing in your checkout. Reports and coverage go to a temporary folder that is deleted when each shard settles. The worktree is reset at the next baseline. Nothing is installed: where a runner's coverage tooling is missing (no `pytest-cov`, no Vitest coverage provider) the runner still runs for the pass rate and flaky tests, and reports no coverage.
504
+ - **How.** Each runner's test files are cut into shards of about five minutes (about 40 files for pytest and `node --test`, 60 for Vitest and Jest, one package for Go, one module for Maven or Gradle) and run one after another; the shard's results are posted as soon as it settles, so a machine that sleeps keeps what already ran. A shard has no wall-clock limit; it is stopped only after ten minutes without output (`ENGINEEROS_BASELINE_IDLE_MS` changes that), which costs that shard and nothing else. Each failing test file is run twice more on its own, to tell a flaky test from a broken one. Runners run side by side only when you set several workers (`/workers`), at most three.
505
+ - **Turn it off.** Set `ENGINEEROS_QUALITY_BASELINE=off` in the connector's environment, or `"quality_baseline": false` in the connector's settings file. The connector then stops advertising the `quality_baseline` capability and refuses a baseline message.
506
+
507
+ ## Quality map and commit reports
508
+
509
+ With each workspace snapshot the connector sends a **quality map**, so EngineerOS can tell which tests a change reaches instead of flagging whole capabilities. It is built from the local context index and `git log`, runs no code from the repository and costs no model tokens:
510
+
511
+ - **Test footprints.** For each test file, the files its imports reach (three levels deep, with `tsconfig`/`jsconfig` `paths`, `baseUrl` and workspace package names resolved), and for browser tests the route files they visit. A file that many others import is recorded but not followed.
512
+ - **File facts.** Per code file over the last 180 days: commits, fix commits, authors, last change, lines, symbols and decision points. Author names are counted, never sent.
513
+ - **Inputs and launch recipes.** The files whose change should rerun everything (manifests, lockfiles, CI, migration folders, `conftest.py`), the app's routes and how it is started (`docker compose`, `npm run dev`, `uvicorn`, `manage.py`, Rails, Spring, Go). Nothing is started.
514
+
515
+ The connector also looks at `HEAD` on every maintenance tick (ten seconds). A new commit or a branch switch that stays put for three seconds is reported as a small delta: the changed files with their added and deleted line counts, the cases of the changed test files, and the map entries that moved. No snapshot is uploaded unless EngineerOS asks for one. Commits that only save EngineerOS's own artifacts are not reported. A workspace that is not a Git repository, and a hunt host, report nothing.
516
+
517
+ ## Bug Hunter
518
+
519
+ Bug Hunter tests a running test environment of the project (`bug_hunt.session`). The coding agent writes test cases; the connector runs them in a browser, with no model involved, so a recorded case is re-run on every new version for free. The connector does not need the project's code: a connector paired in an empty folder hunts from the project's EngineerOS artifacts.
520
+
521
+ Both repository connectors and dedicated hunt hosts set up Playwright and check the browser each time `pair`, `start` or `hunt-host` connects; there is no separate setup command to run. They reuse working Google Chrome or Microsoft Edge, or download the Chromium version required by their managed Playwright tool. Bug Hunter becomes ready only after the browser starts successfully.
522
+
523
+ To retry browser setup manually, point it at the connector's folder: `--project` for a hunt host, `--workspace` for a repository connector.
524
+
525
+ ```bash
526
+ npx --yes @engineeros/connector@latest tools setup playwright --project PROJECT_UUID # hunt host
527
+ npx --yes @engineeros/connector@latest tools setup playwright --workspace . # in the repository
528
+ ```
529
+
530
+ On Linux, missing Chromium system libraries require administrator access. At a terminal, setup asks for your password; otherwise it prints the exact installation command to run. Download or launch failures are reported and can be retried with the command above. Installing the npm connector package alone does not download a browser; the connected workspace setup does.
531
+
532
+ - **Catalogue runs** execute the recorded cases. A failure is run twice more from a fresh start: failing all three times it is reproduced, otherwise flaky.
533
+ - **Hunts** run one agent turn in `.engineeros/bug-hunt/<session>/`. The agent writes each scenario as a case file in `cases/` and probes a draft with `node .engineeros/bug-hunt/<session>/probe.mjs <case file>`, which runs it through the same runner. Case files that cannot be read get one correction turn. The connector registers the cases with EngineerOS, which refuses duplicates, then runs each one.
534
+ - **Review**: newly reproduced failures go to one reviewer turn in a fresh session. Its verdicts decide what becomes a bug.
535
+ - **What pages do on their own**: every run listens, without sending anything, for console and page errors, failed and 5xx or 404 requests, loading that never finishes, broken images and links and mixed content, scans each page once for serious accessibility violations (axe-core) and samples Web Vitals. A signal never changes a case's result. A cause that shows again on a clean re-run is sent to EngineerOS, which files it as a bug; nothing but text (messages, URLs without query values, selectors, numbers) leaves the machine. A production check only listens.
536
+ - **Routes and API calls**: a map also reads `robots.txt`, `sitemap.xml`, the application's own bundles and public source maps (and, in a checkout, its source) for routes, then presses navigation buttons and tabs with every write aborted. It records the application's own XHR and fetch calls as a map of endpoints, reduced to their shape; no response value is kept.
537
+ - **Rules of engagement** are enforced by the runner. Only the environment's hosts and the allowed hosts may be opened or written to. A step that a forbidden-action rule names (a quoted element name or a path) is refused.
538
+ - **Stopping**: EngineerOS can stop a session at any time. Stop ends the agent's turn and still runs and reviews what it wrote; stop without review skips the review; abort ends everything at once.
539
+ - **One at a time**: a hunt starts only while the coding agent is idle, and one session runs on a connector at a time. The session folder is removed when it ends.
540
+ - **Versions**: when the environment's version path is set (a path such as `/version`, or `header:X-App-Version`), the connector reads it at the start of each session and reports it. EngineerOS then compares each page with the previous version.
541
+ - **Command line**: a case's `run` step runs a program without a shell, in this folder, with the environment's variables and any input the case gives. Only programs the hunter allows may run.
542
+ - **Locale, time zone and network**: `set locale` and `set time zone` shape the browser sessions a case starts after them. `set network` makes the current session `offline`, `online` or `slow` (Chromium throttling).
543
+ - **Mobile web, budgets and jobs**: `set device` gives the sessions a case starts a phone's or tablet's screen, touch and browser (any device name Playwright knows), and `tap` touches an element. `responds within`, `loads within` and `largest contentful paint within` check timings. `poll` repeats a request every two seconds until its check holds, for background jobs.
544
+ - **Local instance**: when the hunter has a launch command, the connector starts it from this checkout before the session. It waits up to three minutes for the environment's address to answer, and stops the whole process tree when the session ends.
545
+
546
+ ## Bug Hunter app surfaces and production watch
547
+
548
+ Configure the application surface in Bug Hunter Setup. Web uses the managed Playwright tool. Electron uses
549
+ Playwright's Electron launcher and requires `ENGINEEROS_HUNT_HOST=dedicated` on a VM or spare machine. Give its
550
+ executable path and arguments; the optional launch command builds it before the session. Each case starts with
551
+ `open app`; the application closes at the end, and the environment's seed command runs before each case.
552
+
553
+ WebDriver uses your team's Android (Appium/UiAutomator2) or Windows server. Add the server to Allowed hosts and
554
+ write capabilities as Markdown, for example:
555
+
556
+ ```markdown
557
+ - platformName: Android
558
+ - appium:automationName: UiAutomator2
559
+ - appium:app: /apps/example.apk
560
+ ```
561
+
562
+ Use `testid` for accessibility ids, or a supported role and accessible name. The connector supports opening the app,
563
+ clicking/tapping, filling, checking/unchecking, remembering element text and checking element text/value/state.
564
+ Unsupported actions fail with a repair message. The authorization header is encrypted in Setup and delivered only
565
+ to the assigned connector. No local device or desktop control is performed by Bug Hunter itself.
566
+
567
+ A device-cloud Playwright endpoint makes `set device` connect to a real remote device. Configure a BrowserStack-compatible
568
+ `caps` endpoint and encrypted `username:access key` credentials. Session counters show cloud sessions consumed.
569
+
570
+ `looks like the baseline` compares PNG screenshots using a perceptual pixel diff. The default allowed difference is
571
+ 0.1% of pixels. The first passing run records the page/viewport reference; a project operator can accept a new one
572
+ from a finding. Baseline URLs refresh through the authenticated connector channel when their signatures expire.
573
+
574
+ Flaky cases stay quarantined unless a fresh reviewer reproduces the failure through the case probe (at most five
575
+ attempts), reads its screenshots and confirms a real bug. Those findings carry grade B; deterministic failures carry
576
+ A. Session folders retain raw evidence for recovery.
577
+
578
+ Production is never available to ordinary hunts or catalogue runs. The separate public-check schedule runs only
579
+ cases a person marked production-safe, using `open`, `request GET`, checks and timing budgets, without accounts,
580
+ seed commands, launch commands or write actions. Requests are paced and sessions start at least five minutes apart.
581
+ A non-production hunter can also read its connected Sentry or Datadog tool hourly; imported signals guide staging
582
+ hunts. A failed or unavailable monitoring query never becomes an empty successful result.
583
+
584
+ To run the real Electron fixture, set `HUNT_ELECTRON_EXECUTABLE` to an installed Electron executable and
585
+ `HUNT_PLAYWRIGHT_PACKAGE` to the absolute package.json path of the managed Playwright installation. The test skips
586
+ when these prerequisites are absent.
587
+
588
+
589
+ ### Backend storage and CI security reports
590
+
591
+ Before starting Bug Hunter, configure the backend's `EVIDENCE_STORE_URL`, `EVIDENCE_STORE_BUCKET`,
592
+ `EVIDENCE_STORE_ACCESS_KEY` and `EVIDENCE_STORE_SECRET` for a private S3-compatible bucket. The endpoint must be
593
+ reachable by the backend, browsers and connectors that read signed images. Apply migration `20261021_000148`,
594
+ then run `python -m src.bug_hunter.move_evidence` from `apps/backend`. The move can be resumed safely. The command
595
+ clears database bytes only after each object upload succeeds. Keep the old columns until all environments have moved.
596
+
597
+ Images are served through authenticated redirects to five-minute signed URLs. The daily sweep keeps passing
598
+ snapshots for `EVIDENCE_RETENTION_DAYS` (14 by default), resolved-bug evidence for
599
+ `EVIDENCE_RESOLVED_RETENTION_DAYS` (90), and the latest baseline for each environment, page and viewport.
600
+ Open failure evidence is retained. Storage credentials never go to the connector.
601
+
602
+ Your CI can upload a completed ZAP SARIF 2.1 report with project operator authentication to
603
+ `POST /api/v1/projects/{project_id}/bug-hunter/hunters/{environment_id}/security-scan`.
604
+ The API body has `report` (the SARIF object) and `complete` (a boolean). Set `complete: true` only for a successful
605
+ full scan: only complete reports resolve missing findings. Uploads require an authorized non-production hunter,
606
+ and every finding URL must be in its allowed hosts. Findings deduplicate by environment, rule and URL and can be
585
607
  triaged and filed through Findings. The connector does not run ZAP; CI owns the scanner and policy.
608
+
609
+ ## Third-party code
610
+
611
+ Accessibility scans use [axe-core](https://github.com/dequelabs/axe-core) (MPL-2.0), installed as an unmodified npm dependency and never edited or bundled into other files.