# Local simulator: business-mcp → code orchestrator

Exercises the same connector path as MCP `request_code_change` / `get_code_change_status` without starting the full MCP HTTP server.

## Setup

1. Copy env template (do not commit secrets):

   ```bash
   cp scripts/simulate-code-change.env.example scripts/simulate-code-change.env
   # Edit ORCHESTRATOR token + URL
   ```

2. Required variables (also work via shell export):

   | Variable | Example |
   | -------- | ------- |
   | `LUCOS_POLICY_ENABLED` | `true` |
   | `LUCOS_TOOL_ENABLE_REQUEST_CODE_CHANGE` | `true` |
   | `LUCOS_TOOL_ENABLE_GET_CODE_CHANGE_STATUS` | `true` |
   | `LUCOS_CODE_ORCHESTRATOR_URL` | `http://129.153.35.111:3340` |
   | `LUCOS_CODE_ORCHESTRATOR_TOKEN` | from server `ORCHESTRATOR_AUTH_TOKEN` |
   | `LUCOS_COLLAB_SERVICE_URL` | slack-bot hop for `jira_create_issue` (required unless `--jira-key` or `--skip-jira`) |
   | `SIMULATOR_JIRA_PROJECT` | `TW` (default) |

## Run (Direqt Search `search` repo → PR on `dev`)

```bash
npm run simulate:code-change -- --repo-hint search --target dev
```

Creates a Jira ticket first (project `TW` unless `--jira-project` / `SIMULATOR_JIRA_PROJECT`), then submits the change job with that key so the branch is `ai/TW-####`. Pass `--jira-key TW-353` to reuse an existing ticket, or `--skip-jira` for the old random `ai/run-*` branch.

## Direqt security posture (all suite repos → one PR each)

Documentation-only baseline (`SECURITY.md`, `docs/security-posture.md`, optional `security:audit` npm script):

```bash
npm run simulate:direqt-security
```

Uses each repo’s `default_branch` from `registry/ai-services/direqt-search.yml` (suite default `dev`; libraries often `main`). Override with `--target dev` if needed.

Options: `--only search,api` · `--skip docs,terraform` · `--dry-run`

Jira (required unless you pass a key or skip):

- Default: create one ticket, then every repo job uses `jira_key` so branches are `ai/<KEY>`
- `--jira-key TW-9999` — reuse an existing ticket (no create)
- `--jira-project TW` — project for the created ticket (default `TW`)
- `--skip-jira` — old behavior: orchestrator random `ai/run-*` branch

Other options:

- `--requirement "..."` — override smoke prompt
- `--poll-ms 8000 --max-polls 120` — poll after submit (orchestrator may return terminal status in the POST body already)
- `--dry-run` — print args only

## Direqt Search repo hints

Registry service **name** equals GitHub repo slug (`search`, `api`, `console`, …). Use `--repo-hint <slug>`.

## Server-side checklist for a real PR

On the code-runner (SSH user e.g. `slackautomation`):

1. `GITHUB_TOKEN` on orchestrator (PAT with **repo** access) — used for HTTPS **clone/push** and PR API (no GitHub deploy key required when token is set)
2. PAT must reach `direqt-search/*` private repos if applicable
3. `CURSOR_API_KEY` for edits
4. `WORKSPACE_ROOT` writable by SSH user

If clone fails with `Permission denied (publickey)`, fix GitHub access for the SSH identity used by the orchestrator.
