C1 Identity & least privilege
Minimal 0.00 / 1.00
career-ops has no identity of its own. It runs inside your AI coding CLI as your OS user, and the scripts it tells the agent to run inherit your full environment. The job sources it scans are public and need no login, and no credential is required by default. But nothing narrows what the agent's shell session can reach: your git, cloud and SSH credentials stay reachable, and plugin code gets all of process.env. A hijacked session therefore holds everything you hold.
C2 Approval gates
Minimal 0.05 / 1.00
career-ops ships no approval gate of its own. In the interactive mode it relies on the host CLI's permission prompts. Those prompts are not part of this repository and are not credited here. Its own consent checks, for applying a self-update and for enabling a plugin, are passed by a --confirm command-line flag that the agent can add itself. The documented batch runner turns the host's prompts off by default with --dangerously-skip-permissions. What career-ops gets right is the reach of its own code: no script submits an application or sends email, and the updater keeps a backup branch with rollback.
C3 Tool & action scoping
Minimal 0.40 / 1.00
The network code career-ops owns is careful. Scanner providers use per-provider host allowlists, refuse redirects, and check resolved IP addresses against private ranges at DNS time. Plugin HTTP goes through an HTTPS host allowlist that re-checks redirects. The Playwright browser paths are weaker; their address guard does not cover every path. And the workflow drives everything through a general shell with write and network tools on by default. The opt-in web UI adds per-worker tool allowlists (read-only and no-network scopes for PDF and research), but its evaluation workers still get unrestricted Bash and WebFetch.
C4 Code-execution isolation
Minimal 0.15 / 1.00
Nothing career-ops runs is isolated. The scripts, the Playwright automation and the headless batch workers all run on the host as the user. The batch workers also run with the host CLI's permission prompts disabled. The shipped Docker setup is a compatibility option, not a sandbox: the container runs as root, mounts the whole project read-write, has open network access, and receives your API keys. The agent's own shell still runs on the host anyway.
C5 Untrusted input blast radius
Minimal 0.25 / 1.00
career-ops reads untrusted text all day: job postings, company pages, application forms and recruiter emails. The defence against injected instructions in that text is a strongly worded section of AGENTS.md telling the model to treat it as data, and a CI check that the warning text appears in every mode. Community plugin skill text is printed under an UNTRUSTED banner, but postings and pages reach the model unmarked. Those same sessions hold your CV and personal details and have network and shell access. Nothing in the code stops a hijacked session from leaking that data or acting on it.
C6 Memory, context & configuration integrity
Minimal 0.10 / 1.00
career-ops is built to remember. The model is told to write your lasting preferences and 'automations' into modes/_custom.md, and every mode loads that file as binding instructions. data/agent-inbox.md is a queue of requests that any script or tool can append to, and the agent runs the open items top to bottom. Neither file is validated, tagged with its source, or gated. A single injection that lands in either one fires in every later session. Separately, plugin enablement from workspace configuration is not integrity-protected.
C7 Third-party extensions
Minimal 0.38 / 1.00
Plugins are off by default. The community registry pins every plugin to an exact 40-character commit. Installation clones that commit with risky git transports disabled, runs a static audit, and records a sha256 hash of every file. Changed files load only if the version number changed; if allowed hosts or keys expand, the user must consent again. The weak points: a version bump re-pins quietly without fresh consent, enabling is a --confirm flag the agent can pass, and the consent flow is not tamper-resistant in other respects. Plugins also run inside the same Node process with full access to process.env.
C8 Secrets & sensitive-data protection
Minimal 0.30 / 1.00
No credential is required by default. Optional LLM API keys live in a plaintext, gitignored .env file in the project directory. Every script and subprocess can read them, and so can the agent through its shell. Some masking exists: plugin log output redacts the plugin's keys, one provider masks a URL token, and Gemini error messages strip the key. There is no telemetry anywhere. Your CV and personal details go to whichever model provider you chose, which is the tool's purpose.
C9 Audit & traceability
Minimal 0.25 / 1.00
career-ops keeps records of outcomes, not of agent actions. There is a status-change ledger (status-log.tsv), a scan history, per-worker stdout logs for batch runs, and the reports themselves. The detailed record of what the agent ran is the host CLI's transcript, which career-ops neither owns nor protects. All of these files sit in the project directory, where the agent can edit them. If the ledger write fails, the status change still happens and only a warning is printed.
C10 Limits & kill switch
Minimal 0.25 / 1.00
career-ops sets no session limit of its own. Its network fetches time out after 10 seconds, and the OpenRouter runner caps each model call at 15 seconds and 8,192 output tokens. The batch runner defaults to one worker, two retries, and a pause file. But a headless batch worker has no wall-clock, step or cost cap, and the interactive session runs as long as the host allows.